diff --git a/src/lib/pricing/curated-overrides.json b/src/lib/pricing/curated-overrides.json index b575bbdf..076a58c2 100644 --- a/src/lib/pricing/curated-overrides.json +++ b/src/lib/pricing/curated-overrides.json @@ -68,6 +68,8 @@ { "match": "kiro", "ref": "kiro-cli-agent" }, { "match": "hy3", "ref": "hy3-preview-agent" }, { "match": "composer", "ref": "composer-1" }, + { "match": "fable", "ref": "claude-fable-5" }, + { "match": "mythos", "ref": "claude-mythos-5" }, { "match": "minimax-m2.7-highspeed", "ref": "MiniMax-M2.7-highspeed" }, { "match": "minimax-m2.7", "ref": "MiniMax-M2.7" }, { "match": "deepseek-v4-flash", "ref": "deepseek-v4-flash" }, diff --git a/test/pricing.test.js b/test/pricing.test.js index 72984b1a..5884df39 100644 --- a/test/pricing.test.js +++ b/test/pricing.test.js @@ -475,6 +475,16 @@ test("index: getModelPricing pins Claude Fable/Mythos 5 pricing from curated ove assert.equal(pinned.cache_write, 12.5); } + // Regression (issue #187): auto-pilot/canary variants wrap the pinned name + // with extra prefix/suffix segments (e.g. "claude-auto-pilot-fable-v1-canary"), + // so "fable"/"mythos" is not a contiguous substring of "claude-fable-5"/ + // "claude-mythos-5" — every non-fuzzy resolution tier misses on these ids. + for (const model of ["claude-auto-pilot-fable-v1-canary", "claude-mythos-v1-canary"]) { + const pinned = pricing.getModelPricing(model); + assert.equal(pinned.input, 10, `${model} should resolve to the Fable/Mythos pin`); + assert.equal(pinned.output, 50, `${model} should resolve to the Fable/Mythos pin`); + } + assert.equal( pricing.computeRowCost({ source: "claude",