Skip to content

Surface Codex reasoning tokens and rate limits in Anthropic usage - #149

Open
sommaht wants to merge 1 commit into
raine:mainfrom
sommaht:usage-visibility
Open

Surface Codex reasoning tokens and rate limits in Anthropic usage#149
sommaht wants to merge 1 commit into
raine:mainfrom
sommaht:usage-visibility

Conversation

@sommaht

@sommaht sommaht commented Sep 11, 2026

Copy link
Copy Markdown

Summary

Two small additions to the Codex → Anthropic usage mapping so clients can account for what a Codex turn actually cost.

  • Reasoning tokens. parse_codex_usage already reads output_tokens_details.reasoning_tokens into CodexUsage, but map_codex_usage_to_anthropic dropped it. It is now emitted as output_tokens_details.{reasoning_tokens, thinking_tokens}. The second name is what Claude Code records for Anthropic models, so per-turn accounting in its transcripts becomes comparable across providers (verified: Claude Code keeps thinking_tokens in the transcript usage block; before this it was always 0 for Codex models).
  • Rate limits. The codex.rate_limits stream event was only converted into a progress ping. Codex sends it before any usage exists, so both translators (buffered reducer and live-stream) keep the latest snapshot and attach it to the CodexUsage built from response.completed. The mapper emits it as a typed codex_rate_limits field (plan_type, limit_reached, primary/secondary used_percent, window_minutes, reset_at) on the terminal message_delta usage. Downstream proxies can log the subscription meter per response; Claude Code itself ignores the unknown key.

Example terminal usage after the change:

{"input_tokens":23,"output_tokens":24,"cache_read_input_tokens":0,"cache_creation_input_tokens":0,
 "output_tokens_details":{"reasoning_tokens":17,"thinking_tokens":17},
 "codex_rate_limits":{"plan_type":"prolite","limit_reached":false,
   "primary":{"used_percent":8.0,"window_minutes":10080,"reset_at":1789765755}}}

Test plan

  • cargo test --release: all suites pass; adds a mapper test for reasoning + rate limits, extends the reducer and live-stream codex.rate_limits tests to assert the snapshot reaches the finish usage.
  • cargo fmt --check clean.
  • Manual: streamed /v1/messages against gpt-5.6-terra at xhigh effort reports 390 reasoning of 566 output tokens; a request through Claude Code shows thinking_tokens populated in the session transcript.

🤖 Generated with Claude Code

The Codex translators already parse output_tokens_details.reasoning_tokens
into CodexUsage but dropped it when mapping to the Anthropic usage block,
so clients saw output_tokens with no reasoning breakdown. Emit it as
output_tokens_details.{reasoning_tokens,thinking_tokens}; the second name
matches what Claude Code records for Anthropic models so per-turn
accounting stays comparable across providers.

The codex.rate_limits stream event was only turned into a progress ping.
Codex sends it before any usage exists, so both translators (the buffered
reducer and the live-stream translator) now keep the latest snapshot and
attach it to the CodexUsage they build from response.completed. The
mapper turns it into a typed codex_rate_limits field (plan, limit_reached,
primary/secondary used_percent, window, reset) on the terminal
message_delta usage, so a client or proxy can observe the subscription
meter per response. Both paths get it through the one mapper.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant