- BuildingCompiling TypeScript and bundling assets
- Running Tests147 tests across 23 suites
- Deploy to ProductionUpload to edge nodes
import { ProgressTracker } from "@/components/tool-ui/progress-tracker";export function Example() { return ( <ProgressTracker id="progress-tracker-example" steps={[ { id: "build", label: "Building", description: "Compiling TypeScript and bundling assets", status: "completed", }, { id: "test", label: "Running Tests", description: "147 tests across 23 suites", status: "in-progress", }, { id: "deploy", label: "Deploy to Production", description: "Upload to edge nodes", status: "pending", }, ]} elapsedTime={43200} responseActions={[{ id: "cancel", label: "Cancel", variant: "outline" }]} onResponseAction={(actionId) => console.log(actionId)} /> );}Visual states for pending, in-progress, completed, and failed steps
Optional time tracking with automatic formatting
Failed step indicators with descriptive error messages
Terminal state view showing complete operation history
Each step has one of four statuses:
The component automatically highlights the current step (in-progress or first pending) with a subtle background and aria-current="step" for accessibility.
Use the choice prop to render a terminal state after an operation completes, fails, or is cancelled. The receipt displays the full step history with an outcome indicator, which works well in conversation history.
Receipt features:
success, partial, failed, and cancelled outcomesrole="status" for screen reader announcementsPass elapsedTime in milliseconds to display a timer badge. Automatically formatted as:
3.4s2m 15s<ProgressTracker id="elapsed-time-example" steps={[ { id: "parse", label: "Parse CSV", status: "completed" }, { id: "validate", label: "Validate Records", status: "in-progress" }, { id: "import", label: "Import to Database", status: "pending" }, ]} elapsedTime={247800}/>Copy components/tool-ui/progress-tracker and the shared directory into your project. The shared folder contains utilities used by all Tool UI components. The tool-ui directory should sit alongside your shadcn ui directory.
This component requires the following shadcn/ui components:
pnpm dlx shadcn@latest add button"use client";import { makeAssistantTool } from "@assistant-ui/react";import { ProgressTracker, ProgressTrackerErrorBoundary, parseSerializableProgressTracker, SerializableProgressTrackerSchema, type SerializableProgressTracker,} from "@/components/tool-ui/progress-tracker";export const ProgressTrackerTool = makeAssistantTool<SerializableProgressTracker>({ toolName: "trackProgress", description: "Display real-time progress for multi-step operations", parameters: SerializableProgressTrackerSchema, render: ({ args, toolCallId }) => { if (!(args as any)?.steps) return null; const data = parseSerializableProgressTracker({ ...args, id: (args as any)?.id ?? `progress-tracker-${toolCallId}`, }); return ( <ProgressTrackerErrorBoundary> <ProgressTracker {...data} onResponseAction={async (actionId) => { if (actionId === "cancel") { console.log("Cancelled operation"); } }} /> </ProgressTrackerErrorBoundary> ); },});Mount <ProgressTrackerTool /> under <AssistantRuntimeProvider> to register the tool and its UI.
Prop
Type
Prop
Type
Prop
Type
<article> with role="status" and aria-live="polite" for live updatesaria-busy indicates when an operation is in progressaria-current="step" marks the currently active step<ul> / <li>)Tab to focus action buttons, Enter or Space to activateprefers-reduced-motion