refactor(agents): centralize tool display definitions

This commit is contained in:
Peter Steinberger
2026-03-02 12:13:25 +00:00
parent d977af5853
commit d85d3c88d5
6 changed files with 310 additions and 576 deletions

View File

@@ -0,0 +1,231 @@
{
"version": 1,
"tools": {
"exec": {
"emoji": "🛠️",
"title": "Exec",
"detailKeys": ["command"]
},
"tool_call": {
"emoji": "🧰",
"title": "Tool Call",
"detailKeys": []
},
"tool_call_update": {
"emoji": "🧰",
"title": "Tool Call",
"detailKeys": []
},
"session_status": {
"emoji": "📊",
"title": "Session Status",
"detailKeys": ["sessionKey", "model"]
},
"sessions_list": {
"emoji": "🗂️",
"title": "Sessions",
"detailKeys": ["kinds", "limit", "activeMinutes", "messageLimit"]
},
"sessions_send": {
"emoji": "📨",
"title": "Session Send",
"detailKeys": ["label", "sessionKey", "agentId", "timeoutSeconds"]
},
"sessions_history": {
"emoji": "🧾",
"title": "Session History",
"detailKeys": ["sessionKey", "limit", "includeTools"]
},
"sessions_spawn": {
"emoji": "🧑‍🔧",
"title": "Sub-agent",
"detailKeys": [
"label",
"task",
"agentId",
"model",
"thinking",
"runTimeoutSeconds",
"cleanup"
]
},
"subagents": {
"emoji": "🤖",
"title": "Subagents",
"actions": {
"list": {
"label": "list",
"detailKeys": ["recentMinutes"]
},
"kill": {
"label": "kill",
"detailKeys": ["target"]
},
"steer": {
"label": "steer",
"detailKeys": ["target"]
}
}
},
"agents_list": {
"emoji": "🧭",
"title": "Agents",
"detailKeys": []
},
"memory_search": {
"emoji": "🧠",
"title": "Memory Search",
"detailKeys": ["query"]
},
"memory_get": {
"emoji": "📓",
"title": "Memory Get",
"detailKeys": ["path", "from", "lines"]
},
"web_search": {
"emoji": "🔎",
"title": "Web Search",
"detailKeys": ["query", "count"]
},
"web_fetch": {
"emoji": "📄",
"title": "Web Fetch",
"detailKeys": ["url", "extractMode", "maxChars"]
},
"message": {
"emoji": "✉️",
"title": "Message",
"actions": {
"send": {
"label": "send",
"detailKeys": ["provider", "to", "media", "replyTo", "threadId"]
},
"poll": {
"label": "poll",
"detailKeys": ["provider", "to", "pollQuestion"]
},
"react": {
"label": "react",
"detailKeys": ["provider", "to", "messageId", "emoji", "remove"]
},
"reactions": {
"label": "reactions",
"detailKeys": ["provider", "to", "messageId", "limit"]
},
"read": {
"label": "read",
"detailKeys": ["provider", "to", "limit"]
},
"edit": {
"label": "edit",
"detailKeys": ["provider", "to", "messageId"]
},
"delete": {
"label": "delete",
"detailKeys": ["provider", "to", "messageId"]
},
"pin": {
"label": "pin",
"detailKeys": ["provider", "to", "messageId"]
},
"unpin": {
"label": "unpin",
"detailKeys": ["provider", "to", "messageId"]
},
"list-pins": {
"label": "list pins",
"detailKeys": ["provider", "to"]
},
"permissions": {
"label": "permissions",
"detailKeys": ["provider", "channelId", "to"]
},
"thread-create": {
"label": "thread create",
"detailKeys": ["provider", "channelId", "threadName"]
},
"thread-list": {
"label": "thread list",
"detailKeys": ["provider", "guildId", "channelId"]
},
"thread-reply": {
"label": "thread reply",
"detailKeys": ["provider", "channelId", "messageId"]
},
"search": {
"label": "search",
"detailKeys": ["provider", "guildId", "query"]
},
"sticker": {
"label": "sticker",
"detailKeys": ["provider", "to", "stickerId"]
},
"member-info": {
"label": "member",
"detailKeys": ["provider", "guildId", "userId"]
},
"role-info": {
"label": "roles",
"detailKeys": ["provider", "guildId"]
},
"emoji-list": {
"label": "emoji list",
"detailKeys": ["provider", "guildId"]
},
"emoji-upload": {
"label": "emoji upload",
"detailKeys": ["provider", "guildId", "emojiName"]
},
"sticker-upload": {
"label": "sticker upload",
"detailKeys": ["provider", "guildId", "stickerName"]
},
"role-add": {
"label": "role add",
"detailKeys": ["provider", "guildId", "userId", "roleId"]
},
"role-remove": {
"label": "role remove",
"detailKeys": ["provider", "guildId", "userId", "roleId"]
},
"channel-info": {
"label": "channel",
"detailKeys": ["provider", "channelId"]
},
"channel-list": {
"label": "channels",
"detailKeys": ["provider", "guildId"]
},
"voice-status": {
"label": "voice",
"detailKeys": ["provider", "guildId", "userId"]
},
"event-list": {
"label": "events",
"detailKeys": ["provider", "guildId"]
},
"event-create": {
"label": "event create",
"detailKeys": ["provider", "guildId", "eventName"]
},
"timeout": {
"label": "timeout",
"detailKeys": ["provider", "guildId", "userId"]
},
"kick": {
"label": "kick",
"detailKeys": ["provider", "guildId", "userId"]
},
"ban": {
"label": "ban",
"detailKeys": ["provider", "guildId", "userId"]
}
}
},
"apply_patch": {
"emoji": "🩹",
"title": "Apply Patch",
"detailKeys": []
}
}
}

View File

@@ -1,326 +0,0 @@
{
"version": 1,
"fallback": {
"emoji": "🧩",
"detailKeys": [
"command",
"path",
"url",
"targetUrl",
"targetId",
"ref",
"element",
"node",
"nodeId",
"id",
"requestId",
"to",
"channelId",
"guildId",
"userId",
"name",
"query",
"pattern",
"messageId"
]
},
"tools": {
"exec": {
"emoji": "🛠️",
"title": "Exec",
"detailKeys": ["command"]
},
"tool_call": {
"emoji": "🧰",
"title": "Tool Call",
"detailKeys": []
},
"tool_call_update": {
"emoji": "🧰",
"title": "Tool Call",
"detailKeys": []
},
"process": {
"emoji": "🧰",
"title": "Process",
"detailKeys": ["sessionId"]
},
"read": {
"emoji": "📖",
"title": "Read",
"detailKeys": ["path"]
},
"write": {
"emoji": "✍️",
"title": "Write",
"detailKeys": ["path"]
},
"edit": {
"emoji": "📝",
"title": "Edit",
"detailKeys": ["path"]
},
"apply_patch": {
"emoji": "🩹",
"title": "Apply Patch",
"detailKeys": []
},
"attach": {
"emoji": "📎",
"title": "Attach",
"detailKeys": ["path", "url", "fileName"]
},
"browser": {
"emoji": "🌐",
"title": "Browser",
"actions": {
"status": { "label": "status" },
"start": { "label": "start" },
"stop": { "label": "stop" },
"tabs": { "label": "tabs" },
"open": { "label": "open", "detailKeys": ["targetUrl"] },
"focus": { "label": "focus", "detailKeys": ["targetId"] },
"close": { "label": "close", "detailKeys": ["targetId"] },
"snapshot": {
"label": "snapshot",
"detailKeys": ["targetUrl", "targetId", "ref", "element", "format"]
},
"screenshot": {
"label": "screenshot",
"detailKeys": ["targetUrl", "targetId", "ref", "element"]
},
"navigate": {
"label": "navigate",
"detailKeys": ["targetUrl", "targetId"]
},
"console": { "label": "console", "detailKeys": ["level", "targetId"] },
"pdf": { "label": "pdf", "detailKeys": ["targetId"] },
"upload": {
"label": "upload",
"detailKeys": ["paths", "ref", "inputRef", "element", "targetId"]
},
"dialog": {
"label": "dialog",
"detailKeys": ["accept", "promptText", "targetId"]
},
"act": {
"label": "act",
"detailKeys": [
"request.kind",
"request.ref",
"request.selector",
"request.text",
"request.value"
]
}
}
},
"canvas": {
"emoji": "🖼️",
"title": "Canvas",
"actions": {
"present": { "label": "present", "detailKeys": ["target", "node", "nodeId"] },
"hide": { "label": "hide", "detailKeys": ["node", "nodeId"] },
"navigate": { "label": "navigate", "detailKeys": ["url", "node", "nodeId"] },
"eval": { "label": "eval", "detailKeys": ["javaScript", "node", "nodeId"] },
"snapshot": { "label": "snapshot", "detailKeys": ["format", "node", "nodeId"] },
"a2ui_push": { "label": "A2UI push", "detailKeys": ["jsonlPath", "node", "nodeId"] },
"a2ui_reset": { "label": "A2UI reset", "detailKeys": ["node", "nodeId"] }
}
},
"nodes": {
"emoji": "📱",
"title": "Nodes",
"actions": {
"status": { "label": "status" },
"describe": { "label": "describe", "detailKeys": ["node", "nodeId"] },
"pending": { "label": "pending" },
"approve": { "label": "approve", "detailKeys": ["requestId"] },
"reject": { "label": "reject", "detailKeys": ["requestId"] },
"notify": { "label": "notify", "detailKeys": ["node", "nodeId", "title", "body"] },
"camera_snap": {
"label": "camera snap",
"detailKeys": ["node", "nodeId", "facing", "deviceId"]
},
"camera_list": { "label": "camera list", "detailKeys": ["node", "nodeId"] },
"camera_clip": {
"label": "camera clip",
"detailKeys": ["node", "nodeId", "facing", "duration", "durationMs"]
},
"screen_record": {
"label": "screen record",
"detailKeys": ["node", "nodeId", "duration", "durationMs", "fps", "screenIndex"]
}
}
},
"cron": {
"emoji": "⏰",
"title": "Cron",
"actions": {
"status": { "label": "status" },
"list": { "label": "list" },
"add": {
"label": "add",
"detailKeys": ["job.name", "job.id", "job.schedule", "job.cron"]
},
"update": { "label": "update", "detailKeys": ["id"] },
"remove": { "label": "remove", "detailKeys": ["id"] },
"run": { "label": "run", "detailKeys": ["id"] },
"runs": { "label": "runs", "detailKeys": ["id"] },
"wake": { "label": "wake", "detailKeys": ["text", "mode"] }
}
},
"gateway": {
"emoji": "🔌",
"title": "Gateway",
"actions": {
"restart": { "label": "restart", "detailKeys": ["reason", "delayMs"] }
}
},
"message": {
"emoji": "✉️",
"title": "Message",
"actions": {
"send": {
"label": "send",
"detailKeys": ["provider", "to", "media", "replyTo", "threadId"]
},
"poll": { "label": "poll", "detailKeys": ["provider", "to", "pollQuestion"] },
"react": {
"label": "react",
"detailKeys": ["provider", "to", "messageId", "emoji", "remove"]
},
"reactions": {
"label": "reactions",
"detailKeys": ["provider", "to", "messageId", "limit"]
},
"read": { "label": "read", "detailKeys": ["provider", "to", "limit"] },
"edit": { "label": "edit", "detailKeys": ["provider", "to", "messageId"] },
"delete": { "label": "delete", "detailKeys": ["provider", "to", "messageId"] },
"pin": { "label": "pin", "detailKeys": ["provider", "to", "messageId"] },
"unpin": { "label": "unpin", "detailKeys": ["provider", "to", "messageId"] },
"list-pins": { "label": "list pins", "detailKeys": ["provider", "to"] },
"permissions": { "label": "permissions", "detailKeys": ["provider", "channelId", "to"] },
"thread-create": {
"label": "thread create",
"detailKeys": ["provider", "channelId", "threadName"]
},
"thread-list": {
"label": "thread list",
"detailKeys": ["provider", "guildId", "channelId"]
},
"thread-reply": {
"label": "thread reply",
"detailKeys": ["provider", "channelId", "messageId"]
},
"search": { "label": "search", "detailKeys": ["provider", "guildId", "query"] },
"sticker": { "label": "sticker", "detailKeys": ["provider", "to", "stickerId"] },
"member-info": { "label": "member", "detailKeys": ["provider", "guildId", "userId"] },
"role-info": { "label": "roles", "detailKeys": ["provider", "guildId"] },
"emoji-list": { "label": "emoji list", "detailKeys": ["provider", "guildId"] },
"emoji-upload": {
"label": "emoji upload",
"detailKeys": ["provider", "guildId", "emojiName"]
},
"sticker-upload": {
"label": "sticker upload",
"detailKeys": ["provider", "guildId", "stickerName"]
},
"role-add": {
"label": "role add",
"detailKeys": ["provider", "guildId", "userId", "roleId"]
},
"role-remove": {
"label": "role remove",
"detailKeys": ["provider", "guildId", "userId", "roleId"]
},
"channel-info": { "label": "channel", "detailKeys": ["provider", "channelId"] },
"channel-list": { "label": "channels", "detailKeys": ["provider", "guildId"] },
"voice-status": { "label": "voice", "detailKeys": ["provider", "guildId", "userId"] },
"event-list": { "label": "events", "detailKeys": ["provider", "guildId"] },
"event-create": {
"label": "event create",
"detailKeys": ["provider", "guildId", "eventName"]
},
"timeout": { "label": "timeout", "detailKeys": ["provider", "guildId", "userId"] },
"kick": { "label": "kick", "detailKeys": ["provider", "guildId", "userId"] },
"ban": { "label": "ban", "detailKeys": ["provider", "guildId", "userId"] }
}
},
"agents_list": {
"emoji": "🧭",
"title": "Agents",
"detailKeys": []
},
"sessions_list": {
"emoji": "🗂️",
"title": "Sessions",
"detailKeys": ["kinds", "limit", "activeMinutes", "messageLimit"]
},
"sessions_history": {
"emoji": "🧾",
"title": "Session History",
"detailKeys": ["sessionKey", "limit", "includeTools"]
},
"sessions_send": {
"emoji": "📨",
"title": "Session Send",
"detailKeys": ["label", "sessionKey", "agentId", "timeoutSeconds"]
},
"sessions_spawn": {
"emoji": "🧑‍🔧",
"title": "Sub-agent",
"detailKeys": [
"label",
"task",
"agentId",
"model",
"thinking",
"runTimeoutSeconds",
"cleanup"
]
},
"subagents": {
"emoji": "🤖",
"title": "Subagents",
"actions": {
"list": { "label": "list", "detailKeys": ["recentMinutes"] },
"kill": { "label": "kill", "detailKeys": ["target"] },
"steer": { "label": "steer", "detailKeys": ["target"] }
}
},
"session_status": {
"emoji": "📊",
"title": "Session Status",
"detailKeys": ["sessionKey", "model"]
},
"memory_search": {
"emoji": "🧠",
"title": "Memory Search",
"detailKeys": ["query"]
},
"memory_get": {
"emoji": "📓",
"title": "Memory Get",
"detailKeys": ["path", "from", "lines"]
},
"web_search": {
"emoji": "🔎",
"title": "Web Search",
"detailKeys": ["query", "count"]
},
"web_fetch": {
"emoji": "📄",
"title": "Web Fetch",
"detailKeys": ["url", "extractMode", "maxChars"]
},
"whatsapp_login": {
"emoji": "🟢",
"title": "WhatsApp Login",
"actions": {
"start": { "label": "start" },
"wait": { "label": "wait" }
}
}
}
}

View File

@@ -1,3 +1,4 @@
import SHARED_TOOL_DISPLAY_JSON from "../../apps/shared/OpenClawKit/Sources/OpenClawKit/Resources/tool-display.json" with { type: "json" };
import { redactToolDetail } from "../logging/redact.js";
import { shortenHomeInString } from "../utils.js";
import {
@@ -9,7 +10,7 @@ import {
resolveToolVerbAndDetail,
type ToolDisplaySpec as ToolDisplaySpecBase,
} from "./tool-display-common.js";
import TOOL_DISPLAY_JSON from "./tool-display.json" with { type: "json" };
import TOOL_DISPLAY_OVERRIDES_JSON from "./tool-display-overrides.json" with { type: "json" };
type ToolDisplaySpec = ToolDisplaySpecBase & {
emoji?: string;
@@ -30,9 +31,11 @@ export type ToolDisplay = {
detail?: string;
};
const TOOL_DISPLAY_CONFIG = TOOL_DISPLAY_JSON as ToolDisplayConfig;
const FALLBACK = TOOL_DISPLAY_CONFIG.fallback ?? { emoji: "🧩" };
const TOOL_MAP = TOOL_DISPLAY_CONFIG.tools ?? {};
const SHARED_TOOL_DISPLAY_CONFIG = SHARED_TOOL_DISPLAY_JSON as ToolDisplayConfig;
const TOOL_DISPLAY_OVERRIDES = TOOL_DISPLAY_OVERRIDES_JSON as ToolDisplayConfig;
const FALLBACK = TOOL_DISPLAY_OVERRIDES.fallback ??
SHARED_TOOL_DISPLAY_CONFIG.fallback ?? { emoji: "🧩" };
const TOOL_MAP = Object.assign({}, SHARED_TOOL_DISPLAY_CONFIG.tools, TOOL_DISPLAY_OVERRIDES.tools);
const DETAIL_LABEL_OVERRIDES: Record<string, string> = {
agentId: "agent",
sessionKey: "session",

View File

@@ -226,11 +226,11 @@
</head>
<body>
<canvas id="openclaw-canvas"></canvas>
<div id="openclaw-status">
<div class="card">
<div id="openclaw-status" role="status" aria-live="polite">
<section class="card">
<div class="title" id="openclaw-status-title">Ready</div>
<div class="subtitle" id="openclaw-status-subtitle">Waiting for agent</div>
</div>
</section>
</div>
<openclaw-a2ui-host></openclaw-a2ui-host>
<script src="a2ui.bundle.js"></script>