Expand description
TelemetryHook — maps the agent’s lifecycle Event stream onto
structured tracing spans and events, so a run becomes observable in any
tracing subscriber.
Why tracing and not a hard OpenTelemetry dependency? Because tracing is
the idiomatic Rust instrumentation seam: the library emits spans + events,
and the binary chooses the exporter. Attach
tracing-opentelemetry with an
OTLP pipeline and every span below is exported to Jaeger / Tempo / any OTLP
backend with zero changes here; attach tracing_subscriber::fmt().json()
and you get newline-delimited JSON for log pipelines. One instrumentation,
many backends.
Span/event shape (target harness.telemetry):
agent_run (span, fields: source)
├─ run.start
├─ iter (iter)
├─ model.complete (input_tokens, output_tokens, cached_input_tokens, tool_calls, stop)
├─ tool.call (tool, ok, duration_ms)
├─ sensor (sensor, signals)
├─ compact (stage)
├─ budget.warning (ratio)
└─ run.endWire it like any hook:
ⓘ
let loop_ = AgentLoop::new(model).with_hook(std::sync::Arc::new(TelemetryHook::new()));Structs§
- Telemetry
Hook - Emits a span per run and a structured event per model call, tool call, sensor, compaction, and budget warning. See the module docs for the OTLP bridge.