agentkit-reporting
Observers for turning loop events into logs, summaries, and transcript views.
This crate provides [LoopObserver] implementations for [agentkit-loop].
Instead of baking reporting into the driver, you attach one or more reporters
to the loop and they react to every AgentEvent that flows through it.
Included reporters
| Reporter | Purpose |
|---|---|
StdoutReporter |
Human-readable bracketed log lines ([turn] started ...) |
JsonlReporter |
Machine-readable newline-delimited JSON envelopes |
UsageReporter |
Aggregated token counts and cost totals |
TranscriptReporter |
Growing snapshot of conversation items |
CompositeReporter |
Fan-out wrapper that forwards events to multiple reporters |
Quick start
Compose several reporters with CompositeReporter and hand it to the loop:
use ;
// Build a composite reporter that fans out to all four reporters.
let reporter = new
.with_observer
.with_observer
.with_observer
.with_observer;
// Pass `reporter` as the observer when constructing the agent loop.
Accessing outputs after the loop
Reporters that accumulate state (UsageReporter, TranscriptReporter,
JsonlReporter) expose accessors for reading back data once the loop
finishes:
use ;
// Usage totals
let reporter = new;
// ...run the loop...
let summary = reporter.summary;
println!;
// Transcript items
let reporter = new;
// ...run the loop...
for item in &reporter.transcript.items
// JSONL buffer
let mut reporter = new;
// ...run the loop...
let jsonl = Stringfrom_utf8.unwrap;
let errors = reporter.take_errors;
assert!;
Writing to a file
JsonlReporter and StdoutReporter accept any std::io::Write
implementation, so you can point them at files, network sockets, or
in-memory buffers:
use JsonlReporter;
use BufWriter;
use File;
let file = create.expect;
let reporter = new;
Adapter reporters
For expensive or async reporting, wrap an inner reporter in one of the provided adapters:
| Adapter | Purpose |
|---|---|
BufferedReporter |
Enqueues events and flushes in batches |
ChannelReporter |
Forwards events to another thread via mpsc::Sender |
TracingReporter |
Emits tracing events (requires tracing feature) |
use ;
// Flush to the JSONL writer every 128 events instead of one-at-a-time.
let reporter = new;
use ChannelReporter;
let = pair;
spawn;
// Pass `reporter` to the agent loop.
TracingReporter
TracingReporter bridges agent events into the tracing ecosystem. It
is gated behind the tracing feature to keep the dependency opt-in:
= { = "0.2.2", = ["tracing"] }
use TracingReporter;
let reporter = new;
Events are emitted under the "agentkit" target at levels that match
their severity (INFO for lifecycle, DEBUG for usage/compaction, TRACE for
content deltas, WARN/ERROR for problems).
Failure policy
Reporter failures are non-fatal by default. For reporters that can fail
(I/O, channel sends), implement FallibleObserver and wrap it in a
PolicyReporter to choose how errors are handled:
| Policy | Behaviour |
|---|---|
Ignore |
Silently discard errors (default) |
Log |
Print errors to stderr |
Accumulate |
Collect errors for later inspection |
FailFast |
Panic on first error |
use ;
let = pair;
let reporter = new;
Error handling
JsonlReporter and StdoutReporter never panic on write failures.
Errors are collected internally and can be drained after the loop with
take_errors(). This keeps the LoopObserver::handle_event signature
infallible while still giving you full visibility into any I/O issues.