diff --git a/CHANGELOG.md b/CHANGELOG.md index b22f5ac202..d31e3a9173 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ _Development cycle in progress — entries are added as work merges into `release/v3.8.9` and finalized by the release flow._ +### 🔧 Bug Fixes + +- **cache:** preserve client-side `cache_control` breakpoints for Xiaomi MiMo — added `xiaomi-mimo` to the prompt-caching provider allowlist so Claude Code (via cc-switch) cache hints are no longer stripped by the OpenAI-format translator, restoring cache hits. ([#3088](https://github.com/diegosouzapw/OmniRoute/issues/3088)) + --- ## [3.8.8] — 2026-06-03 diff --git a/open-sse/utils/cacheControlPolicy.ts b/open-sse/utils/cacheControlPolicy.ts index 1e511cbd1f..7fcae00510 100644 --- a/open-sse/utils/cacheControlPolicy.ts +++ b/open-sse/utils/cacheControlPolicy.ts @@ -72,7 +72,18 @@ const DETERMINISTIC_STRATEGIES: Set = new Set(["priority", /** * Providers that support prompt caching */ -const CACHING_PROVIDERS = new Set(["claude", "anthropic", "zai", "qwen", "deepseek"]); +const CACHING_PROVIDERS = new Set([ + "claude", + "anthropic", + "zai", + "qwen", + "deepseek", + // #3088 — Xiaomi MiMo honors OpenAI-format cache_control breakpoints. Without + // this entry, shouldPreserveCacheControl() returns false for Claude Code + // clients and filterToOpenAIFormat() strips cache_control, so Xiaomi never + // sees the cache hints and every request is a cache miss. + "xiaomi-mimo", +]); /** * Detect if the client is Claude Code or another caching-aware client diff --git a/tests/unit/cache-control-policy.test.ts b/tests/unit/cache-control-policy.test.ts index c731a3b193..9708d294e6 100644 --- a/tests/unit/cache-control-policy.test.ts +++ b/tests/unit/cache-control-policy.test.ts @@ -38,6 +38,10 @@ describe("Cache Control Policy", () => { assert.equal(providerSupportsCaching("anthropic"), true); assert.equal(providerSupportsCaching("zai"), true); assert.equal(providerSupportsCaching("qwen"), true); + assert.equal(providerSupportsCaching("deepseek"), true); + // #3088 — Xiaomi MiMo supports prompt caching; cache_control breakpoints + // sent by Claude Code (via cc-switch) must be preserved, not stripped. + assert.equal(providerSupportsCaching("xiaomi-mimo"), true); }); test("rejects non-caching providers", () => { @@ -51,6 +55,20 @@ describe("Cache Control Policy", () => { test("is case-insensitive", () => { assert.equal(providerSupportsCaching("Claude"), true); assert.equal(providerSupportsCaching("ANTHROPIC"), true); + assert.equal(providerSupportsCaching("Xiaomi-MiMo"), true); + }); + + // #3088 — regression: a Claude Code client routed to xiaomi-mimo must keep + // its client-side cache_control breakpoints so Xiaomi's API sees cache hints. + test("preserves client cache_control for xiaomi-mimo single model", () => { + assert.equal( + shouldPreserveCacheControl({ + userAgent: "claude-cli/2.1.113 (external, sdk-cli)", + isCombo: false, + targetProvider: "xiaomi-mimo", + }), + true + ); }); });