Conversation
Claude stream metering treated missing usage fields and explicit zeros the same (gjson Int() → 0), then MergeStreamUsageDetail kept prior positives. A final message_delta with input_tokens:0 after a positive message_start therefore under-counted cache hits. Parse Claude usage with field presence (Exists && Type != Null) and merge only present fields so explicit zeros overwrite while omitted/null keep prior values. Leave OpenAI MergeStreamUsageDetail keep-prior-on-zero unchanged.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
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.
Problem
Claude stream usage is accumulated across
message_startand latermessage_deltaevents. Parsing usedgjson.Int(), which maps both a missing field and an explicit0to zero. The shared stream merge then kept any prior positive value whenever the update was0.A full cache hit therefore billed incorrectly:
message_startcan report positiveinput_tokens/ cache-creation, then the finalmessage_deltareportsinput_tokens: 0(and oftencache_creation_input_tokens: 0) with the realcache_read_input_tokensandoutput_tokens. The start input was kept, so uncached input and cache-hit rate were wrong.Omitted-only deltas such as
{"output_tokens": 15}must still preserve start input and cache fields.Fix
Claude metering now tracks field presence (
Exists() && Type != Null) and merges on that basis:0→ overwritenull→ keep priorThis is scoped to the Claude executor/plugin observe path (
ParseClaudeStreamUsage/parseClaudeUsageNode/ObserveClaudeStream/parseClaudeStreamLine).MergeStreamUsageDetailis unchanged for OpenAI and other protocols that still keep prior values on zero.Tests
message_deltawith explicit zeros → final detail hasinput=0, reported cache read, reported outputinput_tokenspreserves startinput_tokens: nullpreserves startinput_tokensreplaces start