diff --git a/src/hooks/caveman-stats.js b/src/hooks/caveman-stats.js index 008603b4..acef7ba5 100644 --- a/src/hooks/caveman-stats.js +++ b/src/hooks/caveman-stats.js @@ -22,13 +22,20 @@ const COMPRESSION = { 'full': 0.65 }; // Match by model id prefix so this stays correct across point releases // (e.g. claude-sonnet-4-20250514, claude-sonnet-4-7). Update from // https://www.anthropic.com/pricing if a release changes the tier. +// Most-specific prefixes MUST come first — priceForModel returns the first match. const MODEL_OUTPUT_PRICE_PER_M = [ - ['claude-opus-4', 75.00], - ['claude-sonnet-4', 15.00], - ['claude-haiku-4', 4.00], - ['claude-3-5-sonnet', 15.00], - ['claude-3-5-haiku', 4.00], - ['claude-3-opus', 75.00], + // Legacy Opus 4.0 / 4.1 (pre-4.5) billed at the old $75/M output tier, + // including the dated ids (e.g. claude-opus-4-20250514). + ['claude-opus-4-0', 75.00], + ['claude-opus-4-1', 75.00], + ['claude-opus-4-2025', 75.00], + // Opus 4.5–4.8 dropped to $25/M output (rate card held since 4.5). + ['claude-opus-4', 25.00], + ['claude-sonnet-4', 15.00], + ['claude-haiku-4', 5.00], // Haiku 4.5 = $5/M output + ['claude-3-5-sonnet', 15.00], + ['claude-3-5-haiku', 4.00], + ['claude-3-opus', 75.00], ]; function priceForModel(model) { diff --git a/tests/test_caveman_stats.js b/tests/test_caveman_stats.js index 85270c29..e10694b2 100644 --- a/tests/test_caveman_stats.js +++ b/tests/test_caveman_stats.js @@ -160,10 +160,12 @@ test('omits USD line when model is unknown', (tmp) => { test('priceForModel matches by prefix across point releases', () => { const { priceForModel } = require(path.join(ROOT, 'src', 'hooks', 'caveman-stats.js')); - assert.strictEqual(priceForModel('claude-opus-4-7'), 75.00); + assert.strictEqual(priceForModel('claude-opus-4-7'), 25.00); + assert.strictEqual(priceForModel('claude-opus-4-8'), 25.00); assert.strictEqual(priceForModel('claude-opus-4-20250101'), 75.00); + assert.strictEqual(priceForModel('claude-opus-4-1-20250805'), 75.00); assert.strictEqual(priceForModel('claude-sonnet-4-7-20260315'), 15.00); - assert.strictEqual(priceForModel('claude-haiku-4-5'), 4.00); + assert.strictEqual(priceForModel('claude-haiku-4-5'), 5.00); assert.strictEqual(priceForModel('claude-3-5-sonnet-20241022'), 15.00); assert.strictEqual(priceForModel(null), null); assert.strictEqual(priceForModel('gpt-4'), null);