refactor: dedup identical opus-tier rates in modelPricing EXACT_RATES (#4163) - #4259
Merged
Conversation
…#4163) All five claude-opus-* rows carried the same [5.0, 25.0] literal, and the /opus/i FAMILY_RULES entry had to be re-pointed at the newest id on every opus bump (migration 206 and every bump before it) purely to relabel the reported rateModel — zero behavioral effect, two edit sites. The tier now owns one OPUS_TIER_RATES pair and a newest-first OPUS_MODEL_IDS list that generates its EXACT_RATES rows; the family rule takes its pointer from the head of that list. An opus bump is a one-line prepend. The pointer stays a real EXACT_RATES key rather than becoming inline rates on the family rule, because rateModel is load-bearing downstream: UsagePage prints "Priced as <rateModel>", and usageReconciler compares two ids' rateModel to decide whether a recorded and a transcript model are the same family (a null or synthetic label would make 'opus' and 'claude-opus-5' stop matching). A differential run of resolveModelRates and isFreeModelId over 954 provider/model pairs before and after returns byte-identical results.
…ghten the family-label assertion Sharing one OPUS_TIER_RATES array across all five keys meant a future edit to a single opus row would silently rewrite the whole tier; each row now owns its pair, matching the hand-written rows around it. The family-label test asserted only expect.any(String); it now shape-matches /^claude-opus-\d/ rather than hardcoding the current head id, which would have reintroduced the per-bump edit this change removes.
Owner
Author
Review log — antigravity (
|
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.
Summary
All five
claude-opus-*rows inEXACT_RATES(server/lib/modelPricing.js) carried the same hand-copied[5.0, 25.0]literal, and the{ test: /opus/i, rateModel: 'claude-opus-5' }entry inFAMILY_RULEShad to be re-pointed at the newest id on every opus bump — migration 206 and every bump before it — purely to relabel the reportedrateModel, since every opus row already resolved to the same numbers.The tier now owns one
OPUS_TIER_RATESpair plus a newest-firstOPUS_MODEL_IDSlist that generates itsEXACT_RATESrows, and the family rule takes its pointer from the head of that list. An opus bump is now a one-line prepend — no second edit site.Which fix shape, and why
The issue offered two shapes. I took shape 1 (shared constant, pointer derived rather than hand-written) instead of shape 2 (a family rule yielding
ratesinline), becauserateModelis load-bearing downstream and shape 2 could not preserve it:client/src/pages/UsagePage.jsxprintsPriced as ${m.rateModel}in the per-model tooltip.attributedModel()inserver/services/usageReconciler.jscompares two ids' resolvedrateModelto decide whether a recorded launch model and a transcript model are the same family, and deliberately treatsnullas "not recognized, therefore not a match".An inline-
ratesrule would have to reportrateModel: null(breaking that comparison outright) or a synthetic label likeclaude-opus(which would stop matching the exact-table label, soopusandclaude-opus-5would no longer reconcile as one model). Keeping the pointer a realEXACT_RATESkey avoids both while still retiring the per-bump edit — and it now cannot go stale or dangle, since it is derived from the list rather than typed.No pricing or behavior change. A differential run of
resolveModelRatesandisFreeModelIdover 954 provider/model pairs (every listed id, CLI shorthands, Bedrock-prefixed and suffixed variants, unlisted opus generations, localfamily:tagids, and the fallback paths) returns byte-identical results before and after. No client mirror of this module exists — it is server-only.Tests
server/lib/modelPricing.test.jsgains anopus tierblock pinning the three properties that made the hand-maintained pointer safe:matched: 'exact');claude-opus-9,global.anthropic.claude-opus-7-…-v1:0) still prices at $5/$25 without a pointer bump — the invariant this refactor exists to guarantee;usageReconcilerand the usage tooltip depend on.The existing
opusshorthand assertion now checks the rates rather than hardcodingclaude-opus-5, so the suite needs no edit at the next bump either; the new label test covers what that assertion used to.Test plan
cd server && NODE_ENV=test npx vitest run lib/modelPricing.test.js services/usageReconciler.test.js— 89 passed.cd server && NODE_ENV=test npm test— 29127 passed. Four files reported failures under this run, all pre-existing load flakes from concurrent suites (a different, non-overlapping set failed on a second run);services/loras.test.js,services/imageGenQuota.test.js,routes/settings.secretsStrip.test.js, androutes/imageGen.watermark.test.jsall pass in isolation (93 passed) and none touch pricing.resolveModelRates/isFreeModelIdacross 954 pairs: 0 mismatches.Closes #4163