yoagent 0.15.0

Simple, effective agent loop with tool execution and event streaming
Documentation
# Telemetry

yoagent instruments the loop with [`tracing`](https://docs.rs/tracing) **spans**
— structured, timed, nested units your observability stack can consume. With
no subscriber installed the overhead is near-zero (a cached per-callsite
interest check); nothing is exported unless you opt in.

## The span tree

```
agent_loop                (model)
└─ llm_stream             (turn, model, tokens_in, tokens_out, tokens_cached, cost_usd, error)
└─ tool                   (tool, tool_call_id, is_error)
```

- `llm_stream` — one per turn, wrapping the provider call. Token counts are
  recorded from real usage; `cost_usd` is recorded when the `ModelConfig` has
  pricing configured (`CostConfig`).
- `tool` — one per tool execution, with the tool name and error status;
  duration comes free with the span.

## Local: print spans

```rust
tracing_subscriber::fmt()
    .with_span_events(tracing_subscriber::fmt::format::FmtSpan::CLOSE)
    .init();
```

Run `cargo run --example telemetry` to see it.

## Production: OpenTelemetry

The OTel bridge is **application-side** — yoagent needs no OTel dependency
(that's the point of `tracing`). Install the
[`tracing-opentelemetry`](https://docs.rs/tracing-opentelemetry) layer and the
same spans flow to any OTLP backend — Datadog, Grafana Tempo, Honeycomb,
Jaeger:

```rust
// opentelemetry_otlp 0.27+, opentelemetry_sdk 0.27+, tracing-opentelemetry 0.28+
use opentelemetry::trace::TracerProvider as _;
use tracing_subscriber::layer::SubscriberExt;

let exporter = opentelemetry_otlp::SpanExporter::builder()
    .with_tonic()
    .build()?;
let provider = opentelemetry_sdk::trace::SdkTracerProvider::builder()
    .with_batch_exporter(exporter)
    .build();

let subscriber = tracing_subscriber::registry()
    .with(tracing_opentelemetry::layer().with_tracer(provider.tracer("yoagent-app")));
tracing::subscriber::set_global_default(subscriber)?;
```

(The OTel crates rework their builder APIs between releases — if this snippet
drifts, the authoritative wiring is the
[`tracing-opentelemetry` docs](https://docs.rs/tracing-opentelemetry); yoagent
only emits standard `tracing` spans and does not depend on OTel.)

Because these are ordinary `tracing` spans, an agent call nests inside your
app's existing request traces (e.g. an axum handler span) automatically.

## What it buys you

- **Cost attribution** — dollars per turn/model in your dashboards, from the
  same `CostConfig` data as [`session_cost_usd`]../reference/api.md.
- **Latency diagnosis** — "40s request: 8s provider, 30s in one bash tool."
- **Audit** — which tools ran, with what outcome, per session.