feat: capture the token usage Providers already report (0.15.0) - #16
Merged
Merged
Conversation
Stage 11 made "can this agent do the job" answerable, but the report had no cost in it: pass rate, turns, wall time. A prompt change that lifts the pass rate from 70% to 75% while tripling the tokens is usually a bad trade, and it looked like a pure win. Providers return usage on every call and chivgent was throwing it away. Usage now flows from the Provider response to the run: per turn on message_end, per run on agent_end and the run result, per attempt in the eval report, and cumulatively behind /session. Compaction's own summarising call counts too, because it trades a call now against smaller inputs later and that trade cannot be judged with half of it hidden. Tokens only, never money. Converting to a currency needs a model-to-price table, and that table goes stale silently when a Provider changes its rates, producing a figure that looks precise and is wrong. That is worse than no figure, because nobody questions a number with a decimal point in it. A missing figure stays missing: usage is undefined rather than zero when a Provider reports nothing, and a total that contains such a call is flagged incomplete. Streamed Chat Completions only report usage when asked, so stream_options.include_usage is sent; an endpoint predating that field may reject it, and --no-stream is the documented fallback. Running it end to end found a bug the unit tests could not: every turn added the context manager's usage, which is undefined when no compaction was needed, so every real CLI run was flagged incomplete. Not spending anything and not reporting anything are different, and only the second is a gap. The test that would have caught it — a context manager present but never triggered — is now there. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFMvrN7qqBmVMNX26XtRDy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stage 12. Stage 11 made "can this agent do the job" answerable, but the report had no cost in it — pass rate, turns, wall time. A prompt change that lifts the pass rate from 70% to 75% while tripling the tokens is usually a bad trade, and it looked like a pure win. Providers return
usageon every call and chivgent was throwing it away.What it does
Usage flows from the Provider response through to the run: per turn on
message_end, per run onagent_endand the run result, per attempt in the eval report, and cumulatively behind/session.Compaction's own summarising call counts too: it trades a call now against smaller inputs later, and that trade cannot be judged with half of it hidden.
Tokens only, never money
Converting to a currency needs a model-to-price table, and that table goes stale silently when a Provider changes its rates — producing a figure that looks precise and is wrong. That is worse than no figure, because nobody questions a number with a decimal point in it. Token counts are what the Provider itself reported and do not expire.
A missing figure stays missing
usageisundefinedrather than zero when a Provider reports nothing, and a total containing such a call is flagged incomplete. Zeroes would be indistinguishable from a genuinely free call and would quietly understate every total containing them.Compatibility note
Streamed Chat Completions only report usage when asked, so
stream_options: { include_usage: true }is now sent. A self-hosted OpenAI-compatible endpoint predating that field may reject the request;--no-streamis the documented fallback. This is the only change here that can affect an existing user.A bug only running it could find
Every turn added the context manager's usage, which is
undefinedwhen no compaction was needed — so every real CLI run was flagged incomplete, since the CLI always has a context manager. The unit test assertingcomplete: trueused an agent with no context manager, so it never reached that line. Caught by watchingagent_end.usage.completein a live end-to-end run. Not spending anything and not reporting anything are different, and only the second is a gap; the test that would have caught it is now there.Verification
npm run release:checkpasses: type-check, 379 tests, build,npm pack --dry-run.cachedInputTokens, into the eval table and the JSON report.🤖 Generated with Claude Code
https://claude.ai/code/session_01FFMvrN7qqBmVMNX26XtRDy
Generated by Claude Code