Recipes
Local trace viewer
Persist agent spans to disk and open a self-contained HTML waterfall — Jaeger-style, no server required.
Cloud trace viewers are great, but for local development you want
something you can open offline, share as an artifact, and inspect
without a network round-trip. @agentskit/observability ships a
tiny file-backed trace sink plus a zero-dependency HTML renderer
that produces a single-file gantt view of any run.
Install
Comes with @agentskit/observability.
Record spans to disk
import { createFileTraceSink, createTraceTracker } from '@agentskit/observability'
import { createRuntime } from '@agentskit/runtime'
import { anthropic } from '@agentskit/adapters'
const sink = createFileTraceSink('./traces')
const tracker = createTraceTracker({
onSpanStart: sink.onSpanStart,
onSpanEnd: sink.onSpanEnd,
})
const runtime = createRuntime({
adapter: anthropic({ apiKey: process.env.ANTHROPIC_API_KEY!, model: 'claude-sonnet-4-6' }),
observers: [{ name: 'tracker', on: e => tracker.handle(e) }],
})
await runtime.run('What happened in Q3?')
const out = await sink.flush({ traceId: 'q3-summary' })
console.log('json:', out.json, 'html:', out.html)Open ./traces/q3-summary.html in a browser — it's a self-contained
page with no external requests.
Programmatic rendering
If you already have spans from somewhere else (OpenTelemetry export, a saved log file), turn them into a report and render HTML directly.
import { buildTraceReport, renderTraceViewerHtml } from '@agentskit/observability'
const report = buildTraceReport('my-trace', mySpans)
await Bun.write('trace.html', renderTraceViewerHtml(report))What's in a report
{
traceId: string,
startTime: number,
endTime: number,
durationMs: number,
spanCount: number,
errorCount: number,
spans: TraceSpan[], // sorted by startTime
}See also
- Devtools server — live feed for an external UI
- OpenTelemetry observer