Trace viewer
ProOne run as a timeline: each span (agent step, model call, tool, external call, a wait for a person) as a bar on a shared clock, nested under its parent. Opens on the first failure. Select a span for its detail; an open span (still running) runs to "now" with a striped end. The span that broke is solid red; ancestors that failed because of it are pale red.
Preview
Install
With the Candor CLI
First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/trace-viewer
Brings in: locale, ops, status, step-list, utils · npm: lucide-react@^1.67.0
Usage
"use client"
import { TraceViewer } from "@/components/trace-viewer"
import type { AgentIdentity } from "@/lib/chat"
import type { TraceSpan } from "@/lib/ops"
const keel: AgentIdentity = { id: "a-keel", name: "Keel", role: "orchestrator" }
const dev: AgentIdentity = { id: "a-dev", name: "Dev agent", role: "dev" }
const qa: AgentIdentity = { id: "a-qa", name: "QA agent", role: "qa" }
const spans: TraceSpan[] = [
{ id: "s0", name: "Add region to projects", kind: "agent", start: 0, duration: 431_000, status: "failed", agent: keel },
{ id: "s1", parentId: "s0", name: "Plan the change", kind: "model", start: 800, duration: 14_200, status: "succeeded", detail: "Claude Opus 5.5 · 18k in / 1.2k out" },
{ id: "s2", parentId: "s0", name: "Dev agent: build on Staging", kind: "agent", start: 16_000, duration: 300_000, status: "failed", agent: dev },
{ id: "s3", parentId: "s2", name: "migration.apply 0142", kind: "tool", start: 18_000, duration: 14_000, status: "succeeded" },
{ id: "s4", parentId: "s2", name: "Backfill: 19 batches", kind: "external", start: 34_000, duration: 264_000, status: "failed", error: "Batch 12 hit a lock timeout four times; the run was stopped.", detail: "18,240 projects; 11,000 updated before the stop." },
{ id: "s5", parentId: "s0", name: "Wait: ask Dana whether a job writes projects", kind: "wait", start: 318_000, duration: 108_000, status: "succeeded" },
{ id: "s6", parentId: "s0", name: "QA agent: tests", kind: "agent", start: 428_000, duration: 3_000, status: "skipped", agent: qa },
]
export default function Example() {
return <TraceViewer spans={spans} total={431_000} />
}<TraceViewer>
| Prop | Type | Default | Description |
|---|---|---|---|
| spansrequired | TraceSpan[] | — | The run's spans, each with its parent, start and duration in ms from the run's start; no duration means still running. |
| totalrequired | number | — | ms; the run's length so far. |
| className | string | undefined | — | Extra classes for the outer element. |
Strings
The fixed words, in English by default. Change any of them under traceViewer in <LocaleProvider strings={{ … }}>; the table is exported as traceViewerStrings.
| Key | English |
|---|---|
| trace | Trace |
| span | Span |
| spans | Spans |
| spanDetail | Span detail |
| kindAgent | Agent |
| kindModel | Model call |
| kindTool | Tool |
| kindExternal | External call |
| kindWait | Waiting |
| kindOther | Other |
| spanRunning | starts {start}, still running, {status} |
| spanTakes | starts {start}, takes {duration}, {status} |
| starts | Starts |
| takes | Takes |
| stillRunning | Still running |
| agent | Agent |