Tool

A status-aware collapsible row for a tool invocation. The kit owns the disclosure, the state visualization, and the section layout. The caller owns every detail that goes inside.

Anatomy

A tool call is one trigger row plus an expandable body. The row shows a status icon, the tool name, and an optional one-line summary. The body holds any combination of labeled sections, raw blocks, code, markdown, or an error.

The component has no view of the runtime. state is a five-value enum the caller passes in: pending while arguments are still streaming in, approval while the call is waiting on a user decision, running while execution is underway, success when output arrives, error when it fails. The kit mirrors it onto data-state, which drives the trigger pulse, the approval ring, the spinner icon, the destructive tint, and ToolError.

ToolBlock is a thin scrollable monospace container for raw text or JSON. Reach for CodeBlock instead when the body deserves a header and copy action.

TSX

Mapping TanStack AI tool-call states

TanStack AI surfaces a six-value ToolCallState on each tool-call part plus a separate three-value ToolResultState on the matching result. Several of those values are visually indistinguishable in a chat thread, so the kit collapses them into five. Read the table left to right when you wire a renderPart switch.

TanStack sourcestate
tool-call.state = "awaiting-input"pending
tool-call.state = "input-streaming"pending
tool-call.state = "input-complete"pending
tool-call.state = "approval-requested"approval
tool-call.state = "approval-responded"running
tool-result.state = "streaming"running
tool-call.state = "complete"success
tool-result.state = "complete"success
tool-result.state = "error"error

The component never sees a TanStack type. The mapping lives in the caller's renderPart switch, alongside the rest of the bridge code.

API

Reference for each part of the component, including its available props and behavior.

Tool

Root collapsible. Carries the named group tool and writes state to data-state so descendants can hang style off it. Accepts every Collapsible.Root prop, so open, defaultOpen, and onOpenChange work the usual way.

Prop

ToolTrigger

The header row. The whole row is the button: status icon, name, summary, and a chevron that docks right and rotates on open. Goes destructive when the ancestor is in the error state, so the icon and text turn red without extra wiring.

Prop

ToolIcon

The leading icon for the call. The caller passes a single SVG that represents the tool: a globe, a file, a database glyph. It inherits the trigger's color, so it turns destructive in the error state with no extra wiring.

The kit owns one piece of state-aware behavior here: while the call is running, the user's icon is hidden and an animated spinner takes its place. As soon as the state moves to success or error, the user's icon comes back.

Prop

ToolName

The tool identifier. Monospace and medium weight so it reads as the headline of the row. Inherits destructive color from the trigger when the call failed.

Prop

ToolLabel

Optional inline summary next to the name. A short phrase that captures the input or the result at a glance: a city, a file path, a row count. Truncates when crowded.

Prop

ToolContent

Expanding panel. Animates height open and close, indents the body, and runs a vertical rail down the left so the detail reads as nested under the trigger.

Prop

ToolSubtitle

A small uppercase label for sections inside the panel. Drop one before each block to mark what it is: input, output, sources, anything.

Prop

ToolBlock

A scrollable monospaced container for raw text or JSON. Capped at a reasonable height so a large payload does not push the rest of the thread off screen. Pre-wraps long lines. Use a CodeBlock instead when you want syntax highlighting or a header.

Prop

ToolError

Destructive-tinted slot for the failure message. Hidden unless the ancestor Tool is in the error state, so it is safe to leave in the tree at all times. The body is free-form: a single line, a paragraph, a retry button.

Prop

ToolArgument

A compact key/value viewer for a tool call's raw arguments JSON string. Backed by a partial parser, so it renders best-effort rows while the model is still typing tokens and keeps every key it has already locked in.

Pass state="streaming" while the buffer is still growing. The last value pulses to signal the cursor. Switch to state="complete" when the final token lands and the pulse settles. Empty input renders nothing, so the panel does not jump as the first character arrives. Unparseable input falls back to a plain monospace block of the raw text, also pulsing while streaming.

Reach for ToolBlock instead when the input is already a finished payload and you just want to dump it.

Prop