From 9f313db374a80774674409e0a27f9622d9417cb1 Mon Sep 17 00:00:00 2001 From: Paolo Belcastro <1436372+p3ob7o@users.noreply.github.com> Date: Fri, 17 Jul 2026 04:52:52 +0200 Subject: [PATCH] fix(pricing): add Sonnet 5 and Fable 5 to the canonical chat-pricing table (#2799) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit claude-sonnet-5 and claude-fable-5 are GA Anthropic models, but neither was in CANONICAL_PRICING. A brain routing a tier to them (e.g. models.tier.reasoning = anthropic:claude-sonnet-5) ran with cost telemetry blind on that tier: canonicalLookup missed, the budget meter logged BUDGET_METER_NO_PRICING and disabled the gate, and cost views under-reported spend. - model-pricing.ts: anthropic:claude-sonnet-5 at $3/$15 and anthropic:claude-fable-5 at $10/$50. Sonnet 5's launch intro discount ($2/$10 through 2026-08-31) is deliberately not modeled — the table carries standard rates so estimates stay conservative and the entry needs no time-bombed edit when the promo lapses. - takes-quality-eval/pricing.ts: claude-sonnet-5 added to the curated SUPPORTED_MODELS allowlist (a likely judge override). Fable 5 stays out — priced for warn-only consumers, not a budgeted-eval panel model. - model-pricing.test.ts: pin tests for both rows, matching the existing Opus 4.8/4.7 pattern. Drift guards iterate the table; no changes. All derived views (ANTHROPIC_PRICING bare view -> budget-tracker, batch-projection, budget-meter) pick the rows up automatically. Co-authored-by: Paolo Belcastro Co-authored-by: Claude Fable 5 --- src/core/model-pricing.ts | 7 +++++++ src/core/takes-quality-eval/pricing.ts | 1 + test/model-pricing.test.ts | 8 ++++++++ 3 files changed, 16 insertions(+) diff --git a/src/core/model-pricing.ts b/src/core/model-pricing.ts index db1e8854e..090310cef 100644 --- a/src/core/model-pricing.ts +++ b/src/core/model-pricing.ts @@ -52,11 +52,18 @@ export interface ModelPricing { */ export const CANONICAL_PRICING: Record = { // ── Anthropic ────────────────────────────────────────────────────────── + // Fable 5: Anthropic's top tier, above Opus. $10 in / $50 out. + 'anthropic:claude-fable-5': { input: 10.00, output: 50.00 }, // Opus 4.x: $5 in / $25 out. 4.8 (released 2026-05-28) shares 4.7's // per-token rate — closes gbrain#1819. 'anthropic:claude-opus-4-8': { input: 5.00, output: 25.00 }, 'anthropic:claude-opus-4-7': { input: 5.00, output: 25.00 }, 'anthropic:claude-opus-4-6': { input: 5.00, output: 25.00 }, + // Sonnet 5 (released 2026-06-29): same $3/$15 sticker as 4.6. The launch + // intro discount ($2/$10 through 2026-08-31) is deliberately NOT modeled — + // the table carries standard rates so estimates stay conservative and + // don't need a time-bombed edit when the promo lapses. + 'anthropic:claude-sonnet-5': { input: 3.00, output: 15.00 }, 'anthropic:claude-sonnet-4-6': { input: 3.00, output: 15.00 }, // Haiku 4.5 — both the dateless canonical id and the dated snapshot. 'anthropic:claude-haiku-4-5': { input: 1.00, output: 5.00 }, diff --git a/src/core/takes-quality-eval/pricing.ts b/src/core/takes-quality-eval/pricing.ts index b8305a417..6c2aed6be 100644 --- a/src/core/takes-quality-eval/pricing.ts +++ b/src/core/takes-quality-eval/pricing.ts @@ -37,6 +37,7 @@ const SUPPORTED_MODELS = [ 'openai:gpt-5.5', 'anthropic:claude-opus-4-8', 'anthropic:claude-opus-4-7', + 'anthropic:claude-sonnet-5', 'anthropic:claude-sonnet-4-6', 'anthropic:claude-haiku-4-5', 'google:gemini-1.5-pro', diff --git a/test/model-pricing.test.ts b/test/model-pricing.test.ts index 40be89818..26da0100d 100644 --- a/test/model-pricing.test.ts +++ b/test/model-pricing.test.ts @@ -43,6 +43,14 @@ describe('CANONICAL_PRICING — table integrity', () => { expect(CANONICAL_PRICING['anthropic:claude-opus-4-7']).toEqual({ input: 5.0, output: 25.0 }); }); + test('Sonnet 5 present at $3/$15 (standard rate, intro discount not modeled)', () => { + expect(CANONICAL_PRICING['anthropic:claude-sonnet-5']).toEqual({ input: 3.0, output: 15.0 }); + }); + + test('Fable 5 present at $10/$50', () => { + expect(CANONICAL_PRICING['anthropic:claude-fable-5']).toEqual({ input: 10.0, output: 50.0 }); + }); + test('Gemini 2.0 Flash reconciled to $0.10/$0.40; legacy alias agrees', () => { expect(CANONICAL_PRICING['google:gemini-2.0-flash']).toEqual({ input: 0.1, output: 0.4 }); expect(CANONICAL_PRICING['google:gemini-2-flash']).toEqual(