Trace
One line primitive for every agent step on a vertical rail: status glyph, label, mono detail and duration, with ten states and expandable details.
On this page
A coding agent reasons, reads files, searches the web, edits after approval, runs the tests and answers with citations.
The run above combines every Agents component: Reasoning, a TraceGroup of reads, web search, an edit that asks for approval, a shell command that streams, then the answer with Citation and Sources. Each sits on one rail through TraceItem.
Installation
Usage
import { Trace, TraceItem, TraceStep } from "@/components/ui/chatcn/trace"
import { ToolCall } from "@/components/ui/chatcn/tool-call"
<Trace>
<TraceStep status="done" label="Read" detail="src/app/runs/page.tsx" durationMs={84} />
<TraceStep status="running" label="Run" detail="pnpm test --filter web" />
<TraceItem>
<ToolCall variant="inline" name="edit_file" state="approval-requested" {...props} />
</TraceItem>
</Trace>TraceStep is a plain row unless it has children, so a trace of hundreds of steps renders no disclosure machinery. Wrap anything else (an inline tool call, Reasoning) in TraceItem to put it on the rail.
Examples
Every state
All ten step states on one rail.
Expandable steps
Children make a step expandable. Errors and approval requests open by themselves; the chevron appears on hover so a long trace is not a column of arrows.
Steps with details: a plan, a read summary and an error.
States
| Status | Glyph | End of row |
|---|---|---|
pending | Hollow ring | Nothing |
running | Spinner | Running, then elapsed seconds |
done | icon, or a check | Duration |
error | Red cross | Failed |
approval-requested | Hand | Needs approval |
approval-responded | Spinner | Approved, then elapsed seconds |
denied | Ban | Denied |
cancelled | Stop | Cancelled |
retrying | Retry arrow | Retry 2 of 3 |
skipped | Dash | Skipped |
Props
| Prop | Type | Notes |
|---|---|---|
Trace.density | "default" | "compact" | Compact is 28 px rows with dots, used inside groups |
TraceStep.status | TraceStatus | One of the ten states |
label | ReactNode | What the step does, in medium weight |
detail | ReactNode | Path, query or command in mono. Truncates |
icon | ReactNode | Glyph at rest. Defaults to a check |
meta | ReactNode | Replaces the status text and timer |
durationMs, startedAt | number | Measured automatically when omitted |
attempt | { current, total? } | Shown while retrying |
children | ReactNode | Makes the step expandable |
open, defaultOpen, onOpenChange | Controlled or uncontrolled | |
TraceItem.connector | boolean | Draw the rail down to the next item. Default true |
Keyboard
| Key | Action |
|---|---|
Tab | Move between expandable steps |
Enter, Space | Expand or collapse a step |
Accessibility
- The trace is an ordered list. Every row starts with its status in visually hidden text, so a screen reader hears Failed: Fetch api.tallyline.app.
- Expandable steps are Base UI Collapsible triggers with
aria-expanded. - Failure is never color alone: the red cross sits next to the word Failed.
Motion
- The status glyph swaps with a 150 ms blur crossfade, only when the status changes. A trace that mounts already finished is perfectly still.
- Details open over 200 ms and close over 150 ms. The chevron fades in on hover.
- Timers tick once per second, aligned to the start time. Under reduced motion nothing moves but the spinner.