From 6c56bf76d6e27e5b65746a5c0344494c6c494694 Mon Sep 17 00:00:00 2001 From: iris Date: Sat, 4 Jul 2026 12:36:11 +0200 Subject: [PATCH] feat(agent-term): matrix-tool icons + formatters, fill remaining fmtToolUse gaps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add specific icons for matrix tools that had the generic πŸ’¬ fallback: - mcp__matrix__read_room β†’ πŸ“– - mcp__matrix__mark_read β†’ πŸ‘οΈ - mcp__matrix__list_rooms / list_room_members / list_invites β†’ πŸ“‹ - mcp__bash__kill β†’ πŸ›‘ (was generic πŸ”§) Add fmtToolUse cases for high-use tools that fell through to fmtArgsGeneric: - set_status: 'set_status* "idle"' instead of 'set_status text: "idle"' - get_loose_ends: 'get_loose_ends* [iris]' or 'get_loose_ends*()' - get_agent_meta: 'get_agent_meta* iris' or 'get_agent_meta*()' - cancel_loose_end: 'cancel_loose_end* question #42' - bash kill: 'kill* abc123 [force]' - Matrix tools: 'read_room* !abc1234 [50]', 'mark_read* !abc1234', 'send_message* β†’ !room: "body"', 'send_dm* β†’ @mara: "body"', 'send_reply*', 'send_reaction*', 'join_room*', 'open_dm*', 'invite_user*', 'download_file*' Also extend the short-name shortening to cover mcp__matrix__ prefix (was only hyperhive + bash), so matrix tool rows show 'read_room*' instead of 'mcp__matrix__read_room' as the prefix. Two small helpers added: fmtRoom (truncates !id before ':' for readability; keeps #alias intact) and fmtUser (@user:server β†’ @user). Closes #2198. Updates terminal-rendering.md icon list. --- docs/terminal-rendering.md | 2 +- frontend/packages/agent/src/app.js | 59 +++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/docs/terminal-rendering.md b/docs/terminal-rendering.md index 6ad9da54..e31501e3 100644 --- a/docs/terminal-rendering.md +++ b/docs/terminal-rendering.md @@ -56,7 +56,7 @@ parent's negative pull. | `.turn-time` | `Β· HH:MM:SS` on turn-start; `Β· HH:MM:SS Β· ` on turn-end (child span) | muted, smaller | per-event `ts` (unix seconds) on the live frame + history row | harness | | `.text` | (no prefix; markdown body) | fg | claude `assistant.content[].text` | stream-json | | `.thinking` | `πŸ’­ thinking …` | muted, italic | claude `assistant.content[].thinking` | stream-json | -| `.tool-use` (flat) | ` Name args…` | cyan | tool_use w/o rich renderer; `` from `toolIcon(name)` (πŸ“€ send Β· πŸ“₯ recv Β· ❓ ask Β· ⏰ remind Β· 🏷️ set_status Β· πŸͺ’ loose-ends Β· πŸ–₯️ bash Β· πŸ’¬ matrix Β· πŸ“¦ request_* Β· ⏱️ schedule Β· πŸ”§ default) | stream-json | +| `.tool-use` (flat) | ` Name args…` | cyan | tool_use w/o rich renderer; `` from `toolIcon(name)`: πŸ“€ send Β· πŸ“₯ recv Β· ❓ ask Β· ⏰ remind Β· 🏷️ set_status Β· πŸͺ’ loose-ends Β· βœ‚οΈ cancel_loose_end Β· ℹ️ get_agent_meta Β· βœ… ack_until Β· πŸ“œ get_logs/get_host_journal Β· ↻ restart Β· ⏹️ kill Β· ▢️ start Β· πŸ”„ update Β· πŸ“‹ list_containers/list_rooms/list_room_members/list_invites Β· πŸ“– read_room/Read Β· πŸ‘οΈ mark_read Β· πŸ›‘ bash kill Β· πŸ–₯️ bash other Β· πŸ’¬ matrix send/reply/dm Β· πŸ“¦ request_* Β· ⏱️ schedule Β· πŸ”§ default | stream-json | | `.tool-use` `
` | `πŸ’Ύ/✏️ Write/Edit Β· +N` (no `β†’`) | cyan, body is +/- diff | `renderRichToolUse` Write/Edit | stream-json | | `.tool-use` `
` | `πŸ“€ send β†’ to Β· NL`, `❓ ask β†’ to`, `✍️ answer #id` | cyan, body is markdown | rich renderer for send / ask / answer | stream-json | | `.tool-use .ask-answer-inline-slot` | (sub-block under `ask β†’ operator`) | inherits row | inline answer form bound by `reconcileAskBinds` to the loose-end | rich renderer | diff --git a/frontend/packages/agent/src/app.js b/frontend/packages/agent/src/app.js index 5d5b05eb..248a70e0 100644 --- a/frontend/packages/agent/src/app.js +++ b/frontend/packages/agent/src/app.js @@ -1524,6 +1524,12 @@ window.marked = marked; 'mcp__hyperhive__list_containers': 'πŸ“‹', 'mcp__hyperhive__get_logs': 'πŸ“œ', 'mcp__hyperhive__get_host_journal': 'πŸ“œ', + 'mcp__matrix__read_room': 'πŸ“–', + 'mcp__matrix__mark_read': 'πŸ‘οΈ', + 'mcp__matrix__list_rooms': 'πŸ“‹', + 'mcp__matrix__list_room_members': 'πŸ“‹', + 'mcp__matrix__list_invites': 'πŸ“‹', + 'mcp__bash__kill': 'πŸ›‘', Read: 'πŸ“–', Write: 'πŸ’Ύ', Edit: '✏️', Glob: 'πŸ”', Grep: 'πŸ”', }; function toolIcon(name) { @@ -1537,6 +1543,22 @@ window.marked = marked; } return 'πŸ”§'; } + // Shorten a matrix room id or alias for display. Room ids (!xxx:server) + // are trimmed to the first 8 local chars; aliases (#name:server) are + // returned as-is (they're already readable). Falls back to the raw + // value truncated. + function fmtRoom(r) { + if (!r) return '?'; + if (r.startsWith('!')) return r.slice(0, r.indexOf(':') > 0 ? r.indexOf(':') : 9); + if (r.startsWith('#')) return r.split(':')[0] || r; + return trim(r, 20); + } + // Shorten @user:server β†’ @user. + function fmtUser(u) { + if (!u) return '?'; + const colon = u.indexOf(':'); + return colon > 0 ? u.slice(0, colon) : u; + } // Pretty-print a tool call: per-known-tool format, fallback to JSON // for unknown tools. function fmtToolUse(c) { @@ -1546,7 +1568,9 @@ window.marked = marked; ? name.slice('mcp__hyperhive__'.length) + '*' : name.startsWith('mcp__bash__') ? name.slice('mcp__bash__'.length) + '*' - : name; + : name.startsWith('mcp__matrix__') + ? name.slice('mcp__matrix__'.length) + '*' + : name; switch (name) { case 'Read': return short + ' ' + (input.file_path || ''); case 'Write': return short + ' ' + (input.file_path || ''); @@ -1611,6 +1635,39 @@ window.marked = marked; case 'mcp__bash__status': return short + ' id:' + (input.id || '?') + (input.wait_seconds != null ? ' Β· wait ' + input.wait_seconds + 's' : ''); + case 'mcp__bash__kill': + return short + ' ' + (input.id || '?') + (input.force ? ' [force]' : ''); + case 'mcp__hyperhive__set_status': + return short + ' "' + trim(String(input.text || ''), 60) + '"'; + case 'mcp__hyperhive__get_loose_ends': + return short + (input.agent ? ' [' + input.agent + ']' : '()'); + case 'mcp__hyperhive__get_agent_meta': + return short + (input.name ? ' ' + input.name : '()'); + case 'mcp__hyperhive__cancel_loose_end': + return short + ' ' + (input.kind || '?') + ' #' + (input.id != null ? input.id : '?'); + case 'mcp__matrix__read_room': + return short + ' ' + fmtRoom(input.room) + + (input.limit != null ? ' [' + input.limit + ']' : ''); + case 'mcp__matrix__mark_read': + return short + ' ' + fmtRoom(input.room); + case 'mcp__matrix__send_message': + return short + ' β†’ ' + fmtRoom(input.room) + ': ' + + JSON.stringify(trim(String(input.body || ''), 50)); + case 'mcp__matrix__send_dm': + return short + ' β†’ ' + fmtUser(input.user_id) + ': ' + + JSON.stringify(trim(String(input.body || ''), 50)); + case 'mcp__matrix__send_reply': + return short + ' β†’ ' + fmtRoom(input.room) + ': ' + + JSON.stringify(trim(String(input.body || ''), 50)); + case 'mcp__matrix__send_reaction': + return short + ' ' + fmtRoom(input.room) + ' ' + (input.key || '?'); + case 'mcp__matrix__join_room': + case 'mcp__matrix__open_dm': + return short + ' ' + (fmtRoom(input.room) || fmtUser(input.user_id) || '?'); + case 'mcp__matrix__invite_user': + return short + ' ' + fmtUser(input.user_id) + ' β†’ ' + fmtRoom(input.room); + case 'mcp__matrix__download_file': + return short + ' ' + fmtRoom(input.room); default: return fmtArgsGeneric(short, input); } }