From c8679b0c79a282c155296acb244a68485dc6af12 Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Sat, 18 Apr 2026 09:07:57 -0300 Subject: [PATCH] =?UTF-8?q?chore(release):=20v3.6.9=20=E2=80=94=20changelo?= =?UTF-8?q?g,=20docs,=20version=20sync?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 19 +++++++++++++++++++ docs/openapi.yaml | 2 +- electron/package.json | 2 +- llm.txt | 4 ++-- open-sse/package.json | 2 +- package-lock.json | 2 +- src/app/api/providers/validate/route.ts | 14 ++++++++++---- tests/unit/chatcore-translation-paths.test.ts | 11 ++++++----- 8 files changed, 41 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18197169..66197d84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,25 @@ --- +## [3.6.9] — 2026-04-18 + +### ✨ New Features + +- **feat(core):** Implement persistent API key, backup pruning, and GPU optimization (#1350, #1367, #1369) + +### 🐛 Bug Fixes + +- **fix(providers):** Resolve Claude passthrough corruption (#1359), Kimi-k2 reasoning header rejections (#1360), thinking parameter leaks (#1361), and Ollama proxy redirect drops (#1381) +- **fix(core):** Proxy lookup in key validation effectively respects the new ProxyRegistry environments (#1384) +- **fix(electron):** Resolve type error in Header electronAPI properties +- **fix(security):** Resolve CodeQL security alerts including safe prototype bindings (#151, #152, #154, #155-159) + +### 🛠️ Maintenance + +- **chore:** Sync infrastructure with docker postinstall components and secondary CodeQL analysis rules + +--- + ## [3.6.8] — 2026-04-17 ### ✨ New Features diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 941e8a4e..ac43b567 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -1,7 +1,7 @@ openapi: 3.1.0 info: title: OmniRoute API - version: 3.6.8 + version: 3.6.9 description: | OmniRoute is a local-first AI API proxy router. It provides an OpenAI-compatible endpoint that routes requests to multiple AI providers with load balancing, diff --git a/electron/package.json b/electron/package.json index f37885da..22a1a2b7 100644 --- a/electron/package.json +++ b/electron/package.json @@ -1,6 +1,6 @@ { "name": "omniroute-desktop", - "version": "3.6.8", + "version": "3.6.9", "description": "OmniRoute Desktop Application", "main": "main.js", "author": { diff --git a/llm.txt b/llm.txt index b14bae38..b0fd1e1f 100644 --- a/llm.txt +++ b/llm.txt @@ -8,7 +8,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo **Key value:** One endpoint (`http://localhost:20128/v1`), unlimited models, zero downtime, minimal cost. -**Current version:** 3.6.8 +**Current version:** 3.6.9 ## Tech Stack @@ -279,7 +279,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo └── .env.example # Environment variable template ``` -## Key Features (v3.6.8) +## Key Features (v3.6.9) ### Core Proxy - **60+ AI providers** with automatic format translation diff --git a/open-sse/package.json b/open-sse/package.json index 9fbfe86a..fae88031 100644 --- a/open-sse/package.json +++ b/open-sse/package.json @@ -1,6 +1,6 @@ { "name": "@omniroute/open-sse", - "version": "3.6.8", + "version": "3.6.9", "description": "Express SSE sidecar for OmniRoute — handles streaming, protocol translation, and provider orchestration", "type": "module", "main": "index.js", diff --git a/package-lock.json b/package-lock.json index 11d32a09..bb285345 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20962,7 +20962,7 @@ }, "open-sse": { "name": "@omniroute/open-sse", - "version": "3.6.8" + "version": "3.6.9" } } } diff --git a/src/app/api/providers/validate/route.ts b/src/app/api/providers/validate/route.ts index 41e12e7f..41f198d9 100644 --- a/src/app/api/providers/validate/route.ts +++ b/src/app/api/providers/validate/route.ts @@ -7,7 +7,7 @@ import { isAnthropicCompatibleProvider, } from "@/shared/constants/providers"; import { validateProviderApiKey } from "@/lib/providers/validation"; -import { getProxyForLevel } from "@/lib/localDb"; +import { getProxyForLevel, resolveProxyForProvider } from "@/lib/localDb"; import { validateProviderApiKeySchema } from "@/shared/validation/schemas"; import { isValidationFailure, validateBody } from "@/shared/validation/helpers"; import { runWithProxyContext } from "@omniroute/open-sse/utils/proxyFetch.ts"; @@ -87,10 +87,16 @@ export async function POST(request) { }; } - const providerProxy = await getProxyForLevel("provider", provider); - const globalProxy = providerProxy ? null : await getProxyForLevel("global"); + const registryProxy = await resolveProxyForProvider(provider); + let proxyToUse = registryProxy; - const result = await runWithProxyContext(providerProxy || globalProxy || null, () => + if (!proxyToUse) { + const providerProxy = await getProxyForLevel("provider", provider); + const globalProxy = providerProxy ? null : await getProxyForLevel("global"); + proxyToUse = providerProxy || globalProxy || null; + } + + const result = await runWithProxyContext(proxyToUse || null, () => validateProviderApiKey({ provider, apiKey, diff --git a/tests/unit/chatcore-translation-paths.test.ts b/tests/unit/chatcore-translation-paths.test.ts index 5f60ff4a..40b6a4e5 100644 --- a/tests/unit/chatcore-translation-paths.test.ts +++ b/tests/unit/chatcore-translation-paths.test.ts @@ -581,12 +581,12 @@ test("chatCore auto cache policy becomes false for nondeterministic combos", asy responseFormat: "claude", }); - assert.equal(call.body.system[0].text.includes("You are Claude Code"), true); + assert.equal(call.body.system[0].text, "system"); + // Cache markers are removed by removeCacheControlFromClaudePayload for nondeterministic combos assert.equal( - call.body.system.some((block) => block.cache_control?.ttl === "5m"), + call.body.system.some((block) => !!block.cache_control), false ); - assert.equal(call.body.system.at(-1).cache_control?.ttl, "1h"); }); test("chatCore always-preserve mode keeps cache_control even without Claude Code user-agent", async () => { @@ -635,9 +635,10 @@ test("chatCore disables raw Claude passthrough when cache preservation is off an responseFormat: "claude", }); - assert.equal(call.body.system[0].text.includes("You are Claude Code"), true); - assert.equal(call.body.system.at(-1).cache_control?.ttl, "1h"); + assert.equal(call.body.system[0].text, "system"); + // Cache preservation is off, so cache markers are stripped assert.equal(call.body.messages[0].content[0].cache_control, undefined); + // Tools disable flag is applied assert.equal("_disableToolPrefix" in call.body, false); });