feat(models): add Claude Opus 5 pricing - #223
Conversation
claude-opus-5 had no entry, so get_model_info returned None and every Opus 5 message priced to $0 after a warn_once. Rates are $5 per million input and $25 per million output, the same as Claude Opus 4.8, which puts cache write at 6.25 and cache read at 0.5 under the multipliers used throughout this file. Aliases follow the shape already used for the other 5-generation models. The global.anthropic. form matches claude-sonnet-5; claude-fable-5 does not carry one, so that part is a choice rather than a deduction and is easy to drop. Closes Piebald-AI#221
📝 WalkthroughWalkthroughThe model registry adds ChangesClaude Opus 5 support
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/models.rs (1)
2774-2787: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winExpand the regression test to cover the full alias and cache contract.
The test covers only
claude-5-opus. It does not exercise the other accepted names, includingglobal.anthropic.claude-opus-5.get_model_infodoes not normalize the dotted provider prefix, so that alias requires direct coverage.The test also checks only the combined cache total. Add separate assertions for cache-write cost
6.25, cache-read cost0.5, and combined cost6.75.Suggested test expansion
- let model_info = get_model_info("claude-5-opus").expect("model should exist"); - assert!(!model_info.is_estimated); - - let input_cost = calculate_input_cost("claude-5-opus", 1_000_000); - let output_cost = calculate_output_cost("claude-5-opus", 1_000_000); - let cache_cost = calculate_cache_cost("claude-5-opus", 1_000_000, 1_000_000); - - approx_eq(input_cost, 5.0); - approx_eq(output_cost, 25.0); - approx_eq(cache_cost, 6.75); + for model in [ + "claude-opus-5", + "claude-opus-5.0", + "claude-5-opus", + "claude-5.0-opus", + "global.anthropic.claude-opus-5", + ] { + let model_info = get_model_info(model).expect("model should exist"); + assert!(!model_info.is_estimated); + + approx_eq(calculate_input_cost(model, 1_000_000), 5.0); + approx_eq(calculate_output_cost(model, 1_000_000), 25.0); + approx_eq(calculate_cache_cost(model, 1_000_000, 0), 6.25); + approx_eq(calculate_cache_cost(model, 0, 1_000_000), 0.5); + approx_eq(calculate_cache_cost(model, 1_000_000, 1_000_000), 6.75); + }🤖 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 `@src/models.rs` around lines 2774 - 2787, Expand claude_opus_5_alias_maps_to_pricing to iterate over every accepted Claude Opus 5 alias, including global.anthropic.claude-opus-5, and verify each resolves through get_model_info with non-estimated pricing and the expected input/output costs. Add separate cache-write and cache-read assertions for 6.25 and 0.5, while retaining the combined cache-cost assertion of 6.75.
🤖 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 `@src/models.rs`:
- Around line 2774-2787: Expand claude_opus_5_alias_maps_to_pricing to iterate
over every accepted Claude Opus 5 alias, including
global.anthropic.claude-opus-5, and verify each resolves through get_model_info
with non-estimated pricing and the expected input/output costs. Add separate
cache-write and cache-read assertions for 6.25 and 0.5, while retaining the
combined cache-cost assertion of 6.75.
Closes #221.
claude-opus-5had no entry, soget_model_inforeturnedNoneand every Opus 5 message priced to $0 after awarn_once. On the corpus in #221 that was $108.60 of usage reported as free.Rates are $5 per million input and $25 per million output, the same as Claude Opus 4.8, which puts cache write at 6.25 and cache read at 0.5 under the multipliers this file uses throughout. The entry sits between
claude-sonnet-5andclaude-opus-4-8, matching the existing ordering.Aliases follow the shape already used for the other 5-generation models. One line is a judgement rather than a deduction:
global.anthropic.claude-opus-5matches whatclaude-sonnet-5carries, whileclaude-fable-5has no such alias, so the file is not consistent on that point today. Easy to drop if you would rather it were not there.The test mirrors
claude_opus_4_8_alias_maps_to_pricing.Verification. 402 passed, 0 failed, including the new test.
cargo clippy --locked --all-targets -- -D warningsandcargo fmt --checkclean. Run: 30646415635, on the same tree as this branch plus a temporary workflow that is not part of the change, sincechecks.ymldoes not runcargo test.Summary by CodeRabbit