Tracing

Structured records of provider calls, tools, handoffs, approvals, and memory.

Tracing

A Shiro trace is a structured record of one run: provider calls, tool spans, handoffs, approvals, memory operations, timing, usage, and outcomes. Studio is a UI on top of that record. Logs are not a substitute.

Why traces exist#

A log line says something failed. A trace answers where in the run:

  1. Provider input
  2. Tool request + arguments
  3. Tool result / error
  4. Handoff decision
  5. Approval state
  6. Memory reads
  7. Output validation

Debug in that order unless you already know the failing stage.

Wiring a TraceManager#

import { ConsoleTraceExporter, Engine, JsonTraceExporter, TraceManager } from "@shiro-sdk/core";

const traces = new TraceManager();
const engine = new Engine({ events: traces });

// ... plugins, agent ...
await engine.execute(agent, input);

await traces.export(new ConsoleTraceExporter());
const json = await traces.export(new JsonTraceExporter());

Pass the same traces instance (or event bus) you want Studio and exporters to share. See Engine.

What to export#

DestinationUse
ConsoleLocal smoke tests
JSONBug reports, fixtures, Studio replay
Custom exporterYour observability pipeline

Studio can load exported JSON / replay mock traces while you iterate. Live attachment to a running engine uses the same event shapes — keep panel code stream-oriented.

Events vs spans#

  • Events — points in time (tool.started, approval.granted)
  • Spans — intervals with duration (provider call, tool execution)

Studio’s timeline prefers spans; the trace viewer shows both.

Best practices#

  • Trace successes and failures
  • Keep runId in application error responses
  • Attach JSON exports to issues instead of screenshots of logs
  • Open Studio while building new tools — catch bad args early

Common mistakes#

  • Logging only the final string answer
  • Dropping tool arguments from exports
  • Treating provider latency as total run latency
  • Calling tools outside the runner and wondering why traces are empty