From d85d3c88d56d4541a67822df7be1d5789d654ca2 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 2 Mar 2026 12:13:25 +0000 Subject: [PATCH] refactor(agents): centralize tool display definitions --- src/agents/tool-display-overrides.json | 231 ++++++++++++++++++ src/agents/tool-display.json | 326 ------------------------- src/agents/tool-display.ts | 11 +- src/canvas-host/a2ui/index.html | 6 +- ui/src/ui/tool-display.json | 236 ------------------ ui/src/ui/tool-display.ts | 76 +++++- 6 files changed, 310 insertions(+), 576 deletions(-) create mode 100644 src/agents/tool-display-overrides.json delete mode 100644 src/agents/tool-display.json delete mode 100644 ui/src/ui/tool-display.json diff --git a/src/agents/tool-display-overrides.json b/src/agents/tool-display-overrides.json new file mode 100644 index 00000000000..590485404ff --- /dev/null +++ b/src/agents/tool-display-overrides.json @@ -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": [] + } + } +} diff --git a/src/agents/tool-display.json b/src/agents/tool-display.json deleted file mode 100644 index 364a80e0b85..00000000000 --- a/src/agents/tool-display.json +++ /dev/null @@ -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" } - } - } - } -} diff --git a/src/agents/tool-display.ts b/src/agents/tool-display.ts index c630c1c687b..17183d6fe1d 100644 --- a/src/agents/tool-display.ts +++ b/src/agents/tool-display.ts @@ -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 = { agentId: "agent", sessionKey: "session", diff --git a/src/canvas-host/a2ui/index.html b/src/canvas-host/a2ui/index.html index 3f1bce79593..57e767860d4 100644 --- a/src/canvas-host/a2ui/index.html +++ b/src/canvas-host/a2ui/index.html @@ -226,11 +226,11 @@ -
-
+
+
Ready
Waiting for agent
-
+
diff --git a/ui/src/ui/tool-display.json b/ui/src/ui/tool-display.json deleted file mode 100644 index e4cea776eb4..00000000000 --- a/ui/src/ui/tool-display.json +++ /dev/null @@ -1,236 +0,0 @@ -{ - "version": 1, - "fallback": { - "icon": "puzzle", - "detailKeys": [ - "command", - "path", - "url", - "targetUrl", - "targetId", - "ref", - "element", - "node", - "nodeId", - "id", - "requestId", - "to", - "channelId", - "guildId", - "userId", - "name", - "query", - "pattern", - "messageId" - ] - }, - "tools": { - "bash": { - "icon": "wrench", - "title": "Bash", - "detailKeys": ["command"] - }, - "process": { - "icon": "wrench", - "title": "Process", - "detailKeys": ["sessionId"] - }, - "read": { - "icon": "fileText", - "title": "Read", - "detailKeys": ["path"] - }, - "write": { - "icon": "edit", - "title": "Write", - "detailKeys": ["path"] - }, - "edit": { - "icon": "penLine", - "title": "Edit", - "detailKeys": ["path"] - }, - "attach": { - "icon": "paperclip", - "title": "Attach", - "detailKeys": ["path", "url", "fileName"] - }, - "browser": { - "icon": "globe", - "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": { - "icon": "image", - "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": { - "icon": "smartphone", - "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": { - "icon": "loader", - "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": { - "icon": "plug", - "title": "Gateway", - "actions": { - "restart": { "label": "restart", "detailKeys": ["reason", "delayMs"] }, - "config.get": { "label": "config get" }, - "config.schema": { "label": "config schema" }, - "config.apply": { - "label": "config apply", - "detailKeys": ["restartDelayMs"] - }, - "update.run": { - "label": "update run", - "detailKeys": ["restartDelayMs"] - } - } - }, - "whatsapp_login": { - "icon": "circle", - "title": "WhatsApp Login", - "actions": { - "start": { "label": "start" }, - "wait": { "label": "wait" } - } - }, - "discord": { - "icon": "messageSquare", - "title": "Discord", - "actions": { - "react": { "label": "react", "detailKeys": ["channelId", "messageId", "emoji"] }, - "reactions": { "label": "reactions", "detailKeys": ["channelId", "messageId"] }, - "sticker": { "label": "sticker", "detailKeys": ["to", "stickerIds"] }, - "poll": { "label": "poll", "detailKeys": ["question", "to"] }, - "permissions": { "label": "permissions", "detailKeys": ["channelId"] }, - "readMessages": { "label": "read messages", "detailKeys": ["channelId", "limit"] }, - "sendMessage": { "label": "send", "detailKeys": ["to", "content"] }, - "editMessage": { "label": "edit", "detailKeys": ["channelId", "messageId"] }, - "deleteMessage": { "label": "delete", "detailKeys": ["channelId", "messageId"] }, - "threadCreate": { "label": "thread create", "detailKeys": ["channelId", "name"] }, - "threadList": { "label": "thread list", "detailKeys": ["guildId", "channelId"] }, - "threadReply": { "label": "thread reply", "detailKeys": ["channelId", "content"] }, - "pinMessage": { "label": "pin", "detailKeys": ["channelId", "messageId"] }, - "unpinMessage": { "label": "unpin", "detailKeys": ["channelId", "messageId"] }, - "listPins": { "label": "list pins", "detailKeys": ["channelId"] }, - "searchMessages": { "label": "search", "detailKeys": ["guildId", "content"] }, - "memberInfo": { "label": "member", "detailKeys": ["guildId", "userId"] }, - "roleInfo": { "label": "roles", "detailKeys": ["guildId"] }, - "emojiList": { "label": "emoji list", "detailKeys": ["guildId"] }, - "roleAdd": { "label": "role add", "detailKeys": ["guildId", "userId", "roleId"] }, - "roleRemove": { "label": "role remove", "detailKeys": ["guildId", "userId", "roleId"] }, - "channelInfo": { "label": "channel", "detailKeys": ["channelId"] }, - "channelList": { "label": "channels", "detailKeys": ["guildId"] }, - "voiceStatus": { "label": "voice", "detailKeys": ["guildId", "userId"] }, - "eventList": { "label": "events", "detailKeys": ["guildId"] }, - "eventCreate": { "label": "event create", "detailKeys": ["guildId", "name"] }, - "timeout": { "label": "timeout", "detailKeys": ["guildId", "userId"] }, - "kick": { "label": "kick", "detailKeys": ["guildId", "userId"] }, - "ban": { "label": "ban", "detailKeys": ["guildId", "userId"] } - } - }, - "slack": { - "icon": "messageSquare", - "title": "Slack", - "actions": { - "react": { "label": "react", "detailKeys": ["channelId", "messageId", "emoji"] }, - "reactions": { "label": "reactions", "detailKeys": ["channelId", "messageId"] }, - "sendMessage": { "label": "send", "detailKeys": ["to", "content"] }, - "editMessage": { "label": "edit", "detailKeys": ["channelId", "messageId"] }, - "deleteMessage": { "label": "delete", "detailKeys": ["channelId", "messageId"] }, - "readMessages": { "label": "read messages", "detailKeys": ["channelId", "limit"] }, - "pinMessage": { "label": "pin", "detailKeys": ["channelId", "messageId"] }, - "unpinMessage": { "label": "unpin", "detailKeys": ["channelId", "messageId"] }, - "listPins": { "label": "list pins", "detailKeys": ["channelId"] }, - "memberInfo": { "label": "member", "detailKeys": ["userId"] }, - "emojiList": { "label": "emoji list" } - } - } - } -} diff --git a/ui/src/ui/tool-display.ts b/ui/src/ui/tool-display.ts index 4d4b69e5d6b..93a1b5af480 100644 --- a/ui/src/ui/tool-display.ts +++ b/ui/src/ui/tool-display.ts @@ -1,3 +1,4 @@ +import SHARED_TOOL_DISPLAY_JSON from "../../../apps/shared/OpenClawKit/Sources/OpenClawKit/Resources/tool-display.json" with { type: "json" }; import { defaultTitle, formatToolDetailText, @@ -7,16 +8,19 @@ import { type ToolDisplaySpec as ToolDisplaySpecBase, } from "../../../src/agents/tool-display-common.js"; import type { IconName } from "./icons.ts"; -import rawConfig from "./tool-display.json" with { type: "json" }; type ToolDisplaySpec = ToolDisplaySpecBase & { icon?: string; }; -type ToolDisplayConfig = { +type SharedToolDisplaySpec = ToolDisplaySpecBase & { + emoji?: string; +}; + +type SharedToolDisplayConfig = { version?: number; - fallback?: ToolDisplaySpec; - tools?: Record; + fallback?: SharedToolDisplaySpec; + tools?: Record; }; export type ToolDisplay = { @@ -28,9 +32,67 @@ export type ToolDisplay = { detail?: string; }; -const TOOL_DISPLAY_CONFIG = rawConfig as ToolDisplayConfig; -const FALLBACK = TOOL_DISPLAY_CONFIG.fallback ?? { icon: "puzzle" }; -const TOOL_MAP = TOOL_DISPLAY_CONFIG.tools ?? {}; +const EMOJI_ICON_MAP: Record = { + "๐Ÿงฉ": "puzzle", + "๐Ÿ› ๏ธ": "wrench", + "๐Ÿงฐ": "wrench", + "๐Ÿ“–": "fileText", + "โœ๏ธ": "edit", + "๐Ÿ“": "penLine", + "๐Ÿ“Ž": "paperclip", + "๐ŸŒ": "globe", + "๐Ÿ“บ": "monitor", + "๐Ÿงพ": "fileText", + "๐Ÿ”": "settings", + "๐Ÿ’ป": "monitor", + "๐Ÿ”Œ": "plug", + "๐Ÿ’ฌ": "messageSquare", +}; + +const SLACK_SPEC: ToolDisplaySpec = { + icon: "messageSquare", + title: "Slack", + actions: { + react: { label: "react", detailKeys: ["channelId", "messageId", "emoji"] }, + reactions: { label: "reactions", detailKeys: ["channelId", "messageId"] }, + sendMessage: { label: "send", detailKeys: ["to", "content"] }, + editMessage: { label: "edit", detailKeys: ["channelId", "messageId"] }, + deleteMessage: { label: "delete", detailKeys: ["channelId", "messageId"] }, + readMessages: { label: "read messages", detailKeys: ["channelId", "limit"] }, + pinMessage: { label: "pin", detailKeys: ["channelId", "messageId"] }, + unpinMessage: { label: "unpin", detailKeys: ["channelId", "messageId"] }, + listPins: { label: "list pins", detailKeys: ["channelId"] }, + memberInfo: { label: "member", detailKeys: ["userId"] }, + emojiList: { label: "emoji list" }, + }, +}; + +function iconForEmoji(emoji?: string): IconName { + if (!emoji) { + return "puzzle"; + } + return EMOJI_ICON_MAP[emoji] ?? "puzzle"; +} + +function convertSpec(spec?: SharedToolDisplaySpec): ToolDisplaySpec { + return { + icon: iconForEmoji(spec?.emoji), + title: spec?.title, + label: spec?.label, + detailKeys: spec?.detailKeys, + actions: spec?.actions, + }; +} + +const SHARED_TOOL_DISPLAY_CONFIG = SHARED_TOOL_DISPLAY_JSON as SharedToolDisplayConfig; +const FALLBACK = convertSpec(SHARED_TOOL_DISPLAY_CONFIG.fallback ?? { emoji: "๐Ÿงฉ" }); +const TOOL_MAP: Record = Object.fromEntries( + Object.entries(SHARED_TOOL_DISPLAY_CONFIG.tools ?? {}).map(([key, spec]) => [ + key, + convertSpec(spec), + ]), +); +TOOL_MAP.slack = SLACK_SPEC; function shortenHomeInString(input: string): string { if (!input) {