feat(chat): unified tool execution rendering for agents - #4192
Open
kylexu88 wants to merge 31 commits into
Open
Conversation
Introduce ToolCategory and helpers for the unified tool-execution render pipeline (Task 1 of the refactor plan): - categorizeToolName maps agent tool names (Edit/Bash/Read/Grep/Task/...) case-insensitively to a shared category, falling back to `generic` so new agents always have a render path. - mapAcpKindToCategory maps ACP update.kind values to the same category set (backend already normalizes the kind). - TOOL_BLOCK_META provides the i18n title key and icon-park icon name for each category; icon names are placeholders to be verified in Task 5. Also extend vitest.config.ts to discover colocated node tests under packages/desktop/src/**/*.test.ts (and dom variants under the dom project), so the plan's `bunx vitest run <colocated file>` workflow works. This also unblocks two existing colocated tests that were previously outside the include globs.
Known categories (bash/read/edit/task/todo) now show the translated action title in the header, matching the reference design; only generic tools keep the raw tool name. Bash timeline rows prefer description over command, and title/summary/icon colors follow the reference hierarchy (secondary/tertiary/primary, icon 16px).
ACP tool titles are natural-language descriptions that can equal the summary extracted from rawInput, rendering the same text twice in the header. The summary now only renders when it differs from the title.
Tool block headers now show a human tool name like the reference project: known tool names map to specific action titles (write file, replace string, apply patch, glob -> file match, web fetch...), generic command tools are classified by what the command does (cat -> read file, ls -> list files, grep -> search), and unknown names are prettified (snake_case/CamelCase -> spaced words). Adds the 15 new title keys across all 13 languages.
Tool blocks now pick icons by tool name like the reference design: write gets a pencil, glob a folder, web fetch a globe, delete a trash bin, todo/plan a checklist, read an eye. Generic command tools refine the icon by what the command does (cat -> eye, ls -> folder, grep -> search); the dedicated bash block keeps its fixed terminal icon.
Agent tool names like ReadFile/ListDirectory/SearchText/RunCommand (gemini/codex style, no underscores) previously missed the exact-match tables and fell back to the generic toolkit icon. Both the title and icon tables now cover these variants.
Claude-style backends put the natural-language tool description into
the tool_call name field (e.g. name="查看主进程各模块文件" with
args={command,...}), so name-based categorization always fell back to
the generic toolkit block. When the name does not match a known tool,
the category is now inferred from the raw arg signature
(command->bash, file_path->read, old_string/edits/content->edit,
url/pattern/query->search, todos->todo, subagent_type->task). The same
fallback covers ACP calls whose kind was narrowed away by the
backend.
Expanded tool bodies previously showed only the output; the reference layout renders the executed command above the output. The bash timeline rows, task step rows now render the command block too, and command-only steps became expandable.
Consecutive read/edit/search blocks previously merged into one mixed list segment labeled "文件操作" with a fixed read icon. Lists now group by category so each segment header names the action (读取文件 / 编辑文件 / 搜索) with the matching icon, and consecutive task blocks render as individual subagent cards instead of list rows. Drops the now-unused fileOpsTitle key.
Grouped segments always hold 2+ blocks, so their headers switch from
single-action wording ("read file") to the reference project's batch
wording ("batch read files", "batch run commands").
The task icon key came from the raw tool name, which for claude is a natural-language description, so the block fell back to the generic toolkit icon. Subagent steps rendered as compact rows instead of the same full blocks used for top-level tool calls.
When a bash call has no description, the header summary fell back to the full command line, which got hard-clipped in narrow nested contexts. The command now lives only in the expanded body, matching the reference layout.
The grid 0fr collapse left the inner row at its min-content height because the grid item lacked min-height: 0, so a sliver of the body leaked through below the header. The separator border now only renders when open.
…d in bash headers ACP-path tool blocks ignored a model-authored description in rawInput for non-task categories, so agents sending one rendered a bare operand instead. Align the acp_tool_call summary extraction with the tool_call path by preferring description. Bash blocks whose agent provides no description (codex, aionrs) now fall back to a truncated command in the header so it is never empty.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Unify tool execution rendering across all agent backends (claude, codex, aionrs, opencode, gemini-acp, …).
The old three components (MessageToolCall / MessageAcpToolCall / MessageToolGroup) each rendered tool calls with their own visual language and were incompatible with multi-agent grouping. This PR replaces them with a single UnifiedToolBlock pipeline:
Backed by unit + DOM tests (normalization, per-block rendering, grouping, truncation).
Related Issues
N/A
Type of Change
feat— New feature (non-breaking change which adds functionality)Atomic PR Checklist (Rule 1)
<type>(<scope>): <subject>(English)Local Checks (Rule 3)
bun run format— formatting passesbun run lint— no lint errorsbunx tsc --noEmit— no type errorsbunx vitest run— tests pass (4866 tests)bun run i18n:types+node scripts/check-i18n.js)Runtime Verification
Additional Context
Real-agent manual regression (claude/codex/aionrs/opencode) not yet done — requires Electron interaction.