AI Tool Call Display

Structured card for tool invocation traces, statuses, serialized input, and returned output. Install AI Tool Call Display from the VLLNT UI registry with the shadcn CLI.

Report a bug

When to use this in an AI app

Use AI Tool Call Display whenever an agent invokes tools or functions. It surfaces the call name, arguments, status, and result so users can follow exactly what the agent did.

Browse all AI agent components

Structured card for tool invocation traces, statuses, serialized input, and returned output. Part of the ai family in VLLNT UI, it ships as a machine-readable registry entry — copy the source directly into your app with the shadcn CLI and own it, no runtime dependency on a component library.

Preview

Switch between light and dark to inspect the embedded Storybook preview.

Installation

Add AI Tool Call Display to your project with the shadcn CLI. The source lands in your codebase, ready to adapt:

pnpm dlx shadcn@latest add https://ui.vllnt.ai/r/ai-tool-call-display.json

Source

import { cva } from "class-variance-authority"; import { AlertCircle, CheckCircle2, Clock3, Wrench } from "lucide-react"; import { cn } from "../../lib/utils"; import { Badge } from "../badge/badge"; const statusVariants = cva( "rounded-full px-2 py-0 text-[10px] uppercase tracking-wide", { defaultVariants: { status: "queued", }, variants: { status: { complete: "bg-emerald-500/10 text-emerald-700 dark:text-emerald-300", error: "bg-red-500/10 text-red-700 dark:text-red-300", queued: "bg-muted text-muted-foreground", running: "bg-blue-500/10 text-blue-700 dark:text-blue-300", }, }, }, ); export type AIToolCallStatus = "complete" | "error" | "queued" | "running"; export type AIToolCallDisplayProps = React.ComponentPropsWithoutRef<"div"> & { /** Short description of the tool output. */ description?: string; /** Optional execution duration label. */ duration?: string; /** Serialized tool arguments or input payload. */ input?: string; /** Serialized tool result or output payload. */ output?: string; /** Current tool execution state. */ status?: AIToolCallStatus; /** Name of the tool. */ toolName: string; }; const statusIconMap: Record<AIToolCallStatus, React.ReactNode> = { complete: <CheckCircle2 className="size-4" />, error: <AlertCircle className="size-4" />, queued: <Clock3 className="size-4" />, running: <Wrench className="size-4 animate-pulse" />, }; const AIToolCallDisplay = ({ className, description, duration, input, output, ref, status = "queued", toolName, ...props }: AIToolCallDisplayProps & { ref?: React.Ref<HTMLDivElement> }) => { return ( <div className={cn( "rounded-2xl border border-border/70 bg-card p-4 shadow-sm", className, )} ref={ref} {...props} > <div className="flex flex-wrap items-start justify-between gap-3"> <div className="min-w-0 space-y-1"> <div className="flex items-center gap-2 text-sm font-medium text-foreground"> {statusIconMap[status]} <span>{toolName}</span> </div> {description ? ( <p className="text-sm text-muted-foreground">{description}</p> ) : null} </div> <div className="flex items-center gap-2"> {duration ? ( <span className="text-xs text-muted-foreground">{duration}</span> ) : null} <Badge className={statusVariants({ status })} variant="secondary"> {status} </Badge> </div> </div> {input ? ( <details className="mt-4 rounded-xl border border-border/60 bg-muted/20 p-3" open={status !== "complete"} > <summary className="cursor-pointer text-xs font-medium uppercase tracking-wide text-muted-foreground"> Tool input </summary> <pre className="mt-3 overflow-x-auto whitespace-pre-wrap text-xs leading-5 text-foreground"> {input} </pre> </details> ) : null} {output ? ( <details className="mt-3 rounded-xl border border-border/60 bg-muted/20 p-3" open={status !== "complete"} > <summary className="cursor-pointer text-xs font-medium uppercase tracking-wide text-muted-foreground"> Tool output </summary> <pre className="mt-3 overflow-x-auto whitespace-pre-wrap text-xs leading-5 text-foreground"> {output} </pre> </details> ) : null} </div> ); }; AIToolCallDisplay.displayName = "AIToolCallDisplay"; export { AIToolCallDisplay };

Stories

Explore every variant and state in the interactive Storybook:

Preview

Switch between light and dark to inspect the embedded Storybook preview.

Dependencies

  • @vllnt/ui@^0.3.0
  • class-variance-authority
  • lucide-react