diff --git a/internal/cost/cost_test.go b/internal/cost/cost_test.go index 2e2db2a..2c12846 100644 --- a/internal/cost/cost_test.go +++ b/internal/cost/cost_test.go @@ -33,6 +33,8 @@ func TestLookupPrefixAndProviderIDs(t *testing.T) { "claude-3-5-haiku-20241022": "claude-3-5-haiku", "CLAUDE-HAIKU-4-5": "claude-haiku-4-5", "anthropic.claude-opus-4-1-20250805-v1:0": "claude-opus-4-1", + "claude-fable-5-1": "claude-fable-5-1", + "claude-fable-5": "claude-fable-5", } for in, want := range cases { row, ok := tb.Lookup(in) @@ -226,3 +228,28 @@ func TestEveryModelHasExactlyOneCurrentPrice(t *testing.T) { } } } + +func TestFable51CacheReadsAtItsOwnRate(t *testing.T) { + tb, _ := Embedded() + + // Fable 5.1 reads cache at 0.025x input, not the 0.1x every other row + // follows, so the $0.25 looks like a typo of Fable 5's $1.00 and sits one + // character away from a row that would charge four times as much. + for _, tc := range []struct { + model string + want float64 + }{ + {"claude-fable-5-1", 0.25}, + {"claude-mythos-5-1", 0.25}, + {"claude-fable-5", 1.0}, + } { + got, ok := tb.Price(tc.model, event.TokenDelta{CacheRead: 1_000_000}) + if !ok { + t.Errorf("%s has no price", tc.model) + continue + } + if got != tc.want { + t.Errorf("%s: 1M cache-read tokens cost $%.2f, want $%.2f", tc.model, got, tc.want) + } + } +} diff --git a/pricing/pricing.json b/pricing/pricing.json index 2b2cc85..e531043 100644 --- a/pricing/pricing.json +++ b/pricing/pricing.json @@ -1,12 +1,12 @@ { - "version": "2026-09-01.1", + "version": "2026-09-02.1", "source": "https://platform.claude.com/docs/en/about-claude/pricing", "fetched_at": "2026-08-18", "currency": "USD", "unit": "per_million_tokens", "notes": [ "First-party Anthropic API prices. Amazon Bedrock and Google Vertex have separate partner pricing (regional endpoints +10%) and are not covered by this table (OQ-02).", - "cache_write_5m = 1.25x input, cache_write_1h = 2x input, cache_read = 0.1x input \u2014 per Anthropic's published multipliers.", + "cache_write_5m = 1.25x input, cache_write_1h = 2x input, cache_read = 0.1x input \u2014 per Anthropic's published multipliers. Claude Fable 5.1 and Claude Mythos 5.1 are the exception and read 0.025x ($0.25 per 1M), so those two rows deliberately break the 0.1x rule; both were read from the pricing page on 2026-09-02.", "Model ids are matched by prefix against the `model` field observed in transcripts (e.g. claude-opus-5, claude-sonnet-4-5-20250929). Longest prefix wins.", "context_window is the model's maximum input context in tokens as published; used for the 'context fill %' badge (OQ-07).", "Non-Anthropic rows are the providers' own published list prices, fetched 2026-08-27: DeepSeek V4 Pro $0.435/$0.87 per 1M (its 75% cut, made permanent); MiniMax M3 $0.30/$1.20 per 1M standard tier with $0.06 cache read (its permanent 50% off). They are priced so a total that includes non-Anthropic usage is a total; Caprock still does not charge for any of it and cannot see a bill.", @@ -17,6 +17,26 @@ "gemini-3.1-pro-preview and gemini-2.5-pro are tiered by prompt size; the rate here is the =<200k tier. Prompts over 200k tokens bill at roughly double ($4.00/$18.00 and $2.50/$15.00 respectively) and are therefore under-reported by this table." ], "models": [ + { + "id": "claude-fable-5-1", + "display": "Claude Fable 5.1", + "input": 10.0, + "cache_write_5m": 12.5, + "cache_write_1h": 20.0, + "cache_read": 0.25, + "output": 50.0, + "context_window": 1000000 + }, + { + "id": "claude-mythos-5-1", + "display": "Claude Mythos 5.1", + "input": 10.0, + "cache_write_5m": 12.5, + "cache_write_1h": 20.0, + "cache_read": 0.25, + "output": 50.0, + "context_window": 1000000 + }, { "id": "claude-fable-5", "display": "Claude Fable 5",