Tracer
In-memory TraceEvent collector with emit, aiter replay, and TraceKind event kinds used by the agent runner.
Tracer
Tracer is the in-memory event collector the runner uses for every agent run. It assigns run_id, seq, and event_id, buffers the full history in tracer.events, and fans out live events to async subscribers via aiter().
import { Tracer, runAgent } from "@maniac-ai/agents";
const tracer = new Tracer({ run_id: "support-turn-7" });
const result = await runAgent(spec, "Reset my password", { tracer });
console.log(result.trace.length); // same as tracer.events.lengthPass the same tracer into runAgentStream so streaming consumers and the final AgentResult share one buffer. BackgroundTaskDispatcher gives each child task its own tracer and merges events into the parent dispatcher tracer.
emit
tracer.emit(kind, payload, options);kind— aTraceKinddiscriminator (see table below)payload— typed JSON payload for that kind (nested underevent.payload)options— envelope overrides:depth,principal,span_id,parent_span_id,turn_id,message_id,thread_id, token-specificdelta/chunk_kind, etc.
The tracer overwrites seq, event_id, and run_id on every emit so producers cannot break ordering invariants.
aiter and replay
runAgentStream calls tracer.enableStreaming() then iterates tracer.aiter(). Each subscription:
- Replays every event already buffered (late subscribers never miss history)
- Yields live events as they are emitted
- Terminates when
tracer.close()sends a sentinel
One consumer per aiter() call is recommended — async generators cannot be multiplexed across multiple awaiters.
const tracer = new Tracer();
tracer.enableStreaming();
const run = runAgent(spec, query, { tracer });
for await (const event of tracer.aiter()) {
if (event.kind === "final") break;
handle(event);
}
const result = await run;Trace kinds
kind | Typical use |
|---|---|
lm_call_start / lm_call | Model request/response pair per iteration |
token | Streaming text, reasoning, or structured partials |
tool_call_arguments_delta | Streaming tool-call JSON args |
tool | Tool invocation result (includes result_preview when completed) |
step | Step hook before/after/stopped |
guardrail | Block or rewrite from LM/tool guardrails |
approval | HITL approval requested |
agent / subagent | Inner-agent boundary |
memory | Conversation / observation / working-memory writes |
retry | RetryingModel / FallbackModel attempt |
cell | Python REPL execution |
background_task | Dispatcher lifecycle |
plan | Plan primitive updates (ACP) |
final / error | Terminal run outcome |
Switch on event.kind for typed narrowing — payloads are validated by Zod schemas in @maniac-ai/agents/schemas.
AgentResult.trace
runAgent returns result.trace as a snapshot of tracer.events at completion. Errored and cancelled runs still populate trace (and often messages) from the partial run via RunCancelledError.partial.
Integration points
- Inference adapters —
RetryingModelandFallbackModelaccept an optionaltracerand emitretryevents - Memory stores — pass
{ tracer }on write methods to emitmemoryevents - Middleware / guardrails — blocked decisions emit
guardrailevents (see Guardrails) - OTelTracer — wraps
Tracerand translates the same stream to spans (see OTelTracer)