Repository navigation
feat(usage): price GPT-6 Astra token usage - #22006
Alfred212121 wants to merge 1 commit into
Conversation
|
Understand this PR’s impact Explore downstream dependencies and potential security impact with Blast Radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: 📥 CommitsReviewing files that changed from the base of the PR and between 4aaa6c7 and e535ec10be4f2fbb7d1169cb119dea86429c1d26. 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe pricing table now includes GPT-6 Astra rates and long-context tiers. Model normalization maps Priority: ➖ Normal Severity of issue fixed: Medium 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
gpt-6-astra was missing from MODEL_PRICING, so normalizeModelForPricing returned null and estimateCostUsd dropped every event on that model from the total. Stats & Usage showed ~$0 for hundreds of millions of tokens with no unpriced indicator, since hasInferredPricing only covers a missing model name, not a missing table entry. Rates are the published ones: $10 input / $1 cached input / $50 output per 1M, with the >272K long-context tier at 2x input and cache and 1.5x output, which the existing tier fields already express. Fixes stablyai#22005 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
e535ec1 to
515aa3b
Compare
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Reviewed the full 2-file diff at e535ec1 (e535ec10be).
gpt-6-astrapricing entry — adds the model toMODEL_PRICINGat $10 input / $1 cached / $50 output per 1M, with 2x / 2x / 1.5x long-context tiers at the existingLONG_CONTEXT_THRESHOLD_TOKENS(272K), matching the rates cited in #22005.normalizeModelForPricingbranch — resolvesgpt-6-astraandgpt-6-astra-*so reasoning suffixes (-high) and snapshot IDs (-2026-09-01) price at Astra rates. It shadows no existing branch and is not shadowed by the baregpt-5.6exact match.- Two new tests — pin the tiered total (
$87.208for 2M / 1M / 1M) and suffix/snapshot normalization ($1.80); each fails without the new entry, so they are real coverage rather than theatre.
ℹ️ The "after" cost in the PR description looks like it omits the long-context tier
The $1,195.61 figure is exactly the published base rates applied to every token (24,838,404 × $10 + 802,453,760 × $1 + 2,895,411 × $50). But estimateCostUsd applies inputTiers / cachedInputTiers / outputTiers to each daily aggregate row (day::model::projectKey), not per request, so any row whose bucket exceeds 272K is repriced at 2x / 2x / 1.5x. With ~802M cached tokens that tier is likely to fire on most rows, which would put the card nearer $2.3K than the $1.2K shown. Worth confirming against the running app so the PR's before/after reflects what ships.
Technical details
# Long-context tiers apply per daily aggregate row, not per request
## Affected sites
- `src/main/codex-usage/codex-usage-cost-estimate.ts:4` — `calculateTieredCost` charges the base rate up to the threshold and the tier rate only above it (marginal).
- `src/main/codex-usage/codex-usage-rollup-projections.ts:49` — `buildSummary` calls `estimateCostUsd` once per `filteredDaily` row.
- `src/main/usage/usage-rollup-records.ts:105` — the row key is `day::model::projectKey`.
- `src/main/codex-usage/codex-model-pricing.ts:81` — the new Astra entry wires 272K tiers to 20 / 2 / 75.
## Required outcome
- Confirm the figure in the PR description against the actual rendered card. If the rows are large, the description should state the higher number (or explain the tier). No code change is necessarily required — the entry follows the existing convention.
## Open questions for the human
- Is aggregate-level (rather than per-request) tiering the intended model here? That is pre-existing behavior shared by every model in the table, so it is not a defect this PR introduces.DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
The head moved from e535ec1 to 515aa3b (same commit subject, force-pushed), but the diff is byte-identical to the version reviewed in my prior review — no new code or test content. No new findings; the prior review stands.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
|
Good catch — you were right, and my "after" figure was wrong. I re-ran it against the real daily aggregate rows through
84.5% higher, close to your ~$2.3K estimate. With ~802M cached input tokens spread over the rows, most of them clear the 272K threshold and get repriced. I've corrected the PR description. A second error in the same section, which you didn't flag but which follows from yours: I had quoted No code change from either: the entry follows the same tier convention as every other model in the table, and both tests still pass. On your open question
I don't think it is, and I'd like to flag it for a maintainer as a separate issue rather than fold it into this PR. OpenAI's rule is per request — "prompts with more than 272K input tokens are priced at 2x input and cache rates and 1.5x output for the full request". A daily aggregate row is a sum over many requests, so a day of small requests that happens to total more than 272K gets billed as if it were one oversized prompt. That systematically overestimates, and it affects every tiered entry already in the table ( Fixing it properly needs per-event or per-request token counts to survive into the rollup, which is a real change to the aggregation shape — well outside a pricing-table addition. As you say, it is pre-existing behavior this PR doesn't introduce, so I've followed the existing convention here and kept the scope tight. Happy to open a separate issue for it if that's useful. |

ELI5
Orca's Stats & Usage page works out what your Codex sessions cost by looking each model up in a price list. GPT-6 Astra was never added to that list, so Orca quietly counted it as free. On my own data that hid roughly $2,200 of Codex usage behind a near-zero number. This adds Astra to the list.
What Changed
Before: any Codex session run on
gpt-6-astracontributed $0 to the estimated cost in Settings → Stats & Usage — on the Usage Overview tile, the Codex provider card, and the per-model and per-project breakdowns. There was no "inferred pricing" note either, so the figure looked authoritative while being off by orders of magnitude.After: those sessions are priced at the published Astra rates and the totals reflect real spend.
Mechanism:
MODEL_PRICINGinsrc/main/codex-usage/codex-model-pricing.tsstopped atgpt-5.6-luna, andnormalizeModelForPricing()had no branch for Astra, so it fell through toreturn null.estimateCostUsd()returnsnullon a null normalization, and the aggregation treats that as "no cost" rather than "unknown cost". ThehasInferredPricingflag doesn't catch this: it is set when the rollout has no model name at all, not when a named model is missing from the table.Two additions:
gpt-6-astraentry at $10 input / $1 cached input / $50 output per 1M, withinputTiers/cachedInputTiers/outputTiersat $20 / $2 / $75 aboveLONG_CONTEXT_THRESHOLD_TOKENS;gpt-6-astraandgpt-6-astra-*, placed before the baregpt-5.6alias check so it can't be shadowed, and after the 5.6 tier IDs so it doesn't shadow them.Why
The rates are what OpenAI publishes for the model (docs): $10 / $1 / $50 per 1M, and "prompts with more than 272K input tokens are priced at 2x input and cache rates and 1.5x output for the full request". That long-context rule is exactly what the existing
TieredPricefields already express, and 272K is alreadyLONG_CONTEXT_THRESHOLD_TOKENS, so no new machinery is needed — this follows the same shape as #10822, which added the GPT-5.6 family.The alternative would be to make an unpriced-but-named model surface as
hasInferredPricingso the UI says "inferred pricing" instead of showing a wrong number. That's arguably worth doing as a general safety net for the next model launch, but it's a separate behavioral change and doesn't help anyone running Astra today. I kept this PR to the data gap.One thing I deliberately left out:
codex-auto-reviewalso appears as its own model key in rollouts (200M tokens and ~$434 of unpriced usage in my data) and is likewise absent from the table. I don't know what it actually bills as, so I didn't guess. Happy to add it in a follow-up if a maintainer can confirm.Linked Issue
Fixes #22005
Visual Proof
No layout or interaction change — the same cost strings render, with correct numbers.
Before/after on my own
orca-codex-usage.json, both sides computed over the identical set of daily aggregate rows so the comparison is like-for-like:$2.04$2,207.51The
gpt-6-astratoken totals behind that: 24,838,404 uncached input + 802,453,760 cached input + 2,895,411 output.Two notes on the numbers, since an earlier revision of this description got them wrong:
buildSummary()callsestimateCostUsd()once perday::model::projectKeyrow, so the 272K tiers fire on most rows and the real total is ~84% higher. Thanks to the review bot for catching that.$0.47as the "before". That is what the provider card renders under its own default scope/range filter, not the all-rows total, so pairing it with an all-rows "after" was apples-to-oranges. Both numbers above are all-rows.No screenshots: the surrounding panel lists my private project and worktree names.
Testing
Added two cases to
src/main/codex-usage/store-model-pricing.test.ts, following the existing GPT-5.6 ones:prices GPT-6 Astra with current OpenAI rates— 2M input / 1M cached / 1M output crosses the 272K threshold and must come to $87.208;normalizes GPT-6 Astra reasoning suffixes and snapshot IDs before pricing—gpt-6-astra-highandgpt-6-astra-2026-09-01both price asgpt-6-astraat $1.80 under the threshold.I verified those two expected values, plus that the existing
gpt-5.6-sol/gpt-5.6-terra-high/ baregpt-5.6/gpt-5.6-lunaexpectations are unchanged and that an unknown model still returnsnull, by executingestimateCostUsd()directly against this diff. I was not able to run the fullpnpm test/pnpm tc/pnpm buildlocally — pulling and installing the whole workspace is impractical on my connection — so I'm relying on CI for those. The change is confined to one pure data table and one pure string function, with no platform-, SSH-, or mobile-specific behavior.Manual verification was done against the real
orca-codex-usage.jsonnumbers above rather than in a locally built app, for the same build reason.AI Disclosure
Written with Claude Opus 5 (Claude Code). The pricing figures were taken from OpenAI's published model docs and the arithmetic in the new tests was checked against the existing GPT-5.6 cases.
Review
Agent skill upstream boundary
docs/reference/agent-skill-sharing-upstream-boundary.mdand copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.Notes
No security, cross-platform, remote-SSH, mobile, or performance impact: one static object literal gains a key and one pure function gains an equality/prefix check. Backwards compatible — previously unpriced sessions start showing a cost, and no existing model's rate changes.
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)🤖 Generated with Claude Code