From b59a88b7eb2fcadde96ff6974337c8dc7138fd30 Mon Sep 17 00:00:00 2001 From: stanley Date: Thu, 20 Aug 2026 23:11:03 +0700 Subject: [PATCH] fix(pricing): 3 dead entries in LITELLM_PROVIDER_MAP silently drop synced pricing (#10636) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merged — locally validated (28/28 focused pricing-sync tests, gates green). Excellent systematic audit of the whole alias map, not just the one you hit. Thanks! --- src/lib/pricingSync.ts | 23 +++++++++++++++++++---- tests/unit/pricing-sync.test.ts | 11 ++++++++--- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/lib/pricingSync.ts b/src/lib/pricingSync.ts index a334a9f096..e828d962ed 100644 --- a/src/lib/pricingSync.ts +++ b/src/lib/pricingSync.ts @@ -105,10 +105,22 @@ const LITELLM_PROVIDER_MAP: Record = { vertex_ai: ["gemini"], "vertex_ai-anthropic_models": ["anthropic"], google: ["gemini"], - deepseek: ["if"], + // Registry ALIAS, not registry id — pricingSync writes/reads are keyed by + // alias everywhere else (see getPricingForModel(provider, model) callers). + // Four of these previously used the provider's `id` string, which is not a + // valid pricing-lookup key for that provider and, worse, for `deepseek` a + // real (but wrong) alias existed under that string — silently routing + // DeepSeek's synced pricing onto Qoder (open-sse/config/providers/registry/ + // qoder/index.ts, alias "if", an unrelated third-party API) instead of + // DeepSeek (alias "ds"). `bedrock`/`bedrock_converse` and `cloudflare` + // pointed at their provider's `id` ("kiro", "cloudflare-ai") rather than + // its `alias` ("kr", "cf") — not wrong-provider, just a dead key nothing + // downstream ever looks up, so those two providers silently never received + // synced pricing at all. + deepseek: ["ds"], groq: ["groq"], together_ai: ["openrouter"], - bedrock: ["kiro"], + bedrock: ["kr"], fireworks_ai: ["fireworks"], cerebras: ["cerebras"], nvidia_nim: ["nvidia"], @@ -116,8 +128,11 @@ const LITELLM_PROVIDER_MAP: Record = { "vertex_ai-language_models": ["gemini"], "vertex_ai-mistral_models": ["mistral"], gemini: ["gemini"], - bedrock_converse: ["kiro"], - cloudflare: ["cloudflare-ai"], + bedrock_converse: ["kr"], + cloudflare: ["cf"], + // stability-ai has no chat-completions registry entry (image-only: + // open-sse/config/providers/registry/stability-ai/imageModels.ts) — left + // as-is rather than guessed at; not the same bug shape as the three above. stability: ["stability-ai"], }; diff --git a/tests/unit/pricing-sync.test.ts b/tests/unit/pricing-sync.test.ts index 2185c8007f..29ebc0ec41 100644 --- a/tests/unit/pricing-sync.test.ts +++ b/tests/unit/pricing-sync.test.ts @@ -138,9 +138,14 @@ describe("transformToOmniRoute", () => { const result = transformToOmniRoute(raw); - // deepseek maps to "if" alias - assert.ok(result.if, "Should map deepseek to if alias"); - assert.ok(result.if["deepseek-chat"]); + // deepseek maps to "ds" (its real registry alias — open-sse/config/providers/ + // registry/deepseek/index.ts). Previously mapped to "if" (Qoder's alias, an + // unrelated provider) — fixed alongside the other dead LITELLM_PROVIDER_MAP + // entries (bedrock/bedrock_converse/cloudflare) that pointed at a provider's + // `id` instead of its `alias`. + assert.ok(result.ds, "Should map deepseek to its real ds alias"); + assert.ok(result.ds["deepseek-chat"]); + assert.ok(!result.if, "Must not route deepseek pricing onto Qoder's if alias"); }); test("skips entries without input cost", () => {