Compare commits

...

4 Commits

Author SHA1 Message Date
Diego Rodrigues de Sa e Souza 028874fd05 Merge pull request #840 from diegosouzapw/release/v3.3.9
Build Electron Desktop App / Validate version (push) Failing after 33s
Build Electron Desktop App / Build Electron (macos-arm64) (push) Has been skipped
Build Electron Desktop App / Build Electron (linux) (push) Has been skipped
Build Electron Desktop App / Build Electron (macos-intel) (push) Has been skipped
Build Electron Desktop App / Build Electron (windows) (push) Has been skipped
Build Electron Desktop App / Create Release (push) Has been skipped
Build Electron Desktop App / Publish to npm (push) Has been skipped
chore(release): v3.3.9 — summary
2026-03-30 21:38:32 -03:00
diegosouzapw 6d366fe80f chore(release): v3.3.9 — custom provider key rotation fix 2026-03-30 21:33:21 -03:00
Diego Rodrigues de Sa e Souza 0924f767e9 Merge pull request #839 from diegosouzapw/fix/issue-815-custom-provider-key-rotation
fix: rotate extra api keys for custom providers (#815)
2026-03-30 21:30:56 -03:00
diegosouzapw 173b5a1cd1 fix: rotate extra api keys for custom providers (#815) 2026-03-30 21:13:50 -03:00
10 changed files with 51 additions and 36 deletions
+17 -4
View File
@@ -18,11 +18,24 @@ Fetches open feature request issues, analyzes each against the current codebase,
### 2. Fetch Open Feature Request Issues
// turbo
// turbo-all
- Run: `gh issue list --repo <owner>/<repo> --state open --limit 50 --json number,title,labels,body,comments,createdAt,author`
- Filter for issues that are feature requests (label `enhancement`/`feature`, or body describes new functionality, or previously classified as feature request)
- Sort by oldest first
**⚠️ CRITICAL**: The JSON output of `gh issue list` can be truncated by the tool, silently hiding issues and their comments. You MUST use the two-step approach below to guarantee **all** feature requests and their full conversations are fetched.
**Step 2a — Get Issue numbers only** (small output, never truncated):
- Run: `gh issue list --repo <owner>/<repo> --state open --labels "enhancement" --limit 500 --json number --jq '.[].number'`
- (Also run the same for `--labels "feature"` if they are separated, or filter all open issues if labels are not strictly used).
- This outputs one issue number per line. Count them and confirm total.
**Step 2b — Fetch full metadata & conversations for each Issue** (one call per issue):
- For each issue number from step 2a, run:
`gh issue view <NUMBER> --repo <owner>/<repo> --json number,title,labels,body,comments,createdAt,author`
- Read not just the body, but **ALL comments (`comments` array)** completely to understand the full context, agreements, and restrictions discussed by the community.
- You may batch these into parallel calls (up to 4 at a time).
- Filter for issues that are feature requests (if not already filtered by label).
- Sort by oldest first.
### 3. Analyze Each Feature Request
+8
View File
@@ -4,6 +4,14 @@
---
## [3.3.9] - 2026-03-31
### 🐛 Bug Fixes
- **Custom Provider Rotation:** Integrated `getRotatingApiKey` internally inside DefaultExecutor, ensuring `extraApiKeys` rotation triggers correctly for custom and compatible upstream providers (#815)
---
## [3.3.8] - 2026-03-30
### 🚀 Features
+2 -1
View File
@@ -1280,7 +1280,8 @@ OmniRoute v2.0 is built as an operational platform, not just a relay proxy.
| ----------------------------- | --------------------------------------------------------- |
| 🌐 **Deploy Anywhere** | Localhost, VPS, Docker, Cloud environments |
| 🚇 **Cloudflare Tunnel** 🆕 | One-click Quick Tunnel integration from the dashboard |
| 💾 **Cloud Sync** | Configuration sync via cloud worker |
| 🔑 **API Key Model Filtering** | Native /v1/models response filtered via assigned Bearer context roles |
| ⚡ **Smart Cache Bypass** | Configurable TTL heuristics and forced refetch controls |
| 🔄 **Backup/Restore** | Export/import and disaster recovery flows |
| 🧙 **Onboarding Wizard** | First-run guided setup |
| 🔧 **CLI Tools Dashboard** | One-click setup for popular coding tools |
+1 -1
View File
@@ -1,7 +1,7 @@
openapi: 3.1.0
info:
title: OmniRoute API
version: 3.3.8
version: 3.3.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,
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "omniroute-desktop",
"version": "3.3.7",
"version": "3.3.9",
"description": "OmniRoute Desktop Application",
"main": "main.js",
"author": {
+17 -8
View File
@@ -1,6 +1,7 @@
import { BaseExecutor } from "./base.ts";
import { PROVIDERS, OAUTH_ENDPOINTS } from "../config/constants.ts";
import { getAccessToken } from "../services/tokenRefresh.ts";
import { getRotatingApiKey } from "../services/apiKeyRotator.ts";
export class DefaultExecutor extends BaseExecutor {
constructor(provider) {
@@ -41,15 +42,23 @@ export class DefaultExecutor extends BaseExecutor {
buildHeaders(credentials, stream = true) {
const headers = { "Content-Type": "application/json", ...this.config.headers };
// T07: resolve extra keys round-robin locally since DefaultExecutor overrides BaseExecutor buildHeaders
const extraKeys =
(credentials.providerSpecificData?.extraApiKeys as string[] | undefined) ?? [];
const effectiveKey =
extraKeys.length > 0 && credentials.connectionId && credentials.apiKey
? getRotatingApiKey(credentials.connectionId, credentials.apiKey, extraKeys)
: credentials.apiKey;
switch (this.provider) {
case "gemini":
credentials.apiKey
? (headers["x-goog-api-key"] = credentials.apiKey)
effectiveKey
? (headers["x-goog-api-key"] = effectiveKey)
: (headers["Authorization"] = `Bearer ${credentials.accessToken}`);
break;
case "claude":
credentials.apiKey
? (headers["x-api-key"] = credentials.apiKey)
effectiveKey
? (headers["x-api-key"] = effectiveKey)
: (headers["Authorization"] = `Bearer ${credentials.accessToken}`);
break;
case "glm":
@@ -58,12 +67,12 @@ export class DefaultExecutor extends BaseExecutor {
case "kimi-coding-apikey":
case "minimax":
case "minimax-cn":
headers["x-api-key"] = credentials.apiKey || credentials.accessToken;
headers["x-api-key"] = effectiveKey || credentials.accessToken;
break;
default:
if (this.provider?.startsWith?.("anthropic-compatible-")) {
if (credentials.apiKey) {
headers["x-api-key"] = credentials.apiKey;
if (effectiveKey) {
headers["x-api-key"] = effectiveKey;
} else if (credentials.accessToken) {
headers["Authorization"] = `Bearer ${credentials.accessToken}`;
}
@@ -71,7 +80,7 @@ export class DefaultExecutor extends BaseExecutor {
headers["anthropic-version"] = "2023-06-01";
}
} else {
headers["Authorization"] = `Bearer ${credentials.apiKey || credentials.accessToken}`;
headers["Authorization"] = `Bearer ${effectiveKey || credentials.accessToken}`;
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@omniroute/open-sse",
"version": "3.3.7",
"version": "3.3.9",
"description": "Express SSE sidecar for OmniRoute — handles streaming, protocol translation, and provider orchestration",
"type": "module",
"main": "index.js",
+3 -3
View File
@@ -1,12 +1,12 @@
{
"name": "omniroute",
"version": "3.3.7",
"version": "3.3.9",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "omniroute",
"version": "3.3.7",
"version": "3.3.9",
"hasInstallScript": true,
"license": "MIT",
"workspaces": [
@@ -20324,7 +20324,7 @@
},
"open-sse": {
"name": "@omniroute/open-sse",
"version": "3.3.7"
"version": "3.3.9"
}
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "omniroute",
"version": "3.3.8",
"version": "3.3.9",
"description": "Smart AI Router with auto fallback — route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.",
"type": "module",
"bin": {
-16
View File
@@ -1,16 +0,0 @@
## [3.2.8] - 2026-03-29
### ✨ Enhancements & Refactoring
- **Docker Auto-Update UI** — Integrated a detached background update process for Docker Compose deployments. The Dashboard UI now seamlessly tracks update lifecycle events combining JSON REST responses with SSE streaming progress overlays for robust cross-environment reliability.
- **Cache Analytics** — Repaired zero-metrics visualization mapping by migrating Semantic Cache telemetry logs directly into the centralized tracking SQLite module.
### 🐛 Bug Fixes
- **Authentication Logic** — Fixed a bug where saving dashboard settings or adding models failed with a 401 Unauthorized error when `requireLogin` was disabled. API endpoints now correctly evaluate the global authentication toggle. Resolved global redirection by reactivating `src/middleware.ts`.
- **CLI Tool Detection (Windows)** — Prevented fatal initialization exceptions during CLI environment detection by catching `cross-spawn` ENOENT errors correctly. Adds explicit detection paths for `\AppData\Local\droid\droid.exe`.
- **Codex Native Passthrough** — Normalized model translation parameters preventing context poisoning in proxy pass-through mode, enforcing generic `store: false` constraints explicitly for all Codex-originated requests.
- **SSE Token Reporting** — Normalized provider tool-call chunk `finish_reason` detection, fixing 0% Usage analytics for stream-only responses missing strict `<DONE>` indicators.
- **DeepSeek <think> Tags** — Implemented an explicit `<think>` extraction mapping inside `responsesHandler.ts`, ensuring DeepSeek reasoning streams map equivalently to native Anthropic `<thinking>` structures.
---