fix(ccusage): avoid provider-specific Claude pricing fallback - #980
fix(ccusage): avoid provider-specific Claude pricing fallback#980ryoppippi wants to merge 1 commit into
Conversation
Restrict substring fallback for first-party Claude model names to first-party LiteLLM entries. This lets current direct LiteLLM flat pricing entries for Opus 4.6, Opus 4.7, and Sonnet 4.6 win without hardcoding their prices in ccusage. Provider-specific entries such as Bedrock or Vertex can still be matched by exact provider-prefixed names, but first-party Claude lookups no longer fall through to those entries just because their key contains the requested model name. Add regression coverage for preferring first-party Claude substring matches and returning no pricing when only a provider-specific substring match exists.
📝 WalkthroughWalkthroughThe PR refines model pricing lookup in ChangesClaude First-Party Model Pricing Filtering
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
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)
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 |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
ccusage-guide | f7c7f7f | May 11 2026, 09:49 PM |
@ccusage/amp
ccusage
@ccusage/codex
@ccusage/mcp
@ccusage/opencode
@ccusage/pi
commit: |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@packages/internal/src/pricing.ts`:
- Around line 501-539: Replace shorthand Claude model names in the two tests
with the repository's canonical Claude 4 names and exact LiteLLM pricing
entries: update the offlineLoader fixture keys (currently
'anthropic.claude-opus-4-6-v1' and 'claude-opus-4-6-20260205') to the matching
LiteLLM canonical names (e.g., use 'anthropic.claude-opus-4-20250514' / the
exact provider-prefixed key used in the repo) and change the getModelPricing
call argument from 'claude-opus-4-6' to the canonical model name (e.g.,
'claude-opus-4-20250514'), keeping the same assertions (expect
input_cost_per_token_above_200k_tokens to be undefined in the first test and
pricing toBeNull in the second). Ensure references are adjusted for
LiteLLMPricingFetcher and getModelPricing so the test names and fixtures exactly
match the repo’s Claude 4 naming rules.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3365d6c1-1613-4928-bcd5-4232d3548850
📒 Files selected for processing (1)
packages/internal/src/pricing.ts
| it('prefers first-party Claude substring matches over provider-specific entries', async () => { | ||
| using fetcher = new LiteLLMPricingFetcher({ | ||
| offline: true, | ||
| offlineLoader: async () => ({ | ||
| 'anthropic.claude-opus-4-6-v1': { | ||
| input_cost_per_token: 5e-6, | ||
| output_cost_per_token: 2.5e-5, | ||
| input_cost_per_token_above_200k_tokens: 1e-5, | ||
| output_cost_per_token_above_200k_tokens: 5e-5, | ||
| }, | ||
| 'claude-opus-4-6-20260205': { | ||
| input_cost_per_token: 5e-6, | ||
| output_cost_per_token: 2.5e-5, | ||
| }, | ||
| }), | ||
| }); | ||
|
|
||
| const pricing = await Result.unwrap(fetcher.getModelPricing('claude-opus-4-6')); | ||
|
|
||
| expect(pricing?.input_cost_per_token_above_200k_tokens).toBeUndefined(); | ||
| }); | ||
|
|
||
| it('does not use provider-specific substring matches for first-party Claude models', async () => { | ||
| using fetcher = new LiteLLMPricingFetcher({ | ||
| offline: true, | ||
| offlineLoader: async () => ({ | ||
| 'anthropic.claude-opus-4-6-v1': { | ||
| input_cost_per_token: 5e-6, | ||
| output_cost_per_token: 2.5e-5, | ||
| input_cost_per_token_above_200k_tokens: 1e-5, | ||
| output_cost_per_token_above_200k_tokens: 5e-5, | ||
| }, | ||
| }), | ||
| }); | ||
|
|
||
| const pricing = await Result.unwrap(fetcher.getModelPricing('claude-opus-4-6')); | ||
|
|
||
| expect(pricing).toBeNull(); | ||
| }); |
There was a problem hiding this comment.
Align new test model names with repository Claude naming rules.
These new tests use shorthand names (claude-opus-4-6) instead of the repo’s required current Claude 4 names and exact LiteLLM-style entries. Please switch fixtures/queries to the mandated canonical names while keeping the same matching assertions.
As per coding guidelines, “All test files must use current Claude 4 models (claude-sonnet-4-20250514, claude-opus-4-20250514), not outdated Claude 3 models” and “Model names in tests must exactly match LiteLLM's pricing database entries.”
🤖 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 `@packages/internal/src/pricing.ts` around lines 501 - 539, Replace shorthand
Claude model names in the two tests with the repository's canonical Claude 4
names and exact LiteLLM pricing entries: update the offlineLoader fixture keys
(currently 'anthropic.claude-opus-4-6-v1' and 'claude-opus-4-6-20260205') to the
matching LiteLLM canonical names (e.g., use 'anthropic.claude-opus-4-20250514' /
the exact provider-prefixed key used in the repo) and change the getModelPricing
call argument from 'claude-opus-4-6' to the canonical model name (e.g.,
'claude-opus-4-20250514'), keeping the same assertions (expect
input_cost_per_token_above_200k_tokens to be undefined in the first test and
pricing toBeNull in the second). Ensure references are adjusted for
LiteLLMPricingFetcher and getModelPricing so the test names and fixtures exactly
match the repo’s Claude 4 naming rules.
|
Closing this for now. Current LiteLLM pricing data already includes first-party flat entries for the affected Claude 1M-context models, so carrying extra matching logic in ccusage is not worth the added implementation surface. |
Summary
Context
This replaces #898 with a narrower fix. Current Anthropic docs and LiteLLM data show 1M flat pricing for Opus 4.7, Opus 4.6, and Sonnet 4.6, but not every 4.5 model is flat. In particular, LiteLLM still has above-200k tier fields for Sonnet 4.5.
Testing
Summary by CodeRabbit