Prodular UI

Tool call

AI

One tool invocation by a model: name, a short summary of its arguments and its status, with the input and output inside the same container.

npx prodular-ui add tool-call

Statuses

Done with its duration, running with a shimmer, queued, failed and waiting for approval.

Input
{
  "vendor": "Northbeam Logistics",
  "status": "unpaid",
  "limit": 20
}
Output
{
  "count": 2,
  "invoices": [
    {
      "id": "INV-20931",
      "amount": 18240.5,
      "due": "2026-10-30"
    },
    {
      "id": "INV-20977",
      "amount": 9612,
      "due": "2026-11-14"
    }
  ]
}

Approval

Actions with side effects wait for a person. The buttons sit under a divider in the same container.

Input
{
  "invoice": "INV-20931",
  "amount": 18240.5,
  "currency": "USD",
  "method": "ACH",
  "pay_on": "2026-10-29",
  "from_account": "Operating ****4410"
}
Copilot wants to schedule a payment. It runs on Oct 29.

Anatomy

<ToolCall status="done">  <ToolCallHeader>    <ToolCallIcon><ReceiptIcon /></ToolCallIcon>    <ToolCallTitle>Search invoices</ToolCallTitle>    <ToolCallSummary>vendor: Northbeam</ToolCallSummary>    <ToolCallStatus duration="0.9s" />  </ToolCallHeader>  <ToolCallContent>    <ToolCallSection label="Input" value={input} />    <ToolCallSection label="Output" value={output} />  </ToolCallContent></ToolCall>

Guidance

Use it when

  • For every tool the model calls, in the order it called them, between Reasoning and Response.
  • Approval for anything that writes, sends, pays or deletes.

Avoid

  • Showing raw tool names like search_invoices_v2. Write a human title: Search invoices.
  • Opening every call by default. Keep them collapsed unless one failed or needs approval.
  • Nesting code blocks or cards inside. ToolCallSection already separates input and output with dividers.

Rules for AI agents

Published in llms-full.txt, the registry and the MCP server, so coding agents follow them when they build with this component.

  • Always pass status, and update it as the call progresses: pending, running, then done or error. Use approval when a person must allow the call before it runs.
  • Write ToolCallTitle as verb plus object (Search invoices, Schedule payment) and ToolCallSummary as the two or three arguments that matter, not the full JSON.
  • Pass duration to ToolCallStatus when status is done.
  • Put objects in ToolCallSection value. It formats JSON and adds a copy button. Use label Input, Output or Error.
  • For approval, render ToolCallApproval with one sentence that says what will happen, a ghost Deny button and a default button that names the action. Never run the tool before approval.
  • Render a failed call with status error and an Error section, and let the model explain the failure in its Response.

API

ToolCall

PropTypeDefaultDescription
status"pending" | "running" | "done" | "error" | "approval""pending"Drives the icon, shimmer, label and border.
open / defaultOpenbooleanWhether input and output are visible.

ToolCallStatus

PropTypeDefaultDescription
durationstringReplaces Done once finished, for example 1.4s.

ToolCallSection

PropTypeDefaultDescription
labelstringInput, Output or Error.
valueunknownObjects render as formatted JSON, strings as they are.

Installation

The Prodular UI CLI adds the source to components/ui with everything it depends on. In a project that already uses shadcn/ui, the shadcn CLI installs it from the Prodular registry too. See Installation for the first setup.

npx prodular-ui add tool-call# or, with the registry in components.jsonnpx shadcn@latest add @prodular/tool-call

Used in these screens