Docs

React UI

Tool calls

Render pending, settled, and custom tool call states in message parts.

Default rendering

Message.Part delegates tool parts to Message.Tool, so most chat surfaces get tool rendering without extra code.

<Message.Parts>
  <Message.Part />
</Message.Parts>

Message.Tool shows the tool name, status, input, output, and error content when each field is available.

Tool parts come from server-side agent/tool streams. The UI does not execute tools in the browser. For the route and tool definition, see Tools end to end.

Pending and settled states

Use renderWhen to decide when a tool call should appear.

<Message.Tool renderWhen="always" className="tool-call" />
<Message.Tool renderWhen="pending" className="tool-call pending" />
<Message.Tool renderWhen="settled" className="tool-call settled" />

renderWhen="always" is the default. Pending means the input is streaming or available. Settled means output is available or the tool call ended in an error.

Custom tool cards

Compose the smaller tool primitives when the design system owns the card layout.

import { Message } from "@anvia/react-ui";

export function ToolCard() {
  return (
    <Message.Tool className="tool-card" renderWhen="always">
      <header className="tool-card-header">
        <Message.ToolName />
        <Message.ToolStatus />
      </header>
      <section className="tool-card-section">
        <Message.ToolInput />
      </section>
      <section className="tool-card-section">
        <Message.ToolOutput />
        <Message.ToolError />
      </section>
    </Message.Tool>
  );
}

The child function receives the full tool part when a product component wants to format everything itself.

<Message.Tool>
  {(part) => (
    <ToolCallCard
      name={part.toolName}
      state={part.state}
      input={part.input}
      output={part.output}
      error={part.error}
    />
  )}
</Message.Tool>

Use this when the tool output is domain-specific:

<Message.Tool>
  {(part) =>
    part.toolName === "lookup_order" && part.output !== undefined ? (
      <OrderLookupResult value={part.output} />
    ) : (
      <Message.ToolOutput />
    )
  }
</Message.Tool>

Filtering noisy tools

Use Message.Parts filtering when a surface should hide tool calls until a result is available.

<Message.Parts
  filter={(part) => part.type !== "tool" || part.state === "output-available"}
/>

Use the inverse for an activity panel that only shows pending tool work.

<Message.Parts filter={(part) => part.type === "tool" && part.state !== "output-available"}>
  <Message.Part />
</Message.Parts>

For a combined tool and review flow, see Tool and human input.