Skip to content

fix(usage): price a model newer than the table from its nearest known version - #309

Merged
maxthomas95 merged 3 commits into
mainfrom
fix/pricing-fallback-20261109
Nov 10, 2026
Merged

maxthomas95 merged 3 commits into
mainfrom
fix/pricing-fallback-20261109

Conversation

@maxthomas95

Copy link
Copy Markdown
Owner

Summary

Review item 5.5 (docs/REVIEW_2026-11-09.md).

getModelPricing went from the LiteLLM table to a static prefix list (opus, sonnet, haiku) and then to DEFAULT_PRICING at 3 / 15 USD per million tokens. A model released after the table was last refreshed was costed at Sonnet-class rates with only a log line. claude-fable-5-2 was the live case: the table lists claude-fable-5 and claude-fable-5-1 at 10 / 50, so its cost and any budget alert were under-counted by more than three times.

  • Nearest sibling. Between the exact lookup and the prefix list, an unlisted model is priced from the newest listed version of the same family. The family is found by dropping trailing segments one at a time, never below two, so claude-fable-5-2 can borrow from claude-fable-5-1 and never from another family. A release date never makes an older version look newer. A dated or suffixed id for a listed model resolves to that model. Only bare keys are considered, so a provider's markup is never borrowed.
  • Synthetic records. Claude Code's zero-token <synthetic> records, and an empty id, are priced at zero and no longer log "Unknown model" on every run.
  • Source. getModelPricingSource reports table, sibling, prefix, default or none, so a later change can label approximate prices. It is not wired into any UI here.
  • Docs. usage-quota.md says new models can be approximate until the table refreshes.

No price numbers are added or changed.

Test plan

  • npx tsc --noEmit
  • npx eslint on the module and its test
  • npx vitest run src/main/usage (new model-pricing.test.ts, 10 cases)
  • Resolved real ids against this machine's cached table: claude-fable-5-2 is priced at 10 / 50 via claude-fable-5-1; listed models are unchanged
  • Manual: after a Fable 5.2 session, the usage footer and history show a cost in line with 10 / 50 rather than 3 / 15

Out of scope

  • Showing "estimated" in the usage UI and exports for sibling and default prices.
  • Ids whose version sits in the second segment (gpt-5.7-terra): there is no two-segment family to match, so they still use the default.
  • Re-pricing usage already recorded at the old rate.

🤖 Generated with Claude Code

maxthomas95 and others added 3 commits November 9, 2026 20:45
… version

getModelPricing fell from the LiteLLM table straight to a static prefix
list (opus, sonnet, haiku) and then to DEFAULT_PRICING at 3 / 15 USD per
million tokens. A model released after the table was last refreshed was
therefore costed at Sonnet-class rates with only a log line. Real case:
claude-fable-5-2 was missing while claude-fable-5 and -5-1 were listed
at 10 / 50, so its cost and any budget alert were under-counted by more
than three times.

- Add a nearest-sibling step between the exact lookup and the prefix
  list. The family is found by dropping trailing segments one at a time,
  never below two, and the newest listed version in that family wins. A
  release date never makes an older version look newer, a dated or
  suffixed id for a listed model resolves to that model, and only bare
  keys are considered so a provider's markup is never borrowed.
- Price Claude Code's zero-token <synthetic> records (and an empty id)
  at zero without logging "Unknown model" on every run.
- Export getModelPricingSource so a later change can label approximate
  prices. Not wired into any UI here.

No price numbers are added or changed.

Tests: new model-pricing.test.ts, 10 cases, loading fixture tables
through loadPrices. Checked against this machine's cached table:
claude-fable-5-2 now resolves to 10 / 50 via claude-fable-5-1.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The sibling price lookup logs at info level; this mock only had warn, so a model resolved through a sibling threw inside the test.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@maxthomas95
maxthomas95 merged commit d1bd87c into main Nov 10, 2026
10 checks passed
@maxthomas95
maxthomas95 deleted the fix/pricing-fallback-20261109 branch November 10, 2026 02:58
@sonarqubecloud

Copy link
Copy Markdown

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