Skip to content

feat: update model pricing with Claude 4.5 and version-specific rates#182

Open
BenoitdeKersabiec wants to merge 1 commit intoMaciek-roboblog:mainfrom
BenoitdeKersabiec:feature/update-model-pricing
Open

feat: update model pricing with Claude 4.5 and version-specific rates#182
BenoitdeKersabiec wants to merge 1 commit intoMaciek-roboblog:mainfrom
BenoitdeKersabiec:feature/update-model-pricing

Conversation

@BenoitdeKersabiec
Copy link

@BenoitdeKersabiec BenoitdeKersabiec commented Jan 17, 2026

Update pricing to reflect current Anthropic pricing as of January 2025:

  • Add Claude 4.5 models (Opus, Sonnet, Haiku) with new lower rates
  • Add Claude 4 models with distinct pricing from 4.5
  • Add Claude 3.5 models (Haiku, Sonnet)
  • Refactor fallback logic to detect model versions (4.5, 4, 3.5, 3)
  • Extract helper methods for cleaner code

Pricing source: https://platform.claude.com/docs/en/about-claude/pricing

Summary by CodeRabbit

Release Notes

  • New Features

    • Added pricing support for new Claude model versions including Opus 4.5, Sonnet 4.5, Haiku 4.5, Opus 4, Sonnet 4, and updated Claude 3.x variants.
  • Improvements

    • Enhanced pricing calculation logic with improved fallback handling for better model compatibility and cache pricing defaults.

✏️ Tip: You can customize this high-level summary in your review settings.

Update pricing to reflect current Anthropic pricing as of January 2025:
- Add Claude 4.5 models (Opus, Sonnet, Haiku) with new lower rates
- Add Claude 4 models with distinct pricing from 4.5
- Add Claude 3.5 models (Haiku, Sonnet)
- Refactor fallback logic to detect model versions (4.5, 4, 3.5, 3)
- Extract helper methods for cleaner code

Pricing source: https://platform.claude.com/docs/en/about-claude/pricing
@coderabbitai
Copy link

coderabbitai bot commented Jan 17, 2026

📝 Walkthrough

Walkthrough

The pricing module is expanded with fallback pricing data for new Claude model variants (opus-4-5, sonnet-4-5, haiku-4-5, opus-4, sonnet-4, and claude-3 variants). Two internal helper methods are added to manage cache pricing defaults and fallback pricing lookup, with refactored pricing retrieval logic to use these helpers.

Changes

Cohort / File(s) Summary
Pricing Data & Fallback Logic
src/claude_monitor/core/pricing.py
Expanded FALLBACK_PRICING dictionary with 9 new model variants and their input/output/cache pricing. Updated __init__ model mappings to reference new variants. Added _ensure_cache_pricing() helper to set cache pricing defaults. Added _get_fallback_pricing() helper to determine appropriate fallback entry by model name and version indicators. Refactored _get_pricing_for_model() to use new helpers and gracefully handle unknown models when strict mode is disabled.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A hop and a skip through pricing anew,
With opus and sonnet in clever review,
Cache defaults now nestled where helpers once grew,
Our fallback grows stronger—Claude's costs crystal-clear too!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately reflects the main change: updating pricing data to include Claude 4.5 models and implementing version-specific pricing logic.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/claude_monitor/core/pricing.py`:
- Around line 237-248: The is_4 detection can miss model names that end with
"-4" (e.g., "claude-opus-4"); update the is_4 boolean in pricing.py to also
check for model_lower.endswith("-4") (keeping the existing is_4_5 precedence) so
that the block that returns self.FALLBACK_PRICING["opus-4"] correctly handles
trailing "-4" names; change the is_4 assignment (the variable named is_4 that
uses model_lower, and the subsequent if "opus" branch that returns opus-4) to
include this endswith check.
- Around line 29-108: FALLBACK_PRICING contains an outdated rate for the
"haiku-3-5" key; update the "haiku-3-5" entry in the FALLBACK_PRICING dict to
use input: 1.0 and output: 5.0 (and adjust related cache_creation/cache_read if
you want them to match the 4.5 haiku multipliers) so it matches the current
Claude 3.5 Haiku pricing; locate the FALLBACK_PRICING constant and change the
"haiku-3-5" values accordingly (or add a comment explaining why the older 0.8/4
values are intentionally retained if you choose not to update).
🧹 Nitpick comments (1)
src/claude_monitor/core/pricing.py (1)

197-202: Avoid mutating the input dictionary.

This method modifies the pricing dict in place. Since self.pricing values are direct references to FALLBACK_PRICING entries, any mutation would affect the class-level constant. Currently safe because all entries have cache keys, but fragile if custom pricing is provided without them.

♻️ Return a new dict instead of mutating
     def _ensure_cache_pricing(self, pricing: Dict[str, float]) -> Dict[str, float]:
+        result = pricing.copy()
-        if "cache_creation" not in pricing:
-            pricing["cache_creation"] = pricing["input"] * 1.25
-        if "cache_read" not in pricing:
-            pricing["cache_read"] = pricing["input"] * 0.1
-        return pricing
+        if "cache_creation" not in result:
+            result["cache_creation"] = result["input"] * 1.25
+        if "cache_read" not in result:
+            result["cache_read"] = result["input"] * 0.1
+        return result

Comment on lines 29 to 108
FALLBACK_PRICING: Dict[str, Dict[str, float]] = {
"opus": {
"opus-4-5": {
"input": 5.0,
"output": 25.0,
"cache_creation": 6.25,
"cache_read": 0.5,
},
"sonnet-4-5": {
"input": 3.0,
"output": 15.0,
"cache_creation": 3.75,
"cache_read": 0.3,
},
"haiku-4-5": {
"input": 1.0,
"output": 5.0,
"cache_creation": 1.25,
"cache_read": 0.1,
},
"opus-4": {
"input": 15.0,
"output": 75.0,
"cache_creation": 18.75,
"cache_read": 1.5,
},
"sonnet": {
"sonnet-4": {
"input": 3.0,
"output": 15.0,
"cache_creation": 3.75,
"cache_read": 0.3,
},
"haiku": {
"haiku-3-5": {
"input": 0.8,
"output": 4.0,
"cache_creation": 1.0,
"cache_read": 0.08,
},
"sonnet-3-5": {
"input": 3.0,
"output": 15.0,
"cache_creation": 3.75,
"cache_read": 0.3,
},
"opus-3": {
"input": 15.0,
"output": 75.0,
"cache_creation": 18.75,
"cache_read": 1.5,
},
"sonnet-3": {
"input": 3.0,
"output": 15.0,
"cache_creation": 3.75,
"cache_read": 0.3,
},
"haiku-3": {
"input": 0.25,
"output": 1.25,
"cache_creation": 0.3,
"cache_read": 0.03,
},
"opus": {
"input": 5.0,
"output": 25.0,
"cache_creation": 6.25,
"cache_read": 0.5,
},
"sonnet": {
"input": 3.0,
"output": 15.0,
"cache_creation": 3.75,
"cache_read": 0.3,
},
"haiku": {
"input": 1.0,
"output": 5.0,
"cache_creation": 1.25,
"cache_read": 0.1,
},
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

Claude API pricing January 2025 official documentation

💡 Result:

As of January 2025, Anthropic’s official Claude API documentation lists token-based pricing (per 1M tokens) and related multipliers. Key published rates:

  • Claude Sonnet (mid‑tier): Input $3 / 1M, Output $15 / 1M. [1][2]
  • Claude Haiku (cost‑efficient): Input $0.80 / 1M, Output $4 / 1M. [1][2]
  • Claude Opus (highest capability): Input $15 / 1M, Output $75 / 1M. [2]

Other documented details:

  • Prompt‑caching and cache read/write multipliers apply (cache writes/read charged differently). [2]
  • Batch (asynchronous) API: typically a 50% discount on input/output token rates for supported models. [1]
  • Long‑context (1M token window) premium rates apply for >200K input tokens on Sonnet 4/4.5 (higher per‑token rates). [1]

Sources: Anthropic / Claude official docs. [1] https://docs.claude.com/en/docs/about-claude/pricing [2] https://docs.anthropic.com/en/docs/about-claude/models/all-models


🌐 Web query:

Claude 4.5 opus sonnet haiku pricing per million tokens 2025

💡 Result:

Here are Anthropic’s Claude 4.5 (Opus / Sonnet / Haiku) API prices per million tokens (USD):

  • Opus 4.5 — Input: $5 / 1M tokens; Output: $25 / 1M. [1][2]
  • Sonnet 4.5 — Input: $3 / 1M (prompts >200K: $6 / 1M); Output: $15 / 1M (prompts >200K: $22.50 / 1M). [2][3]
  • Haiku 4.5 — Input: $1 / 1M; Output: $5 / 1M. [2][3]

Sources: Anthropic product/news and pricing pages. [1] Anthropic announcement; [2] Claude pricing page; [3] Claude docs (models & pricing).


🌐 Web query:

Claude 4 opus sonnet pricing input output per million tokens

💡 Result:

Summary (per‑million‑token API pricing):

  • Claude Opus 4 / Opus 4.1 — Input: $15 / MTok; Output: $75 / MTok. [1][2]
  • Claude Opus 4.5 — Input: $5 / MTok; Output: $25 / MTok. [2][3]
  • Claude Sonnet 4 (and Sonnet 3.7) — Input: $3 / MTok; Output: $15 / MTok. [1][2]
  • Claude Sonnet 4.5 — Typical: Input $3 / MTok and Output $15 / MTok for prompts ≤200K tokens; higher rates apply for prompts >200K (Input $6 / MTok, Output $22.50 / MTok). [2][3]

Sources: Anthropic/Claude pricing pages and docs. [1] [2] [3]

References:
[1] Anthropic models overview / pricing. (docs.anthropic.com)
[2] Claude pricing page (official). (claude.com)
[3] Recent pricing summary / blog posts (Opus/Sonnet 4.5 announcements). (website.claude.com)

Citations:


🌐 Web query:

Claude 3.5 haiku sonnet pricing input output per million tokens

💡 Result:

Short answer — per Anthropic’s docs (current model pages):

  • Claude 3.5 Sonnet: $3 /M input tokens; $15 /M output tokens. [1][2]
  • Claude 3.5 Haiku: $0.80 /M input tokens; $4 /M output tokens. [1][2]

Note: some news reporting (Nov 2024) states Claude 3.5 Haiku was later listed at $1 /M input and $5 /M output; you may see either pair in different pages. [3]

Sources: Anthropic model/pricing docs and Claude pricing page. [1][2][3]


🌐 Web query:

Claude 3 opus sonnet haiku pricing input output per million tokens

💡 Result:

Summary (price per 1M tokens, USD):

  • Claude Opus (Claude 3 / Opus series): Input $15 / MTok — Output $75 / MTok. [1][2]
  • Claude Sonnet (Claude 3 Sonnet family): Input $3 / MTok — Output $15 / MTok. [1][2]
  • Claude Haiku (Claude 3 family): depends on sub‑version — e.g. Haiku 4.5: Input $1 / MTok — Output $5 / MTok; older Haiku variants: Haiku 3.5 ≈ $0.80 input / $4 output, Haiku 3 ≈ $0.25 input / $1.25 output. [1][2]

Notes: Anthropic’s docs also list prompt‑caching multipliers (5‑min and 1‑hr cache write rates and cache read rates) that affect billed rates; see the cited pricing table for details. [1][2]

Sources: Anthropic / Claude docs pricing tables. [1] [2]


🌐 Web query:

Claude prompt caching pricing cache write cache read multiplier per million tokens

💡 Result:

Short answer:

  • Multiplier: cache write = 1.25× base input price (25% higher); cache read = 0.10× base input price (10% of base). [1][2]

  • Example prices (per MTok = per million tokens) reported by Anthropic for Claude models:

    • Claude 3.5 Sonnet — Input $3 / MTok; Cache write $3.75 / MTok; Cache read $0.30 / MTok. [1]
    • Claude 3 Opus — Input $15 / MTok; Cache write $18.75 / MTok; Cache read $1.50 / MTok. [1]
    • Claude 3 Haiku — Input $0.25 / MTok; Cache write $0.30 / MTok; Cache read $0.03 / MTok. [1]
    • (Docs also show 5‑min vs 1‑hour write multipliers where 1‑hour writes = 2× base input price). [2]

Sources: Anthropic prompt-caching blog and Claude pricing docs. [1][2]


Pricing structure verified against official documentation and correctly implemented.

All base input/output prices match Anthropic's official Claude API pricing as of January 2025:

  • 4.5 models: Opus ($5/$25), Sonnet ($3/$15), Haiku ($1/$5) ✓
  • 4 models: Opus ($15/$75), Sonnet ($3/$15) ✓
  • 3.5 models: Sonnet ($3/$15), Haiku ($0.80/$4) ✓
  • 3 models: Opus ($15/$75), Sonnet ($3/$15), Haiku ($0.25/$1.25) ✓

Cache pricing multipliers are correctly applied (1.25× for cache writes, 0.10× for cache reads).

Minor note: The haiku-3-5 entry uses $0.80/$4 per official documentation, but Anthropic updated Claude 3.5 Haiku pricing to $1/$5 in November 2024. Consider updating haiku-3-5 to match the current rate, or document why the earlier pricing is retained. The generic haiku fallback correctly defaults to the current 4.5 pricing ($1/$5).

🤖 Prompt for AI Agents
In `@src/claude_monitor/core/pricing.py` around lines 29 - 108, FALLBACK_PRICING
contains an outdated rate for the "haiku-3-5" key; update the "haiku-3-5" entry
in the FALLBACK_PRICING dict to use input: 1.0 and output: 5.0 (and adjust
related cache_creation/cache_read if you want them to match the 4.5 haiku
multipliers) so it matches the current Claude 3.5 Haiku pricing; locate the
FALLBACK_PRICING constant and change the "haiku-3-5" values accordingly (or add
a comment explaining why the older 0.8/4 values are intentionally retained if
you choose not to update).

Comment on lines +237 to +248
is_4_5 = "4-5" in model_lower or "4.5" in model_lower
is_4 = not is_4_5 and (
"4-" in model_lower or "-4-" in model_lower or "4.1" in model_lower
)
is_3_5 = "3-5" in model_lower or "3.5" in model_lower

if "opus" in model_lower:
return self.FALLBACK_PRICING["opus"]
if is_4_5:
return self.FALLBACK_PRICING["opus-4-5"]
if is_4:
return self.FALLBACK_PRICING["opus-4"]
return self.FALLBACK_PRICING["opus-3"]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Version detection may miss models ending in "-4".

The is_4 check looks for "4-" or "-4-" in the model name, but won't match model names that end with -4 (e.g., "claude-opus-4", "some-opus-4"). While currently mapped models are handled in self.pricing, future model variations or API name differences could fall through incorrectly.

🔧 Suggested fix to handle trailing -4
-        is_4 = not is_4_5 and (
-            "4-" in model_lower or "-4-" in model_lower or "4.1" in model_lower
-        )
+        is_4 = not is_4_5 and (
+            "4-" in model_lower or "-4-" in model_lower or 
+            model_lower.endswith("-4") or "4.1" in model_lower
+        )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
is_4_5 = "4-5" in model_lower or "4.5" in model_lower
is_4 = not is_4_5 and (
"4-" in model_lower or "-4-" in model_lower or "4.1" in model_lower
)
is_3_5 = "3-5" in model_lower or "3.5" in model_lower
if "opus" in model_lower:
return self.FALLBACK_PRICING["opus"]
if is_4_5:
return self.FALLBACK_PRICING["opus-4-5"]
if is_4:
return self.FALLBACK_PRICING["opus-4"]
return self.FALLBACK_PRICING["opus-3"]
is_4_5 = "4-5" in model_lower or "4.5" in model_lower
is_4 = not is_4_5 and (
"4-" in model_lower or "-4-" in model_lower or
model_lower.endswith("-4") or "4.1" in model_lower
)
is_3_5 = "3-5" in model_lower or "3.5" in model_lower
if "opus" in model_lower:
if is_4_5:
return self.FALLBACK_PRICING["opus-4-5"]
if is_4:
return self.FALLBACK_PRICING["opus-4"]
return self.FALLBACK_PRICING["opus-3"]
🤖 Prompt for AI Agents
In `@src/claude_monitor/core/pricing.py` around lines 237 - 248, The is_4
detection can miss model names that end with "-4" (e.g., "claude-opus-4");
update the is_4 boolean in pricing.py to also check for
model_lower.endswith("-4") (keeping the existing is_4_5 precedence) so that the
block that returns self.FALLBACK_PRICING["opus-4"] correctly handles trailing
"-4" names; change the is_4 assignment (the variable named is_4 that uses
model_lower, and the subsequent if "opus" branch that returns opus-4) to include
this endswith check.

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.

2 participants