ToolRenderer

Render one tool part (AI SDK v5 shape: { type, toolCallId, state, input, output }) with the matching card: tool-Bash → BashTool, tool-Edit and tool-Write → EditTool, tool-Grep, tool-Glob and tool-WebSearch → SearchTool, tool-TodoWrite → TodoTool, tool-PlanWrite → PlanTool, tool-Question → QuestionTool, tool-Task and tool-Agent → ToolGroup with nestedTools, tool-Thinking → ThinkingTool, tool-mcp__<server>__<tool> → McpTool. Types listed in toolRegistry render as GenericTool with a title, and anything else as a generic row with the tool name. dynamic-tool parts are routed by their toolName. Entries in toolRenderers are keyed by the full part type (tool-Bash, tool-mcp__git__search) and take precedence over built-in cards; a bare name only matches mcp__user-tools__<name>. They receive name, input, output (unwrapped for MCP), status (streaming, pending, success, error), part and onAction, which reports to onToolAction. Pass chatStatus so a tool without output is shown as pending while the chat streams and as finished after it stops. MessageList uses ToolRenderer for every tool part, so in a chat you usually pass toolRenderers to AgentChat instead. The card parts are also exported for custom layouts: BashToolTerminalCard, EditToolDiffCard, SearchGroupRich, ThinkingCollapsed and GenericToolRow.

Getting Started
$pnpm add @sinups/ai-kit @mantine/core @mantine/hooks @tabler/icons-react
Examples
Built-in cards
Custom renderer
API reference
Prop
Type
Required
part
ToolPart
Yes
Tool part in AI SDK v5 shape: `{ type, toolCallId, state, input, output }`
nestedTools
ToolPart[]
No
Tool parts nested under this part, passed to `ToolGroup` for `tool-Task` / `tool-Agent`
chatStatus
string
No
Chat status from `useChat()`, used to tell a pending tool from an interrupted one
toolRenderers
Record<string, React.ComponentType<CustomToolRendererProps>>
No
Custom renderers keyed by part type (`tool-Bash`, `tool-mcp__git__search`), which take precedence over the built-in card, or by `<name>` for `mcp__user-tools__<name>`
onToolAction
ToolActionHandler
No
Receives actions reported by custom renderers through `onAction`
wrapLines
boolean
No
Wraps long lines in diffs instead of scrolling them sideways