# Token, cost and model metrics for ClaudeAgent and CodexAgent runs

> Agno now fills `RunOutput.metrics`, `model` and `model_provider` on every `ClaudeAgent` and `CodexAgent` run, so their usage shows up in AgentOS sessions and on the `/metrics` page.

- Published: 2026-10-12
- Author: Kaustubh Shukla
- Categories: Changelog
- Canonical: https://www.agno.com/blog/token-cost-and-model-metrics-for-claudeagent-and-codexagent-runs
- Markdown: https://www.agno.com/blog/token-cost-and-model-metrics-for-claudeagent-and-codexagent-runs.md

Agno's `ClaudeAgent` maps the Claude SDK's result message onto `RunOutput.metrics`, with input, output and cache tokens, the cost in USD, and one entry per model in `metrics.details["model"]`, where Claude Code's helper model gets its own line and cost. `CodexAgent` takes the growth of the thread's token total over the turn, so a turn with two tool calls counts all three model requests. Agno times both, setting `duration` and, for streamed runs, `time_to_first_token`.

Completed runs add up into the session's `session_metrics`. AgentOS shows those totals in the sessions list, the session view and the daily `/metrics` aggregation.

Runs also carry `model` and `model_provider`, which the Models Runs card on the AgentOS metrics page counts. With no model on the agent or in its options, `ClaudeAgent` now runs `claude-sonnet-4-6` and `CodexAgent` runs `gpt-5.6-luna`, and the run records what the SDK was asked to run. Earlier releases left an unset model to the CLI, so set `model` yourself if you relied on the CLI's default. A model in `options` (Claude) or `thread_options` and `turn_options` (Codex) overrides that default.

![Before and after, real output from two CodexAgent runs through AgentOS with a fake Codex SDK standing in for the model. Before: run.model None, run.metrics None, GET /sessions/s1 total_tokens None, GET /metrics model_metrics empty. Now: run.model gpt-5.6-luna (OpenAI), run.metrics 49270 in, 164 out, 49434 total, GET /sessions/s1 total_tokens 98868, GET /metrics model_metrics gpt-5.6-luna, OpenAI, count 2.](https://www.agno.com/images/v3-1-3-external-agent-metrics.png)

On the Claude side, the fake SDK from the release's tests stands in for Claude Code and returns a fixed usage report:

```python
agent = ClaudeAgent(id="claude", db=db)  # no model set

run = list(agent.run("hi", session_id="s", stream=True, yield_run_output=True))[-1]
print(run.model, run.model_provider)
m = run.metrics
print(m.input_tokens, m.output_tokens, m.cache_read_tokens, m.cache_write_tokens, m.cost)
print([(x.id, x.cost) for x in m.details["model"]])
```

```text
claude-sonnet-4-6 Anthropic
3 5 14334 5369 0.0365982
[('claude-sonnet-4-6', 0.0365982)]
```

Claude's `input_tokens` leaves out the cached prefix, as the native Anthropic model does, while Codex's includes it, as the OpenAI API does. Codex reports no cost, so `cost` stays unset on `CodexAgent` runs.

See the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/frameworks/claude-agent-sdk/metrics_agentos.py) and its [Codex counterpart](https://github.com/agno-agi/agno/blob/main/cookbook/frameworks/codex/codex_metrics_agentos.py), and learn more about [provider metrics](https://docs.agno.com/agent-os/multi-framework/observability#provider-metrics) in the documentation.
