Tool call
Shows a tool the agent called, with its arguments, status and result. Use it inside a reply wherever the agent acts.
Loading preview…
Install
- 1
Run this command in your Tailwind CSS project. It adds
components/ai/tool-call-card.tsxand installs its dependencies.$ npx shadcn@latest add https://gradientdeck.com/ai-components/r/tool-call-card.json
Build an AI agent tool approval flow in React →
Usage & API
Example
import { ToolCallCard } from "@/components/ai/tool-call-card"
<ToolCallCard
name="…"
summary="…"
status={status}
input={input}
/>Props ToolCallCard
| Prop | Type & description | Required |
|---|---|---|
name | string | Required |
summary | stringShort, human summary of the arguments, e.g. a path or a query. | Required |
status | ToolCallStatus | Required |
input | Record<string, unknown> | Required |
output | string | Optional |
duration | numberSeconds, shown once the call has finished. | Optional |
server | stringThe server or integration the tool belongs to, e.g. "postgres". | Optional |
icon | ComponentType<{ className?: string }> | Optional |
defaultOpen | boolean | Optional |
Dependencies
- React
- Tailwind CSS
- motion
- lucide-react
Implementation notes
The header button shows an icon, then server and the tool name when server is set, then summary in a truncated monospace span, then the status. pending reads Waiting. running shows a spinner and the word Running. error reads Failed. done shows duration to one decimal place, or the word Done when duration is omitted. Opening the header reveals Request, which pretty-prints input, and Response. output is shown only when status is done or error. A running call says it is waiting for a response, and a pending call says it has not been sent yet. defaultOpen starts the body expanded. The icon defaults to a search mark.
Example
import { ToolCallLine } from "@/components/ai/tool-call-inline"
<ToolCallLine
verb="…"
target="…"
status={status}
/>Props ToolCallLine
| Prop | Type & description | Required |
|---|---|---|
verb | stringPast-tense verb once done, e.g. "Read". Shown as-is. | Required |
target | string | Required |
status | ToolCallLineStatus | Required |
duration | numberMilliseconds. | Optional |
icon | ComponentType<{ className?: string }> | Optional |
detail | string | Optional |
Dependencies
- React
- Tailwind CSS
- motion
- lucide-react
Implementation notes
One row, no container, meant to sit between paragraphs. verb is the word on the left and is shown as you pass it, so a running call can read Searching while a finished one reads Searched. target sits beside it in monospace. detail is an optional short note, and it uses the error color when status is error. A spinner replaces the icon while status is running. The icon defaults to a terminal mark. duration formats as milliseconds under one second and as seconds otherwise, and it fades in on hover once the call is no longer running. There is no expand. If the payload matters, use the card.
Example
import { ToolCallStack } from "@/components/ai/tool-call-stack"
<ToolCallStack
calls={[]}
/>Props ToolCallStack
| Prop | Type & description | Required |
|---|---|---|
calls | StackedCall[] | Required |
total | numberTotal calls the agent plans to make, if known. | Optional |
defaultOpen | boolean | Optional |
Dependencies
- React
- Tailwind CSS
- motion
- lucide-react
Implementation notes
The header is a single button. While any call has status running it reads Working and shows how many calls are in the list, followed by of total when total is set. When nothing is running it reads Used N tools, and it adds a failed count when any call has status error. Collapsed, only the running call is shown under the header, and that row swaps as the current call changes. Each row shows a spinner or the call's icon, then label, target, and the word failed on an error. Opening the header lists every call in order. defaultOpen starts that list open. A stack row has id, label, target, status and icon, and it has no request body.
Choosing a layout
Place it in the reply at the moment the agent acts, not in a side panel the message then has to point at. A person scanning the thread should see what was attempted without expanding anything. Open the card when the exact arguments matter, such as the query sent to a database, because summary is only a human label and input is the object that was actually sent. Leave the card closed, or use the line, when the following sentence already paraphrases the result.
Use a stack when a run of calls would turn the reply into a wall of rows. While any call is running the header reads Working, and total, if you pass it, shows how far through a known set the agent is. Prefer terminal when the action was a shell command with streamed output, file edit when the result is a diff, and web search when the result is a list of pages. Do not use a tool call to ask permission. That pause is tool approval, which offers deny, allow once and always allow.
Does this run the tool, or only draw the call?
It only draws the call. status, input, output, verb, detail and the stack's calls are values you set. Moving a card from Running to a duration means you changed status to done and passed duration. The line shows detail and its hover time only after you take it out of running. There is no fetch, no retry and no clock inside the file.
Why does the response say the call was not sent?
On the card, Response renders output only when status is done or error. pending uses the line Not sent yet, and running uses Waiting for a response. An open card that is still pending shows the request JSON beside that empty response, which is how a queued call looks different from a failure that already has output.