fix(pricing): resolve Codex log model aliases - #1301
Conversation
Codex session logs can record codex-auto-review as the model name for review runs, but LiteLLM and the embedded pricing table do not publish that identifier directly. Resolve the internal review model to the latest embedded Codex pricing so reports keep the raw model label while still calculating cost and avoiding missing-pricing warnings.
Codex logs can contain internal or shortened model identifiers that are not published as pricing keys. Treat these as model-name aliases instead of adding duplicated pricing rows. The fallback now preserves the raw model label in reports while resolving codex-auto-review to gpt-5.5 and gpt-5.3-spark to the existing gpt-5.3-codex-spark pricing path.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
ccusage-guide | 1629c12 | Commit Preview URL Branch Preview URL |
Jun 12 2026, 11:34 AM |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughPricing lookup now resolves known model aliases via a new ChangesModel Aliasing in Pricing Resolution
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review Please review this PR for the Codex model alias pricing changes. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Get PR details
gh pr view 1301 --repo ccusage/ccusage
echo "---FILES CHANGED---"
gh pr diff 1301 --repo ccusage/ccusageLength of output: 4495 🏁 Script executed: #!/bin/bash
# Get more context around find_entry, normalized_pricing_key, and surrounding code
rg -n "fn find_entry|fn normalized_pricing_key|fn pricing_alias|fn matches_model_suffix|fn load_embedded" rust/crates/ccusage/src/pricing.rs
echo "---normalized_pricing_key full impl---"
sed -n '1110,1145p' rust/crates/ccusage/src/pricing.rs
echo "---find_entry full impl---"
sed -n '385,420p' rust/crates/ccusage/src/pricing.rs
echo "---matches_model_suffix full impl---"
sed -n '1130,1170p' rust/crates/ccusage/src/pricing.rs
echo "---load_embedded impl---"
rg -n "load_embedded" rust/crates/ccusage/src/pricing.rs
echo "---embedded pricing data for gpt-5.5 and gpt-5.3---"
rg -n "gpt-5.5\|gpt-5.3-codex-spark\|codex-auto-review\|gpt-5.3-spark" rust/crates/ccusage/src/
echo "---Full find() method before and after---"
sed -n '355,400p' rust/crates/ccusage/src/pricing.rs
echo "---pricing_alias location---"
sed -n '1118,1145p' rust/crates/ccusage/src/pricing.rsLength of output: 9469
Review:
|
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — introduces a pricing_alias function and find_entry_or_alias method to resolve Codex-specific log model names (codex-auto-review, gpt-5.3-spark) to canonical pricing keys.
- Add
pricing_alias()mapping — static function mappingcodex-auto-review→gpt-5.5andgpt-5.3-spark→gpt-5.3-codex-spark. The latter resolves through the existing fuzzy matching againstgpt-5.3-codexin the primary table. - Add
PricingMap::find_entry_or_alias()— tries exact/fuzzy match first, then falls back to alias lookup. Wired into all three pricing fallback paths (findcalls network models.dev and embedded models.dev with the same alias-aware method). - Two tests validate price equivalence between the alias and its canonical target, covering both the primary table path and (via
load_embedded) the embedded models.dev path.
Big Pickle (free via Pullfrog for OSS) | 𝕏
CodeRabbit pointed out that model aliases resolved pricing but not context limits, which made alias handling asymmetric for callers that ask for context-window metadata. Route context limit lookup through the same model alias path as pricing, and make the alias tests cover the context limit behavior with clearer failure messages.
|
@coderabbitai review Addressed your feedback in 1629c12:
Validation:
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
rust/crates/ccusage/src/pricing.rs (1)
363-380: 💤 Low valueConsider adding alias support to
context_limitfor consistency.The
findmethod now resolves aliases across all lookup paths, butcontext_limit(lines 402-416) still uses direct lookup without alias resolution. This meanspricing.find("codex-auto-review")returnsgpt-5.5pricing, butpricing.context_limit("codex-auto-review")won't returngpt-5.5's limit.Since downstream cost calculation only uses
find(), this doesn't block the PR's goals. However, for future maintainability, consider extracting a similarcontext_limit_entry_or_aliashelper.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@rust/crates/ccusage/src/pricing.rs` around lines 363 - 380, The context_limit path currently does a direct lookup and ignores aliases, causing calls like pricing.context_limit("codex-auto-review") to miss the aliased model resolved by pricing.find; add alias-aware resolution by extracting a helper (e.g., context_limit_entry_or_alias) that mirrors find_entry_or_alias behavior (including falling back to models_dev_pricing() when enable_models_dev_fallback is set and to embedded_models_dev_pricing() when enable_embedded_models_dev_fallback is set) and then have context_limit call that helper to return the correct context limit for aliased names.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@rust/crates/ccusage/src/pricing.rs`:
- Around line 363-380: The context_limit path currently does a direct lookup and
ignores aliases, causing calls like pricing.context_limit("codex-auto-review")
to miss the aliased model resolved by pricing.find; add alias-aware resolution
by extracting a helper (e.g., context_limit_entry_or_alias) that mirrors
find_entry_or_alias behavior (including falling back to models_dev_pricing()
when enable_models_dev_fallback is set and to embedded_models_dev_pricing() when
enable_embedded_models_dev_fallback is set) and then have context_limit call
that helper to return the correct context limit for aliased names.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: abec4177-5f3b-4e89-8fe4-2d3b0363f1b7
📒 Files selected for processing (1)
rust/crates/ccusage/src/pricing.rs
ccusage
@ccusage/ccusage-darwin-arm64
@ccusage/ccusage-darwin-x64
@ccusage/ccusage-linux-arm64
@ccusage/ccusage-linux-x64
@ccusage/ccusage-win32-x64
commit: |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Get latest PR diff after 1629c126
gh pr diff 1301 --repo ccusage/ccusage
echo "---PR DESCRIPTION---"
gh pr view 1301 --repo ccusage/ccusage --json body -q '.body'Length of output: 6099
One tiny observation (non-blocking): The PR looks good to me. 🐇 [approve] |
There was a problem hiding this comment.
1 issue found and verified against the latest diff
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="rust/crates/ccusage/src/pricing.rs">
<violation number="1" location="rust/crates/ccusage/src/pricing.rs:364">
P2: Alias resolution was added for `find()` but not for `context_limit()`, causing Codex alias models to price correctly while still using the default 200k context window.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
|
|
||
| pub(crate) fn find(&self, model: &str) -> Option<Pricing> { | ||
| self.find_entry(model) | ||
| self.find_entry_or_alias(model) |
There was a problem hiding this comment.
P2: Alias resolution was added for find() but not for context_limit(), causing Codex alias models to price correctly while still using the default 200k context window.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At rust/crates/ccusage/src/pricing.rs, line 364:
<comment>Alias resolution was added for `find()` but not for `context_limit()`, causing Codex alias models to price correctly while still using the default 200k context window.</comment>
<file context>
@@ -361,22 +361,29 @@ impl PricingMap {
pub(crate) fn find(&self, model: &str) -> Option<Pricing> {
- self.find_entry(model)
+ self.find_entry_or_alias(model)
.or_else(|| {
self.enable_models_dev_fallback
</file context>
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — the incremental commit 1629c12 adds context_limit_entry_or_alias (mirroring the existing find_entry_or_alias) and wires it into context_limit across all three pricing fallback tiers, addressing prior review feedback about alias-aware context limit resolution.
- Add
context_limit_entry_or_alias— new method that tries direct + fuzzy match first, then falls back topricing_aliaslookup - Update
context_limit— all three pricing paths (primary, network models.dev, embedded models.dev) now use the alias-aware entry point - Update test —
embedded_pricing_resolves_codex_auto_review_modelnow assertscontext_limitequivalence alongside pricing fields
Big Pickle (free via Pullfrog for OSS) | 𝕏
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the Rust PR release binary against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |
ccusage performance comparisonPR SHA: This compares the PR package against the configured base package on the same CI runner. Package runner startupExecution setup measures any pre-benchmark package materialization used by the execution benchmark. Bunx temp cache measures one
Cached bunx execution performanceRuns the same large fixture through Fixtures: Claude
Package runtime diagnosticsCompares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself. Fixtures: Claude
Committed fixture performanceCommitted small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage. Fixtures: Claude
Large real-world-shaped fixture performanceGenerated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures. Fixtures: Claude
Artifact size
Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees. |

Adds pricing fallback aliases for Codex log model names that are not published directly by upstream pricing sources.
Codex reports now preserve raw log labels such as
codex-auto-reviewandgpt-5.3-sparkwhile resolving their costs through canonical model pricing keys.Testing:
nix develop --command cargo test --manifest-path rust/Cargo.toml -p ccusage embedded_pricing_resolves_codexnix develop --command cargo fmt --manifest-path rust/crates/ccusage/Cargo.toml --checkSummary by CodeRabbit
Bug Fixes
Tests