-
Notifications
You must be signed in to change notification settings - Fork 0
features tool cards
Active contributors: Mario Zechner, kt, Armin Ronacher
Tool cards are the web UI's rendering of tool calls the agent makes during a turn. Each tool call arrives as a tool-* frame, is normalized into a ChatToolPart, and is dispatched by web/design to a per-kind card component. The card lifecycle derives entirely from the part state: input-streaming renders a pending or streaming card, output-available renders success, and output-error renders an error. The same tool events are rendered differently by the TUI, which has its own components in packages/coding-agent.
Tool cards live in web/design/src/components/agent-elements/tools/. They consume the ChatToolPart shape from web/protocol and are driven by frames produced in web/server/src/event-mapper.ts (see streaming-chat).
A tool execution on the runtime emits tool_execution_start, tool_execution_update, and tool_execution_end. The event mapper (web/server/src/event-mapper.ts) turns these into tool frames carrying a ChatToolPart with a state of input-streaming, then output-available or output-error. The client reducer upserts the part into the assistant message by toolCallId. In web/design, buildAssistantElements (web/design/src/components/agent-elements/message-turns.tsx) walks message parts, assigns stable keys, and hands each tool part to ToolRenderer.
ToolRenderer (web/design/src/components/agent-elements/tools/tool-renderer.tsx) dispatches on part.type. Specialized components handle the common tools; MCP tools and custom renderers are resolved by prefix and registry lookup; anything else falls back to GenericTool. The dispatch order is: specialized switch, MCP parsing, custom renderers for plain tool-* parts, registry-based generic tools, then a fallback that shows the tool name.
flowchart LR
A[AgentSessionEvent tool_execution_*] --> B[event-mapper]
B --> C[tool frame / ChatToolPart]
C --> D[client reducer upsert by toolCallId]
D --> E[ToolRenderer dispatch on part.type]
E --> F{tool-IPython?}
E --> G{tool-Bash?}
E --> H{tool-Edit / tool-Write?}
E --> I{tool-WebSearch / Grep / Glob?}
E --> J{tool-PlanWrite?}
E --> K{tool-TodoWrite?}
E --> L{tool-Question?}
E --> M{tool-Task / tool-Agent?}
E --> N{tool-Thinking?}
E --> O{mcp__?}
F --> P[IpythonTool]
G --> Q[BashTool]
H --> R[EditTool]
I --> S[SearchTool]
J --> T[PlanTool]
K --> U[TodoTool]
L --> V[QuestionTool]
M --> W[ToolGroup]
N --> X[ThinkingTool]
O --> Y{has custom renderer?}
Y -->|yes| Z[CustomRenderer]
Y -->|no| AA[McpTool]
E --> AB[else: toolRegistry lookup / GenericTool]
toolRegistry (web/design/src/components/agent-elements/tools/tool-registry.ts) holds metadata (icon, title, subtitle, variant) for generic tools such as Read, Grep, Glob, WebFetch, Edit, Write, Bash, IPython, TodoWrite, PlanWrite, and Thinking. It also parses MCP tool types: parseMcpToolType recognizes the tool-mcp__<server>__<tool> prefix and the built-in resource tool names, returning a McpToolInfo used by McpTool.
tool-part-normalizer.ts (web/design/src/components/agent-elements/utils/tool-part-normalizer.ts) parses stringified input/output/result JSON on tool parts so card components can read structured fields. tool-adapters.ts (web/design/src/components/agent-elements/utils/tool-adapters.ts) maps a protocol tool part to a timeline ToolStep, translating part state to a step state (input-streaming to partial-call, output-available to result) and extracting per-tool detail such as bash commands, file paths, diff stats, search queries, and thinking content. format-tool.ts derives pending/error/success status and elapsed time, and memoizes tool parts by comparing state, input, and output.
-
ipython-tool.tsx: renders an IPython cell with a per-session cell index (In [n]), the code, and the output or error. Recognizes%%bashcells and shows kernel-restart status. -
bash-tool.tsx: renders a terminal card with the command and its output, and a command summary for the header. -
edit-tool.tsx: renders a diff card using@pierre/diffs/react, computes old/new file contents from input and output, and shows diff stats and a collapsible body. -
thinking-tool.tsx: renders the thinking trace as a collapsible block. -
todo-tool.tsx: renders todo updates from theTodoWritetool. -
plan-tool.tsx: renders a plan with its title, summary, status, and an approval footer with Execute/Stay/Refine actions plus a refine textarea. -
search-tool.tsx: renders a search group showing the query and a result list for web/code searches. -
mcp-tool.tsx: renders an MCP tool call, deriving a display name from the tool name, formatting prioritized arguments, and rendering JSON output through Streamdown. -
generic-tool.tsx: the fallback row used by registry tools and nested tool summaries.
tool-group.tsx (web/design/src/components/agent-elements/tools/tool-group.tsx) renders a tool-Task or tool-Agent subagent call. It summarizes nested tools by category (file reads/edits, searches, commands), reveals nested tool rows progressively while pending, auto-expands shortly after the group starts, and shows an elapsed-time or output-duration label. Nested parts are re-derived with the last one marked input-streaming while the group is still running.
tool-approval-footer.tsx (web/design/src/components/agent-elements/tools/tool-approval-footer.tsx) is the reusable two-button footer (approve/reject) rendered by IpythonTool, BashTool, and EditTool when the part input carries an approval object. It shows a Starting or Waiting status while pending and locks the decision once chosen.
The TUI renders the same tool events with its own components in packages/coding-agent/src/modes/interactive/components/. tool-execution.ts is a TUI Container that manages a tool call's call/result renderers, IPython cell component, bash streaming, image rendering, and expansion state, using built-in tool definitions for replay. ipython-cell.ts renders IPython cells in the terminal, tool-panel.ts hosts the panel, and edit-summary.ts summarizes file changes. These run in the terminal's component tree rather than as DOM cards, so the lifecycle is expressed through TUI component state and the working-icon pulse instead of part states.
- Wire contract:
ChatToolPartand tool frames fromweb/protocol. See web-protocol. - Frame production:
web/server/src/event-mapper.ts(toPascalCasetool naming,input-streaming/output-available/output-errorstates). See web-server and streaming-chat. - Client assembly:
web/appmessage state and reducer. See web-app. - Rendering dispatch and cards:
web/design. See web-design. - TUI rendering:
packages/coding-agent/src/modes/interactive/components/. See tui.
- Add or change a tool card: edit the dispatch in
web/design/src/components/agent-elements/tools/tool-renderer.tsx, add metadata intool-registry.ts, and add the component underweb/design/src/components/agent-elements/tools/. - Change how a tool part becomes a timeline step: edit
web/design/src/components/agent-elements/utils/tool-adapters.ts. - Change status derivation or memoization: edit
web/design/src/components/agent-elements/utils/format-tool.ts. - Change subagent/tool-group behavior: edit
web/design/src/components/agent-elements/tools/tool-group.tsx. - Change the approval footer: edit
web/design/src/components/agent-elements/tools/tool-approval-footer.tsx. - Change TUI tool rendering: edit the components under
packages/coding-agent/src/modes/interactive/components/.
| File | Role |
|---|---|
web/server/src/event-mapper.ts |
Produces tool frames with ChatToolPart states; toPascalCase tool naming. |
web/design/src/components/agent-elements/tools/tool-renderer.tsx |
Core dispatch by part.type to card components. |
web/design/src/components/agent-elements/tools/tool-registry.ts |
Tool metadata (icon/title/subtitle/variant) and MCP tool name parsing. |
web/design/src/components/agent-elements/utils/tool-adapters.ts |
Maps protocol tool parts to a timeline ToolStep and step state. |
web/design/src/components/agent-elements/utils/tool-part-normalizer.ts |
Parses stringified input/output/result JSON on tool parts. |
web/design/src/components/agent-elements/utils/format-tool.ts |
Tool status derivation, elapsed time, and memo comparison. |
web/design/src/components/agent-elements/tools/tool-group.tsx |
Subagent/task tool group with nested tool rows and progressive reveal. |
web/design/src/components/agent-elements/tools/tool-approval-footer.tsx |
Reusable approve/reject footer for tool cards. |
web/design/src/components/agent-elements/tools/ipython-tool.tsx |
IPython cell card with cell index, code, output, and kernel status. |
web/design/src/components/agent-elements/tools/bash-tool.tsx |
Terminal card for bash commands. |
web/design/src/components/agent-elements/tools/edit-tool.tsx |
Diff card for edit/write tools. |
web/design/src/components/agent-elements/tools/plan-tool.tsx |
Plan card with approval and refine actions. |
web/design/src/components/agent-elements/tools/mcp-tool.tsx |
MCP tool card with argument formatting and JSON output. |
packages/coding-agent/src/modes/interactive/components/tool-execution.ts |
TUI container for tool call rendering. |