github diegosouzapw/OmniRoute v3.0.5
Release v3.0.5

latest releases: v3.0.7, v3.0.6
7 hours ago

Changelog

[Unreleased]


[3.0.5] — 2026-03-25

✨ New Features

  • Limits UI: Added tag grouping feature to the connections dashboard to improve visual organization for accounts with custom tags.

[3.0.4] — 2026-03-25

🐛 Bug Fixes

  • Streaming: Fixed TextDecoder state corruption inside combo sanitize TransformStream which caused SSE garbled output matching multibyte characters (PR #614)
  • Providers UI: Safely render HTML tags inside provider connection error tooltips using dangerouslySetInnerHTML
  • Proxy Settings: Added missing username and password payload body properties allowing authenticated proxies to be successfully verified from the Dashboard.
  • Provider API: Bound soft exception returns to getCodexUsage preventing API HTTP 500 failures when token fetch fails

[3.0.3] — 2026-03-25

✨ New Features

  • Auto-Sync Models: Added a UI toggle and sync-models endpoint to automatically synchronise model lists per provider using a scheduled interval scheduler (PR #597)

🐛 Bug Fixes

  • Timeouts: Elevated default proxies FETCH_TIMEOUT_MS and STREAM_IDLE_TIMEOUT_MS to 10 minutes to properly support deep reasoning models (like o1) without aborting requests (Fixes #609)
  • CLI Tool Detection: Improved cross-platform detection handling NVM paths, Windows PATHEXT (preventing .cmd wrappers issue), and custom NPM prefixes (PR #598)
  • Streaming Logs: Implemented tool_calls delta accumulation in streaming response logs so function calls are tracked and persisted accurately in DB (PR #603)
  • Model Catalog: Removed auth exemption, properly hiding comfyui and sdwebui models when no provider is explicitly configured (PR #599)

🌐 Translations

  • cs: Improved Czech translation strings across the app (PR #601)

[3.0.2] — 2026-03-25

🚀 Enhancements & Features

feat(ui): Connection Tag Grouping

  • Added a Tag/Group field to EditConnectionModal (stored in providerSpecificData.tag) without requiring DB schema migrations.
  • Connections in the provider view now dynamically group by tag with visual dividers.
  • Untagged connections appear first without a header, followed by tagged groups in alphabetical order.
  • The tag grouping automatically applies to the Codex/Copilot/Antigravity Limits section since toggles exist inside connection rows.

🐛 Bug Fixes

fix(ui): Proxy Management UI Stabilization

  • Missing badges on connection cards: Fixed by using resolveProxyForConnection() rather than static mapping.
  • Test Connection disabled in saved mode: Enabled the Test button by resolving proxy config from the saved list.
  • Config Modal freezing: Added onClose() calls after save/clear to prevent the UI from freezing.
  • Double usage counting: ProxyRegistryManager now loads usage eagerly on mount with deduplication by scope + scopeId. Usage counts were replaced with a Test button displaying IP/latency inline.

fix(translator): function_call prefix stripping

  • Repaired an incomplete fix from PR #607 where only tool_use blocks stripped Claude's proxy_ tool prefix. Now, clients using the OpenAI Responses API format will also correctly receive tool tools without the proxy_ prefix.

[3.0.1] — 2026-03-25

🔧 Hotfix Patch — Critical Bug Fixes

Three critical regressions reported by users after the v3.0.0 launch have been resolved.

fix(translator): strip proxy_ prefix in non-streaming Claude responses (#605)

The proxy_ prefix added by Claude OAuth was only stripped from streaming responses. In non-streaming mode, translateNonStreamingResponse had no access to the toolNameMap, causing clients to receive mangled tool names like proxy_read_file instead of read_file.

Fix: Added optional toolNameMap parameter to translateNonStreamingResponse and applied prefix stripping in the Claude tool_use block handler. chatCore.ts now passes the map through.

fix(validation): add LongCat specialty validator to skip /models probe (#592)

LongCat AI does not expose GET /v1/models. The generic validateOpenAICompatibleProvider validator fell through to a chat-completions fallback only if validationModelId was set, which LongCat doesn't configure. This caused provider validation to fail with a misleading error on add/save.

Fix: Added longcat to the specialty validators map, probing /chat/completions directly and treating any non-auth response as a pass.

fix(translator): normalize object tool schemas for Anthropic (#595)

MCP tools (e.g. pencil, computer_use) forward tool definitions with {type:"object"} but without a properties field. Anthropic's API rejects these with: object schema missing properties.

Fix: In openai-to-claude.ts, inject properties: {} as a safe default when type is "object" and properties is absent.


🔀 Community PRs Merged (2)

PR Author Summary
#589 @flobo3 docs(i18n): fix Russian translation for Playground and Testbed
#591 @rdself fix(ui): improve Provider Limits light mode contrast and plan tier display

✅ Issues Resolved

#592 #595 #605


🧪 Tests

  • 926 tests, 0 failures (unchanged from v3.0.0)

[3.0.0] — 2026-03-24

🎉 OmniRoute v3.0.0 — The Free AI Gateway, Now with 67+ Providers

The biggest release ever. From 36 providers in v2.9.5 to 67+ providers in v3.0.0 — with MCP Server, A2A Protocol, auto-combo engine, Provider Icons, Registered Keys API, 926 tests, and contributions from 12 community members across 10 merged PRs.

Consolidated from v3.0.0-rc.1 through rc.17 (17 release candidates over 3 days of intense development).


🆕 New Providers (+31 since v2.9.5)

Provider Alias Tier Notes
OpenCode Zen opencode-zen Free 3 models via opencode.ai/zen/v1 (PR #530 by @kang-heewon)
OpenCode Go opencode-go Paid 4 models via opencode.ai/zen/go/v1 (PR #530 by @kang-heewon)
LongCat AI lc Free 50M tokens/day (Flash-Lite) + 500K/day (Chat/Thinking) during public beta
Pollinations AI pol Free No API key needed — GPT-5, Claude, Gemini, DeepSeek V3, Llama 4 (1 req/15s)
Cloudflare Workers AI cf Free 10K Neurons/day — ~150 LLM responses or 500s Whisper audio, edge inference
Scaleway AI scw Free 1M free tokens for new accounts — EU/GDPR compliant (Paris)
AI/ML API aiml Free $0.025/day free credits — 200+ models via single endpoint
Puter AI pu Free 500+ models (GPT-5, Claude Opus 4, Gemini 3 Pro, Grok 4, DeepSeek V3)
Alibaba Cloud (DashScope) ali Paid International + China endpoints via alicode/alicode-intl
Alibaba Coding Plan bcp Paid Alibaba Model Studio with Anthropic-compatible API
Kimi Coding (API Key) kmca Paid Dedicated API-key-based Kimi access (separate from OAuth)
MiniMax Coding minimax Paid International endpoint
MiniMax (China) minimax-cn Paid China-specific endpoint
Z.AI (GLM-5) zai Paid Zhipu AI next-gen GLM models
Vertex AI vertex Paid Google Cloud — Service Account JSON or OAuth access_token
Ollama Cloud ollamacloud Paid Ollama's hosted API service
Synthetic synthetic Paid Passthrough models gateway
Kilo Gateway kg Paid Passthrough models gateway
Perplexity Search pplx-search Paid Dedicated search-grounded endpoint
Serper Search serper-search Paid Web search API integration
Brave Search brave-search Paid Brave Search API integration
Exa Search exa-search Paid Neural search API integration
Tavily Search tavily-search Paid AI search API integration
NanoBanana nb Paid Image generation API
ElevenLabs el Paid Text-to-speech voice synthesis
Cartesia cartesia Paid Ultra-fast TTS voice synthesis
PlayHT playht Paid Voice cloning and TTS
Inworld inworld Paid AI character voice chat
SD WebUI sdwebui Self-hosted Stable Diffusion local image generation
ComfyUI comfyui Self-hosted ComfyUI local workflow node-based generation
GLM Coding glm Paid BigModel/Zhipu coding-specific endpoint

Total: 67+ providers (4 Free, 8 OAuth, 55 API Key) + unlimited OpenAI/Anthropic-Compatible custom providers.


✨ Major Features

🔑 Registered Keys Provisioning API (#464)

Auto-generate and issue OmniRoute API keys programmatically with per-provider and per-account quota enforcement.

Endpoint Method Description
/api/v1/registered-keys POST Issue a new key — raw key returned once only
/api/v1/registered-keys GET List registered keys (masked)
/api/v1/registered-keys/{id} GET/DELETE Get metadata / Revoke
/api/v1/quotas/check GET Pre-validate quota before issuing
/api/v1/providers/{id}/limits GET/PUT Configure per-provider issuance limits
/api/v1/accounts/{id}/limits GET/PUT Configure per-account issuance limits
/api/v1/issues/report POST Report quota events to GitHub Issues

Security: Keys stored as SHA-256 hashes. Raw key shown once on creation, never retrievable again.

🎨 Provider Icons via @lobehub/icons (#529)

130+ provider logos using @lobehub/icons React components (SVG). Fallback chain: Lobehub SVG → existing PNG → generic icon. Applied across Dashboard, Providers, and Agents pages with standardized ProviderIcon component.

🔄 Model Auto-Sync Scheduler (#488)

Auto-refreshes model lists for connected providers every 24 hours. Runs on server startup. Configurable via MODEL_SYNC_INTERVAL_HOURS.

🔀 Per-Model Combo Routing (#563)

Map model name patterns (glob) to specific combos for automatic routing:

  • claude-sonnet* → code-combo, gpt-4o* → openai-combo, gemini-* → google-combo
  • New model_combo_mappings table with glob-to-regex matching
  • Dashboard UI section: "Model Routing Rules" with inline add/edit/toggle/delete

🧭 API Endpoints Dashboard

Interactive catalog, webhooks management, OpenAPI viewer — all in one tabbed page at /dashboard/endpoint.

🔍 Web Search Providers

5 new search provider integrations: Perplexity Search, Serper, Brave Search, Exa, Tavily — enabling grounded AI responses with real-time web data.

📊 Search Analytics

New tab in /dashboard/analytics — provider breakdown, cache hit rate, cost tracking. API: GET /api/v1/search/analytics.

🛡️ Per-API-Key Rate Limits (#452)

max_requests_per_day and max_requests_per_minute columns with in-memory sliding-window enforcement returning HTTP 429.

🎵 Media Playground

Full media generation playground at /dashboard/media: Image Generation, Video, Music, Audio Transcription (2GB upload limit), and Text-to-Speech.


🔒 Security & CI/CD

  • CodeQL remediation — Fixed 10+ alerts: 6 polynomial-redos, 1 insecure-randomness (Math.random()crypto.randomUUID()), 1 shell-command-injection
  • Route validation — Zod schemas + validateBody() on 176/176 API routes — CI enforced
  • CVE fix — dompurify XSS vulnerability (GHSA-v2wj-7wpq-c8vv) resolved via npm overrides
  • Flatted — Bumped 3.3.3 → 3.4.2 (CWE-1321 prototype pollution)
  • Docker — Upgraded docker/setup-buildx-action v3 → v4

🐛 Bug Fixes (40+)

OAuth & Auth

  • #537 — Gemini CLI OAuth: clear actionable error when GEMINI_OAUTH_CLIENT_SECRET missing in Docker
  • #549 — CLI settings routes now resolve real API key from keyId (not masked strings)
  • #574 — Login no longer freezes after skipping wizard password setup
  • #506 — Cross-platform machineId rewritten (Windows REG.exe → macOS ioreg → Linux → hostname fallback)

Providers & Routing

  • #536 — LongCat AI: fixed baseUrl and authHeader
  • #535 — Pinned model override: body.model correctly set to pinnedModel
  • #570 — Unprefixed Claude models now resolve to Anthropic provider
  • #585<omniModel> internal tags no longer leak to clients in SSE streaming
  • #493 — Custom provider model naming no longer mangled by prefix stripping
  • #490 — Streaming + context cache protection via TransformStream injection
  • #511<omniModel> tag injected into first content chunk (not after [DONE])

CLI & Tools

  • #527 — Claude Code + Codex loop: tool_result blocks now converted to text
  • #524 — OpenCode config saved correctly (XDG_CONFIG_HOME, TOML format)
  • #522 — API Manager: removed misleading "Copy masked key" button
  • #546--version returning unknown on Windows (PR by @k0valik)
  • #544 — Secure CLI tool detection via known installation paths (PR by @k0valik)
  • #510 — Windows MSYS2/Git-Bash paths normalized automatically
  • #492 — CLI detects mise/nvm-managed Node when app/server.js missing

Streaming & SSE

  • PR #587 — Revert resolveDataDir import in responsesTransformer for Cloudflare Workers compat (@k0valik)
  • PR #495 — Bottleneck 429 infinite wait: drop waiting jobs on rate limit (@xandr0s)
  • #483 — Stop trailing data: null after [DONE] signal
  • #473 — Zombie SSE streams: timeout reduced 300s → 120s for faster fallback

Media & Transcription

  • Transcription — Deepgram video/mp4audio/mp4 MIME mapping, auto language detection, punctuation
  • TTS[object Object] error display fixed for ElevenLabs-style nested errors
  • Upload limits — Media transcription increased to 2GB (nginx client_max_body_size 2g + maxDuration=300)

🔧 Infrastructure & Improvements

Sub2api Gap Analysis (T01–T15 + T23–T42)

  • T01requested_model column in call logs (migration 009)
  • T02 — Strip empty text blocks from nested tool_result.content
  • T03 — Parse x-codex-5h-* / x-codex-7d-* quota headers
  • T04X-Session-Id header for external sticky routing
  • T05 — Rate-limit DB persistence with dedicated API
  • T06 — Account deactivated → permanent block (1-year cooldown)
  • T07 — X-Forwarded-For IP validation (extractClientIp())
  • T08 — Per-API-key session limits with sliding-window enforcement
  • T09 — Codex vs Spark rate-limit scopes (separate pools)
  • T10 — Credits exhausted → distinct 1h cooldown fallback
  • T11max reasoning effort → 131072 budget tokens
  • T12 — MiniMax M2.7 pricing entries
  • T13 — Stale quota display fix (reset window awareness)
  • T14 — Proxy fast-fail TCP check (≤2s, cached 30s)
  • T15 — Array content normalization for Anthropic
  • T23 — Intelligent quota reset fallback (header extraction)
  • T24503 cooldown + 406 mapping
  • T25 — Provider validation fallback
  • T29 — Vertex AI Service Account JWT auth
  • T33 — Thinking level to budget conversion
  • T36403 vs 429 error classification
  • T38 — Centralized model specifications (modelSpecs.ts)
  • T39 — Endpoint fallback for fetchAvailableModels
  • T41 — Background task auto-redirect to flash models
  • T42 — Image generation aspect ratio mapping

Other Improvements

  • Per-model upstream custom headers — via configuration UI (PR #575 by @zhangqiang8vip)
  • Model context length — configurable in model metadata (PR #578 by @hijak)
  • Model prefix stripping — option to remove provider prefix from model names (PR #582 by @jay77721)
  • Gemini CLI deprecation — marked deprecated with Google OAuth restriction warning
  • YAML parser — replaced custom parser with js-yaml for correct OpenAPI spec parsing
  • ZWS v5 — HMR leak fix (485 DB connections → 1, memory 2.4GB → 195MB)
  • Log export — New JSON export button on dashboard with time range dropdown
  • Update notification banner — dashboard homepage shows when new versions are available

🌐 i18n & Documentation

  • 30 languages at 100% parity — 2,788 missing keys synced
  • Czech — Full translation: 22 docs, 2,606 UI strings (PR by @zen0bit)
  • Chinese (zh-CN) — Complete retranslation (PR by @only4copilot)
  • VM Deployment Guide — Translated to English as source document
  • API Reference — Added /v1/embeddings and /v1/audio/speech endpoints
  • Provider count — Updated from 36+/40+/44+ to 67+ across README and all 30 i18n READMEs

🔀 Community PRs Merged (10)

PR Author Summary
#587 @k0valik fix(sse): revert resolveDataDir import for Cloudflare Workers compat
#582 @jay77721 feat(proxy): model name prefix stripping option
#581 @jay77721 fix(npm): link electron-release to npm-publish workflow
#578 @hijak feat: configurable context length in model metadata
#575 @zhangqiang8vip feat: per-model upstream headers, compat PATCH, chat alignment
#562 @coobabm fix: MCP session management, Claude passthrough, detectFormat
#561 @zen0bit fix(i18n): Czech translation corrections
#555 @k0valik fix(sse): centralized resolveDataDir() for path resolution
#546 @k0valik fix(cli): --version returning unknown on Windows
#544 @k0valik fix(cli): secure CLI tool detection via installation paths
#542 @rdself fix(ui): light mode contrast CSS theme variables
#530 @kang-heewon feat: OpenCode Zen + Go providers with OpencodeExecutor
#512 @zhangqiang8vip feat: per-protocol model compatibility (compatByProtocol)
#497 @zhangqiang8vip fix: dev-mode HMR resource leaks (ZWS v5)
#495 @xandr0s fix: Bottleneck 429 infinite wait (drop waiting jobs)
#494 @zhangqiang8vip feat: MiniMax developer→system role fix
#480 @prakersh fix: stream flush usage extraction
#479 @prakersh feat: Codex 5.3/5.4 and Anthropic pricing entries
#475 @only4copilot feat(i18n): improved Chinese translation

Thank you to all contributors! 🙏


📋 Issues Resolved (50+)

#452 #458 #462 #464 #466 #473 #474 #481 #483 #487 #488 #489 #490 #491 #492 #493 #506 #508 #509 #510 #511 #513 #520 #521 #522 #524 #525 #527 #529 #531 #532 #535 #536 #537 #541 #546 #549 #563 #570 #574 #585


🧪 Tests

  • 926 tests, 0 failures (up from 821 in v2.9.5)
  • +105 new tests covering: model-combo mappings, registered keys, OpencodeExecutor, Bailian provider, route validation, error classification, aspect ratio mapping, and more

📦 Database Migrations

Migration Description
008 registered_keys, provider_key_limits, account_key_limits tables
009 requested_model column in call_logs
010 model_combo_mappings table for per-model combo routing

⬆️ Upgrading from v2.9.5

# npm
npm install -g omniroute@3.0.0

# Docker
docker pull diegosouzapw/omniroute:3.0.0

# Migrations run automatically on first startup

Breaking changes: None. All existing configurations, combos, and API keys are preserved.
Database migrations 008-010 run automatically on startup.


[3.0.0-rc.17] — 2026-03-24

🔒 Security & CI/CD

  • CodeQL remediation — Fixed 10+ alerts:
    • 6 polynomial-redos in provider.ts / chatCore.ts (replaced (?:^|/) alternation patterns with segment-based matching)
    • 1 insecure-randomness in acp/manager.ts (Math.random()crypto.randomUUID())
    • 1 shell-command-injection in prepublish.mjs (JSON.stringify() path escaping)
  • Route validation — Added Zod schemas + validateBody() to 5 routes missing validation:
    • model-combo-mappings (POST, PUT), webhooks (POST, PUT), openapi/try (POST)
    • CI check:route-validation:t06 now passes: 176/176 routes validated

🐛 Bug Fixes

  • #585<omniModel> internal tags no longer leak to clients in SSE responses. Added outbound sanitization TransformStream in combo.ts

⚙️ Infrastructure

  • Docker — Upgraded docker/setup-buildx-action from v3 → v4 (Node.js 20 deprecation fix)
  • CI cleanup — Deleted 150+ failed/cancelled workflow runs

🧪 Tests

  • Test suite: 926 tests, 0 failures (+3 new)

[3.0.0-rc.16] — 2026-03-24

✨ New Features

  • Increased media transcription limits
  • Added Model Context Length to registry metadata
  • Added per-model upstream custom headers via configuration UI
  • Fixed multiple bugs, Zod valiadation for patches, and resolved various community issues.

[3.0.0-rc.15] — 2026-03-24

✨ New Features

  • #563 — Per-model Combo Routing: map model name patterns (glob) to specific combos for automatic routing
    • New model_combo_mappings table (migration 010) with pattern, combo_id, priority, enabled
    • resolveComboForModel() DB function with glob-to-regex matching (case-insensitive, * and ? wildcards)
    • getComboForModel() in model.ts: augments getCombo() with model-pattern fallback
    • chat.ts: routing decision now checks model-combo mappings before single-model handling
    • API: GET/POST /api/model-combo-mappings, GET/PUT/DELETE /api/model-combo-mappings/:id
    • Dashboard: "Model Routing Rules" section added to Combos page with inline add/edit/toggle/delete
    • Examples: claude-sonnet* → code-combo, gpt-4o* → openai-combo, gemini-* → google-combo

🌐 i18n

  • Full i18n Sync: 2,788 missing keys added across 30 language files — all languages now at 100% parity with en.json
  • Agents page i18n: OpenCode Integration section fully internationalized (title, description, scanning, download labels)
  • 6 new keys added to agents namespace for OpenCode section

🎨 UI/UX

  • Provider Icons: 16 missing provider icons added (3 copied, 2 downloaded, 11 SVG created)
  • SVG fallback: ProviderIcon component updated with 4-tier strategy: Lobehub → PNG → SVG → Generic icon
  • Agents fingerprinting: Synced with CLI tools — added droid, openclaw, copilot, opencode to fingerprint list (14 total)

🔒 Security

  • CVE fix: Resolved dompurify XSS vulnerability (GHSA-v2wj-7wpq-c8vv) via npm overrides forcing dompurify@^3.3.2
  • npm audit now reports 0 vulnerabilities

🧪 Tests

  • Test suite: 923 tests, 0 failures (+15 new model-combo mapping tests)

[3.0.0-rc.14] — 2026-03-23

🔀 Community PRs Merged

PR Author Summary
#562 @coobabm fix(ux): MCP session management, Claude passthrough normalization, OAuth modal, detectFormat
#561 @zen0bit fix(i18n): Czech translation corrections — HTTP method names and documentation updates

🧪 Tests

  • Test suite: 908 tests, 0 failures

[3.0.0-rc.13] — 2026-03-23

🔧 Bug Fixes

  • config: resolve real API key from keyId in CLI settings routes (codex-settings, droid-settings, kilo-settings) to prevent writing masked strings (#549)

[3.0.0-rc.12] — 2026-03-23

🔀 Community PRs Merged

PR Author Summary
#546 @k0valik fix(cli): --version returning unknown on Windows — use JSON.parse(readFileSync) instead of ESM import
#555 @k0valik fix(sse): centralized resolveDataDir() for path resolution in credentials, autoCombo, responses logger, and request logger
#544 @k0valik fix(cli): secure CLI tool detection via known installation paths (8 tools) with symlink validation, file-type checks, size bounds, minimal env in healthcheck
#542 @rdself fix(ui): improve light mode contrast — add missing CSS theme variables (bg-primary, bg-subtle, text-primary) and fix dark-only colors in log detail

🔧 Bug Fixes

  • TDZ fix in cliRuntime.tsvalidateEnvPath was used before initialization at module startup by getExpectedParentPaths(). Reordered declarations to fix ReferenceError.
  • Build fixes — Added pino and pino-pretty to serverExternalPackages to prevent Turbopack from breaking Pino's internal worker loading.

🧪 Tests

  • Test suite: 905 tests, 0 failures

[3.0.0-rc.10] — 2026-03-23

🔧 Bug Fixes

  • #509 / #508 — Electron build regression: downgraded Next.js from 16.1.x to 16.0.10 to eliminate Turbopack module-hashing instability that caused blank screens in the Electron desktop bundle.
  • Unit test fixes — Corrected two stale test assertions (nanobanana-image-handler aspect ratio/resolution, thinking-budget Gemini thinkingConfig field mapping) that had drifted after recent implementation changes.
  • #541 — Responded to user feedback about installation complexity; no code changes required.

[3.0.0-rc.9] — 2026-03-23

✨ New Features

  • T29 — Vertex AI SA JSON Executor: implemented using the jose library to handle JWT/Service Account auth, along with configurable regions in the UI and automatic partner model URL building.
  • T42 — Image generation aspect ratio mapping: created sizeMapper logic for generic OpenAI formats (size), added native imagen3 handling, and updated NanoBanana endpoints to utilize mapped aspect ratios automatically.
  • T38 — Centralized model specifications: modelSpecs.ts created for limits and parameters per model.

🔧 Improvements

  • T40 — OpenCode CLI tools integration: native opencode-zen and opencode-go integration completed in earlier PR.

[3.0.0-rc.8] — 2026-03-23

🔧 Bug Fixes & Improvements (Fallback, Quota & Budget)

  • T24503 cooldown await fix + 406 mapping: mapped 406 Not Acceptable to 503 Service Unavailable with proper cooldown intervals.
  • T25 — Provider validation fallback: graceful fallback to standard validation models when a specific validationModelId is not present.
  • T36403 vs 429 provider handling refinement: extracted into errorClassifier.ts to properly segregate hard permissions failures (403) from rate limits (429).
  • T39 — Endpoint Fallback for fetchAvailableModels: implemented a tri-tier mechanism (/models -> /v1/models -> local generic catalog) + list_models_catalog MCP tool updates to reflect source and warning.
  • T33 — Thinking level to budget conversion: translates qualitative thinking levels into precise budget allocations.
  • T41 — Background task auto redirect: routes heavy background evaluation tasks to flash/efficient models automatically.
  • T23 — Intelligent quota reset fallback: accurately extracts x-ratelimit-reset / retry-after header values or maps static cooldowns.

[3.0.0-rc.7] — 2026-03-23 (What's New vs v2.9.5 — will be released as v3.0.0)

Upgrade from v2.9.5: 16 issues resolved · 2 community PRs merged · 2 new providers · 7 new API endpoints · 3 new features · DB migration 008+009 · 832 tests passing · 15 sub2api gap improvements (T01–T15 complete).

🆕 New Providers

Provider Alias Tier Notes
OpenCode Zen opencode-zen Free 3 models via opencode.ai/zen/v1 (PR #530 by @kang-heewon)
OpenCode Go opencode-go Paid 4 models via opencode.ai/zen/go/v1 (PR #530 by @kang-heewon)

Both providers use the new OpencodeExecutor with multi-format routing (/chat/completions, /messages, /responses, /models/{model}:generateContent).


✨ New Features

🔑 Registered Keys Provisioning API (#464)

Auto-generate and issue OmniRoute API keys programmatically with per-provider and per-account quota enforcement.

Endpoint Method Description
/api/v1/registered-keys POST Issue a new key — raw key returned once only
/api/v1/registered-keys GET List registered keys (masked)
/api/v1/registered-keys/{id} GET Get key metadata
/api/v1/registered-keys/{id} DELETE Revoke a key
/api/v1/registered-keys/{id}/revoke POST Revoke (for clients without DELETE support)
/api/v1/quotas/check GET Pre-validate quota before issuing
/api/v1/providers/{id}/limits GET/PUT Configure per-provider issuance limits
/api/v1/accounts/{id}/limits GET/PUT Configure per-account issuance limits
/api/v1/issues/report POST Report quota events to GitHub Issues

DB — Migration 008: Three new tables: registered_keys, provider_key_limits, account_key_limits.
Security: Keys stored as SHA-256 hashes. Raw key shown once on creation, never retrievable again.
Quota types: maxActiveKeys, dailyIssueLimit, hourlyIssueLimit per provider and per account.
Idempotency: idempotency_key field prevents duplicate issuance. Returns 409 IDEMPOTENCY_CONFLICT if key was already used.
Budget per key: dailyBudget / hourlyBudget — limits how many requests a key can route per window.
GitHub reporting: Optional. Set GITHUB_ISSUES_REPO + GITHUB_ISSUES_TOKEN to auto-create GitHub issues on quota exceeded or issuance failures.

🎨 Provider Icons — @lobehub/icons (#529)

All provider icons in the dashboard now use @lobehub/icons React components (130+ providers with SVG).
Fallback chain: Lobehub SVG → existing /providers/{id}.png → generic icon. Uses a proper React ErrorBoundary pattern.

🔄 Model Auto-Sync Scheduler (#488)

OmniRoute now automatically refreshes model lists for connected providers every 24 hours.

  • Runs on server startup via the existing /api/sync/initialize hook
  • Configurable via MODEL_SYNC_INTERVAL_HOURS environment variable
  • Covers 16 major providers
  • Records last sync time in the settings database

🔧 Bug Fixes

OAuth & Auth

  • #537 — Gemini CLI OAuth: Clear actionable error when GEMINI_OAUTH_CLIENT_SECRET is missing in Docker/self-hosted deployments. Previously showed cryptic client_secret is missing from Google. Now provides specific docker-compose.yml and ~/.omniroute/.env instructions.

Providers & Routing

  • #536 — LongCat AI: Fixed baseUrl (api.longcat.chat/openai) and authHeader (Authorization: Bearer).
  • #535 — Pinned model override: body.model is now correctly set to pinnedModel when context-cache protection is active.
  • #532 — OpenCode Go key validation: Now uses the zen/v1 test endpoint (testKeyBaseUrl) — same key works for both tiers.

CLI & Tools

  • #527 — Claude Code + Codex loop: tool_result blocks are now converted to text instead of dropped, stopping infinite tool-result loops.
  • #524 — OpenCode config save: Added saveOpenCodeConfig() handler (XDG_CONFIG_HOME aware, writes TOML).
  • #521 — Login stuck: Login no longer freezes after skipping password setup — redirects correctly to onboarding.
  • #522 — API Manager: Removed misleading "Copy masked key" button (replaced with a lock icon tooltip).
  • #532 — OpenCode Go config: Guide settings handler now handles opencode toolId.

Developer Experience

  • #489 — Antigravity: Missing googleProjectId returns a structured 422 error with reconnect guidance instead of a cryptic crash.
  • #510 — Windows paths: MSYS2/Git-Bash paths (/c/Program Files/...) are now normalized to C:\\Program Files\\... automatically.
  • #492 — CLI startup: omniroute CLI now detects mise/nvm-managed Node when app/server.js is missing and shows targeted fix instructions.

📖 Documentation Updates

  • #513 — Docker password reset: INITIAL_PASSWORD env var workaround documented
  • #520 — pnpm: pnpm approve-builds better-sqlite3 step documented

✅ Issues Resolved in v3.0.0

#464 #488 #489 #492 #510 #513 #520 #521 #522 #524 #527 #529 #532 #535 #536 #537


🔀 Community PRs Merged

PR Author Summary
#530 @kang-heewon OpenCode Zen + Go providers with OpencodeExecutor and improved tests

[3.0.0-rc.7] - 2026-03-23

🔧 Improvements (sub2api Gap Analysis — T05, T08, T09, T13, T14)

  • T05 — Rate-limit DB persistence: setConnectionRateLimitUntil(), isConnectionRateLimited(), getRateLimitedConnections() in providers.ts. The existing rate_limited_until column is now exposed as a dedicated API — OAuth token refresh must NOT touch this field to prevent rate-limit loops.
  • T08 — Per-API-key session limit: max_sessions INTEGER DEFAULT 0 added to api_keys via auto-migration. sessionManager.ts gains registerKeySession(), unregisterKeySession(), checkSessionLimit(), and getActiveSessionCountForKey(). Callers in chatCore.js can enforce the limit and decrement on req.close.
  • T09 — Codex vs Spark rate-limit scopes: getCodexModelScope() and getCodexRateLimitKey() in codex.ts. Standard models (gpt-5.x-codex, codex-mini) get scope "codex"; spark models (codex-spark*) get scope "spark". Rate-limit keys should be ${accountId}:${scope} so exhausting one pool doesn't block the other.
  • T13 — Stale quota display fix: getEffectiveQuotaUsage(used, resetAt) returns 0 when the reset window has passed; formatResetCountdown(resetAt) returns a human-readable countdown string (e.g. "2h 35m"). Both exported from providers.ts + localDb.ts for dashboard consumption.
  • T14 — Proxy fast-fail: new src/lib/proxyHealth.ts with isProxyReachable(proxyUrl, timeoutMs=2000) (TCP check, ≤2s instead of 30s timeout), getCachedProxyHealth(), invalidateProxyHealth(), and getAllProxyHealthStatuses(). Results cached 30s by default; configurable via PROXY_FAST_FAIL_TIMEOUT_MS / PROXY_HEALTH_CACHE_TTL_MS.

🧪 Tests

  • Test suite: 832 tests, 0 failures

[3.0.0-rc.6] - 2026-03-23

🔧 Bug Fixes & Improvements (sub2api Gap Analysis — T01–T15)

  • T01requested_model column in call_logs (migration 009): track which model the client originally requested vs the actual routed model. Enables fallback rate analytics.
  • T02 — Strip empty text blocks from nested tool_result.content: prevents Anthropic 400 errors (text content blocks must be non-empty) when Claude Code chains tool results.
  • T03 — Parse x-codex-5h-* / x-codex-7d-* headers: parseCodexQuotaHeaders() + getCodexResetTime() extract Codex quota windows for precise cooldown scheduling instead of generic 5-min fallback.
  • T04X-Session-Id header for external sticky routing: extractExternalSessionId() in sessionManager.ts reads x-session-id / x-omniroute-session headers with ext: prefix to avoid collision with internal SHA-256 session IDs. Nginx-compatible (hyphenated header).
  • T06 — Account deactivated → permanent block: isAccountDeactivated() in accountFallback.ts detects 401 deactivation signals and applies a 1-year cooldown to prevent retrying permanently dead accounts.
  • T07 — X-Forwarded-For IP validation: new src/lib/ipUtils.ts with extractClientIp() and getClientIpFromRequest() — skips unknown/non-IP entries in X-Forwarded-For chains (Nginx/proxy-forwarded requests).
  • T10 — Credits exhausted → distinct fallback: isCreditsExhausted() in accountFallback.ts returns 1h cooldown with creditsExhausted flag, distinct from generic 429 rate limiting.
  • T11max reasoning effort → 131072 budget tokens: EFFORT_BUDGETS and THINKING_LEVEL_MAP updated; reverse mapping now returns "max" for full-budget responses. Unit test updated.
  • T12 — MiniMax M2.7 pricing entries added: minimax-m2.7, MiniMax-M2.7, minimax-m2.7-highspeed added to pricing table (sub2api PR #1120). M2.5/GLM-4.7/GLM-5/Kimi pricing already existed.
  • T15 — Array content normalization: normalizeContentToString() helper in openai-to-claude.ts correctly collapses array-formatted system/tool messages to string before sending to Anthropic.

🧪 Tests

  • Test suite: 832 tests, 0 failures (unchanged from rc.5)

[3.0.0-rc.5] - 2026-03-22

✨ New Features

  • #464 — Registered Keys Provisioning API: auto-issue API keys with per-provider & per-account quota enforcement
    • POST /api/v1/registered-keys — issue keys with idempotency support
    • GET /api/v1/registered-keys — list (masked) registered keys
    • GET /api/v1/registered-keys/{id} — get key metadata
    • DELETE /api/v1/registered-keys/{id} / POST ../{id}/revoke — revoke keys
    • GET /api/v1/quotas/check — pre-validate before issuing
    • PUT /api/v1/providers/{id}/limits — set provider issuance limits
    • PUT /api/v1/accounts/{id}/limits — set account issuance limits
    • POST /api/v1/issues/report — optional GitHub issue reporting
    • DB migration 008: registered_keys, provider_key_limits, account_key_limits tables

[3.0.0-rc.4] - 2026-03-22

✨ New Features

  • #530 (PR) — OpenCode Zen and OpenCode Go providers added (by @kang-heewon)
    • New OpencodeExecutor with multi-format routing (/chat/completions, /messages, /responses)
    • 7 models across both tiers

[3.0.0-rc.3] - 2026-03-22

✨ New Features

  • #529 — Provider icons now use @lobehub/icons with graceful PNG fallback and a ProviderIcon component (130+ providers supported)
  • #488 — Auto-update model lists every 24h via modelSyncScheduler (configurable via MODEL_SYNC_INTERVAL_HOURS)

🔧 Bug Fixes

  • #537 — Gemini CLI OAuth: now shows clear actionable error when GEMINI_OAUTH_CLIENT_SECRET is missing in Docker/self-hosted deployments

[3.0.0-rc.2] - 2026-03-22

🔧 Bug Fixes

  • #536 — LongCat AI key validation: fixed baseUrl (api.longcat.chat/openai) and authHeader (Authorization: Bearer)
  • #535 — Pinned model override: body.model is now set to pinnedModel when context-cache protection detects a pinned model
  • #524 — OpenCode config now saved correctly: added saveOpenCodeConfig() handler (XDG_CONFIG_HOME aware, writes TOML)

[3.0.0-rc.1] - 2026-03-22

🔧 Bug Fixes

  • #521 — Login no longer gets stuck after skipping password setup (redirects to onboarding)
  • #522 — API Manager: Removed misleading "Copy masked key" button (replaced with lock icon tooltip)
  • #527 — Claude Code + Codex superpowers loop: tool_result blocks now converted to text instead of dropped
  • #532 — OpenCode GO API key validation now uses the correct zen/v1 endpoint (testKeyBaseUrl)
  • #489 — Antigravity: missing googleProjectId returns structured 422 error with reconnect guidance
  • #510 — Windows: MSYS2/Git-Bash paths (/c/Program Files/...) are now normalized to C:\\Program Files\\...
  • #492omniroute CLI now detects mise/nvm when app/server.js is missing and shows targeted fix

📖 Documentation

  • #513 — Docker password reset: INITIAL_PASSWORD env var workaround documented
  • #520 — pnpm: pnpm approve-builds better-sqlite3 documented

✅ Closed Issues

#489, #492, #510, #513, #520, #521, #522, #525, #527, #532


[2.9.5] — 2026-03-22

Sprint: New OpenCode providers, embedding credentials fix, CLI masked key bug, CACHE_TAG_PATTERN fix.

🐛 Bug Fixes

  • CLI tools save masked API key to config filesclaude-settings, cline-settings, and openclaw-settings POST routes now accept a keyId param and resolve the real API key from DB before writing to disk. ClaudeToolCard updated to send keyId instead of the masked display string. Fixes #523, #526.
  • Custom embedding providers: No credentials error/v1/embeddings now tracks credentialsProviderId separately from the routing prefix, so credentials are fetched from the matching provider node ID rather than the public prefix string. Fixes a regression where google/gemini-embedding-001 and similar custom-provider models would always fail with a credentials error. Fixes #532-related. (PR #528 by @jacob2826)
  • Context cache protection regex misses \n prefixCACHE_TAG_PATTERN in comboAgentMiddleware.ts updated to match both literal \n (backslash-n) and actual newline U+000A that combo.ts streaming injects around the <omniModel> tag after fix #515. Fixes #531.

✨ New Providers

  • OpenCode Zen — Free tier gateway at opencode.ai/zen/v1 with 3 models: minimax-m2.5-free, big-pickle, gpt-5-nano
  • OpenCode Go — Subscription service at opencode.ai/zen/go/v1 with 4 models: glm-5, kimi-k2.5, minimax-m2.7 (Claude format), minimax-m2.5 (Claude format)
  • Both providers use the new OpencodeExecutor which routes dynamically to /chat/completions, /messages, /responses, or /models/{model}:generateContent based on the requested model. (PR #530 by @kang-heewon)

[2.9.4] — 2026-03-21

Sprint: Bug fixes — preserve Codex prompt cache key, fix tagContent JSON escaping, sync expired token status to DB.

🐛 Bug Fixes

  • fix(translator): Preserve prompt_cache_key in Responses API → Chat Completions translation (#517)
    — The field is a cache-affinity signal used by Codex; stripping it was preventing prompt cache hits.
    Fixed in openai-responses.ts and responsesApiHelper.ts.

  • fix(combo): Escape \n in tagContent so injected JSON string is valid (#515)
    — Template literal newlines (U+000A) are not allowed unescaped inside JSON string values.
    Replaced with \\n literal sequences in open-sse/services/combo.ts.

  • fix(usage): Sync expired token status back to DB on live auth failure (#491)
    — When the Limits & Quotas live check returns 401/403, the connection testStatus is now updated
    to "expired" in the database so the Providers page reflects the same degraded state.
    Fixed in src/app/api/usage/[connectionId]/route.ts.


[2.9.3] — 2026-03-21

Sprint: Add 5 new free AI providers — LongCat, Pollinations, Cloudflare AI, Scaleway, AI/ML API.

✨ New Providers

  • feat(providers/longcat): Add LongCat AI (lc/) — 50M tokens/day free (Flash-Lite) + 500K/day (Chat/Thinking) during public beta. OpenAI-compatible, standard Bearer auth.
  • feat(providers/pollinations): Add Pollinations AI (pol/) — no API key required. Proxies GPT-5, Claude, Gemini, DeepSeek V3, Llama 4 (1 req/15s free). Custom executor handles optional auth.
  • feat(providers/cloudflare-ai): Add Cloudflare Workers AI (cf/) — 10K Neurons/day free (~150 LLM responses or 500s Whisper audio). 50+ models on global edge. Custom executor builds dynamic URL with accountId from credentials.
  • feat(providers/scaleway): Add Scaleway Generative APIs (scw/) — 1M free tokens for new accounts. EU/GDPR compliant (Paris). Qwen3 235B, Llama 3.1 70B, Mistral Small 3.2.
  • feat(providers/aimlapi): Add AI/ML API (aiml/) — $0.025/day free credit, 200+ models (GPT-4o, Claude, Gemini, Llama) via single aggregator endpoint.

🔄 Provider Updates

  • feat(providers/together): Add hasFree: true + 3 permanently free model IDs: Llama-3.3-70B-Instruct-Turbo-Free, Llama-Vision-Free, DeepSeek-R1-Distill-Llama-70B-Free
  • feat(providers/gemini): Add hasFree: true + freeNote (1,500 req/day, no credit card needed, aistudio.google.com)
  • chore(providers/gemini): Rename display name to Gemini (Google AI Studio) for clarity

⚙️ Infrastructure

  • feat(executors/pollinations): New PollinationsExecutor — omits Authorization header when no API key provided
  • feat(executors/cloudflare-ai): New CloudflareAIExecutor — dynamic URL construction requires accountId in provider credentials
  • feat(executors): Register pollinations, pol, cloudflare-ai, cf executor mappings

📝 Documentation

  • docs(readme): Expanded free combo stack to 11 providers ($0 forever)
  • docs(readme): Added 4 new free provider sections (LongCat, Pollinations, Cloudflare AI, Scaleway) with model tables
  • docs(readme): Updated pricing table with 4 new free tier rows
  • docs(i18n/pt-BR): Updated pricing table + added LongCat/Pollinations/Cloudflare AI/Scaleway sections in Portuguese
  • docs(new-features/ai): 10 task spec files + master implementation plan in docs/new-features/ai/

🧪 Tests

  • Test suite: 821 tests, 0 failures (unchanged)

[2.9.2] — 2026-03-21

Sprint: Fix media transcription (Deepgram/HuggingFace Content-Type, language detection) and TTS error display.

🐛 Bug Fixes

  • fix(transcription): Deepgram and HuggingFace audio transcription now correctly map video/mp4audio/mp4 and other media MIME types via new resolveAudioContentType() helper. Previously, uploading .mp4 files consistently returned "No speech detected" because Deepgram was receiving Content-Type: video/mp4.
  • fix(transcription): Added detect_language=true to Deepgram requests — auto-detects audio language (Portuguese, Spanish, etc.) instead of defaulting to English. Fixes non-English transcriptions returning empty or garbage results.
  • fix(transcription): Added punctuate=true to Deepgram requests for higher-quality transcription output with correct punctuation.
  • fix(tts): [object Object] error display in Text-to-Speech responses fixed in both audioSpeech.ts and audioTranscription.ts. The upstreamErrorResponse() function now correctly extracts nested string messages from providers like ElevenLabs that return { error: { message: "...", status_code: 401 } } instead of a flat error string.

🧪 Tests

  • Test suite: 821 tests, 0 failures (unchanged)

Triaged Issues

  • #508 — Tool call format regression: requested proxy logs and provider chain info (needs-info)
  • #510 — Windows CLI healthcheck path: requested shell/Node version info (needs-info)
  • #485 — Kiro MCP tool calls: closed as external Kiro issue (not OmniRoute)
  • #442 — Baseten /models endpoint: closed (documented manual workaround)
  • #464 — Key provisioning API: acknowledged as roadmap item

[2.9.1] — 2026-03-21

Sprint: Fix SSE omniModel data loss, merge per-protocol model compatibility.

Bug Fixes

  • #511 — Critical: <omniModel> tag was sent after finish_reason:stop in SSE streams, causing data loss. Tag is now injected into the first non-empty content chunk, guaranteeing delivery before SDKs close the connection.

Merged PRs

  • PR #512 (@zhangqiang8vip): Per-protocol model compatibility — normalizeToolCallId and preserveOpenAIDeveloperRole can now be configured per client protocol (OpenAI, Claude, Responses API). New compatByProtocol field in model config with Zod validation.

Triaged Issues

  • #510 — Windows CLI healthcheck_failed: requested PATH/version info
  • #509 — Turbopack Electron regression: upstream Next.js bug, documented workarounds
  • #508 — macOS black screen: suggested --disable-gpu workaround

[2.9.0] — 2026-03-20

Sprint: Cross-platform machineId fix, per-API-key rate limits, streaming context cache, Alibaba DashScope, search analytics, ZWS v5, and 8 issues closed.

✨ New Features

  • feat(search): Search Analytics tab in /dashboard/analytics — provider breakdown, cache hit rate, cost tracking. New API: GET /api/v1/search/analytics (#feat/search-provider-routing)
  • feat(provider): Alibaba Cloud DashScope added with custom endpoint path validation — configurable chatPath and modelsPath per node (#feat/custom-endpoint-paths)
  • feat(api): Per-API-key request-count limits — max_requests_per_day and max_requests_per_minute columns with in-memory sliding-window enforcement returning HTTP 429 (#452)
  • feat(dev): ZWS v5 — HMR leak fix (485 DB connections → 1), memory 2.4GB → 195MB, globalThis singletons, Edge Runtime warning fix (@zhangqiang8vip)

🐛 Bug Fixes

  • fix(#506): Cross-platform machineIdgetMachineIdRaw() rewritten with try/catch waterfall (Windows REG.exe → macOS ioreg → Linux file read → hostname → os.hostname()). Eliminates process.platform branching that Next.js bundler dead-code-eliminated, fixing 'head' is not recognized on Windows. Also fixes #466.
  • fix(#493): Custom provider model naming — removed incorrect prefix stripping in DefaultExecutor.transformRequest() that mangled org-scoped model IDs like zai-org/GLM-5-FP8.
  • fix(#490): Streaming + context cache protection — TransformStream intercepts SSE to inject <omniModel> tag before [DONE] marker, enabling context cache protection for streaming responses.
  • fix(#458): Combo schema validation — system_message, tool_filter_regex, context_cache_protection fields now pass Zod validation on save.
  • fix(#487): KIRO MITM card cleanup — removed ZWS_README, generified AntigravityToolCard to use dynamic tool metadata.

🧪 Tests

  • Added Anthropic-format tools filter unit tests (PR #397) — 8 regression tests for tool.name without .function wrapper
  • Test suite: 821 tests, 0 failures (up from 813)

📋 Issues Closed (8)

  • #506 — Windows machineId head not recognized (fixed)
  • #493 — Custom provider model naming (fixed)
  • #490 — Streaming context cache (fixed)
  • #452 — Per-API-key request limits (implemented)
  • #466 — Windows login failure (same root cause as #506)
  • #504 — MITM inactive (expected behavior)
  • #462 — Gemini CLI PSA (resolved)
  • #434 — Electron app crash (duplicate of #402)

[2.8.9] — 2026-03-20

Sprint: Merge community PRs, fix KIRO MITM card, dependency updates.

Merged PRs

  • PR #498 (@Sajid11194): Fix Windows machine ID crash (undefined\REG.exe). Replaces node-machine-id with native OS registry queries. Closes #486.
  • PR #497 (@zhangqiang8vip): Fix dev-mode HMR resource leaks — 485 leaked DB connections → 1, memory 2.4GB → 195MB. globalThis singletons, Edge Runtime warning fix, Windows test stability. (+1168/-338 across 22 files)
  • PRs #499-503 (Dependabot): GitHub Actions updates — docker/build-push-action@7, actions/checkout@6, peter-evans/dockerhub-description@5, docker/setup-qemu-action@4, docker/login-action@4.

Bug Fixes

  • #505 — KIRO MITM card now displays tool-specific instructions (api.anthropic.com) instead of Antigravity-specific text.
  • #504 — Responded with UX clarification (MITM "Inactive" is expected behavior when proxy is not running).

[2.8.8] — 2026-03-20

Sprint: Fix OAuth batch test crash, add "Test All" button to individual provider pages.

Bug Fixes

  • OAuth batch test crash (ERR_CONNECTION_REFUSED): Replaced sequential for-loop with 5-connection concurrency limit + 30s per-connection timeout via Promise.race() + Promise.allSettled(). Prevents server crash when testing large OAuth provider groups (~30+ connections).

Features

  • "Test All" button on provider pages: Individual provider pages (e.g., /providers/codex) now show a "Test All" button in the Connections header when there are 2+ connections. Uses POST /api/providers/test-batch with {mode: "provider", providerId}. Results displayed in a modal with pass/fail summary and per-connection diagnosis.

[2.8.7] — 2026-03-20

Sprint: Merge PR #495 (Bottleneck 429 drop), fix #496 (custom embedding providers), triage features.

Bug Fixes

  • Bottleneck 429 infinite wait (PR #495 by @xandr0s): On 429, limiter.stop({ dropWaitingJobs: true }) immediately fails all queued requests so upstream callers can trigger fallback. Limiter is deleted from Map so next request creates a fresh instance.
  • Custom embedding models unresolvable (#496): POST /v1/embeddings now resolves custom embedding models from ALL provider_nodes (not just localhost). Enables models like google/gemini-embedding-001 added via dashboard.

Issues Responded

  • #452 — Per-API-key request-count limits (acknowledged, on roadmap)
  • #464 — Auto-issue API keys with provider/account limits (needs more detail)
  • #488 — Auto-update model lists (acknowledged, on roadmap)
  • #496 — Custom embedding provider resolution (fixed)

[2.8.6] — 2026-03-20

Sprint: Merge PR #494 (MiniMax role fix), fix KIRO MITM dashboard, triage 8 issues.

Features

  • MiniMax developer→system role fix (PR #494 by @zhangqiang8vip): Per-model preserveDeveloperRole toggle. Adds "Compatibility" UI in providers page. Fixes 422 "role param error" for MiniMax and similar gateways.
  • roleNormalizer: normalizeDeveloperRole() now accepts preserveDeveloperRole parameter with tri-state behavior (undefined=keep, true=keep, false=convert).
  • DB: New getModelPreserveOpenAIDeveloperRole() and mergeModelCompatOverride() in models.ts.

Bug Fixes

  • KIRO MITM dashboard (#481/#487): CLIToolsPageClient now routes any configType: "mitm" tool to AntigravityToolCard (MITM Start/Stop controls). Previously only Antigravity was hardcoded.
  • AntigravityToolCard generic: Uses tool.image, tool.description, tool.id instead of hardcoded Antigravity values. Guards against missing defaultModels.

Cleanup

  • Removed ZWS_README_V2.md (development-only docs from PR #494).

Issues Triaged (8)

  • #487 — Closed (KIRO MITM fixed in this release)
  • #486 — needs-info (Windows REG.exe PATH issue)
  • #489 — needs-info (Antigravity projectId missing, OAuth reconnect needed)
  • #492 — needs-info (missing app/server.js on mise-managed Node)
  • #490 — Acknowledged (streaming + context cache blocking, fix planned)
  • #491 — Acknowledged (Codex auth state inconsistency)
  • #493 — Acknowledged (Modal provider model name prefix, workaround provided)
  • #488 — Feature request backlog (auto-update model lists)

[2.8.5] — 2026-03-19

Sprint: Fix zombie SSE streams, context cache first-turn, KIRO MITM, and triage 5 external issues.

Bug Fixes

  • Zombie SSE Streams (#473): Reduce STREAM_IDLE_TIMEOUT_MS from 300s → 120s for faster combo fallback when providers hang mid-stream. Configurable via env var.
  • Context Cache Tag (#474): Fix injectModelTag() to handle first-turn requests (no assistant messages) — context cache protection now works from the very first response.
  • KIRO MITM (#481): Change KIRO configType from guidemitm so the dashboard renders MITM Start/Stop controls.
  • E2E Test (CI): Fix providers-bailian-coding-plan.spec.ts — dismiss pre-existing modal overlay before clicking Add API Key button.

Closed Issues

  • #473 — Zombie SSE streams bypass combo fallback
  • #474 — Context cache <omniModel> tag missing on first turn
  • #481 — MITM for KIRO not activatable from dashboard
  • #468 — Gemini CLI remote server (superseded by #462 deprecation)
  • #438 — Claude unable to write files (external CLI issue)
  • #439 — AppImage doesn't work (documented libfuse2 workaround)
  • #402 — ARM64 DMG "damaged" (documented xattr -cr workaround)
  • #460 — CLI not runnable on Windows (documented PATH fix)

[2.8.4] — 2026-03-19

Sprint: Gemini CLI deprecation, VM guide i18n fix, dependabot security fix, provider schema expansion.

Features

  • Gemini CLI Deprecation (#462): Mark gemini-cli provider as deprecated with warning — Google restricts third-party OAuth usage from March 2026
  • Provider Schema (#462): Expand Zod validation with deprecated, deprecationReason, hasFree, freeNote, authHint, apiHint optional fields

Bug Fixes

  • VM Guide i18n (#471): Add VM_DEPLOYMENT_GUIDE.md to i18n translation pipeline, regenerate all 30 locale translations from English source (were stuck in Portuguese)

Security

  • deps: Bump flatted 3.3.3 → 3.4.2 — fixes CWE-1321 prototype pollution (#484, @dependabot)

Closed Issues

  • #472 — Model Aliases regression (fixed in v2.8.2)
  • #471 — VM guide translations broken
  • #483 — Trailing data: null after [DONE] (fixed in v2.8.3)

Merged PRs


[2.8.3] — 2026-03-19

Sprint: Czech i18n, SSE protocol fix, VM guide translation.

Features

  • Czech Language (#482): Full Czech (cs) i18n — 22 docs, 2606 UI strings, language switcher updates (@zen0bit)
  • VM Deployment Guide: Translated from Portuguese to English as the source document (@zen0bit)

Bug Fixes

  • SSE Protocol (#483): Stop sending trailing data: null after [DONE] signal — fixes AI_TypeValidationError in strict AI SDK clients (Zod-based validators)

Merged PRs

  • #482 — Add Czech language + Fix VM_DEPLOYMENT_GUIDE.md English source (@zen0bit)

[2.8.2] — 2026-03-19

Sprint: 2 merged PRs, model aliases routing fix, log export, and issue triage.

Features

  • Log Export: New Export button on /dashboard/logs with time range dropdown (1h, 6h, 12h, 24h). Downloads JSON of request/proxy/call logs via /api/logs/export API (#user-request)

Bug Fixes

  • Model Aliases Routing (#472): Settings → Model Aliases now correctly affect provider routing, not just format detection. Previously resolveModelAlias() output was only used for getModelTargetFormat() but the original model ID was sent to the provider
  • Stream Flush Usage (#480): Usage data from the last SSE event in the buffer is now correctly extracted during stream flush (merged from @prakersh)

Merged PRs

  • #480 — Extract usage from remaining buffer in flush handler (@prakersh)
  • #479 — Add missing Codex 5.3/5.4 and Anthropic model ID pricing entries (@prakersh)

[2.8.1] — 2026-03-19

Sprint: Five community PRs — streaming call log fixes, Kiro compatibility, cache token analytics, Chinese translation, and configurable tool call IDs.

✨ Features

  • feat(logs): Call log response content now correctly accumulated from raw provider chunks (OpenAI/Claude/Gemini) before translation, fixing empty response payloads in streaming mode (#470, @zhangqiang8vip)
  • feat(providers): Per-model configurable 9-char tool call ID normalization (Mistral-style) — only models with the option enabled get truncated IDs (#470)
  • feat(api): Key PATCH API expanded to support allowedConnections, name, autoResolve, isActive, and accessSchedule fields (#470)
  • feat(dashboard): Response-first layout in request log detail UI (#470)
  • feat(i18n): Improved Chinese (zh-CN) translation — complete retranslation (#475, @only4copilot)

🐛 Bug Fixes

  • fix(kiro): Strip injected model field from request body — Kiro API rejects unknown top-level fields (#478, @prakersh)
  • fix(usage): Include cache read + cache creation tokens in usage history input totals for accurate analytics (#477, @prakersh)
  • fix(callLogs): Support Claude format usage fields (input_tokens/output_tokens) alongside OpenAI format, include all cache token variants (#476, @prakersh)

[2.8.0] — 2026-03-19

Sprint: Bailian Coding Plan provider with editable base URLs, plus community contributions for Alibaba Cloud and Kimi Coding.

✨ Features

  • feat(providers): Added Bailian Coding Plan (bailian-coding-plan) — Alibaba Model Studio with Anthropic-compatible API. Static catalog of 8 models including Qwen3.5 Plus, Qwen3 Coder, MiniMax M2.5, GLM 5, and Kimi K2.5. Includes custom auth validation (400=valid, 401/403=invalid) (#467, @Mind-Dragon)
  • feat(admin): Editable default URL in Provider Admin create/edit flows — users can configure custom base URLs per connection. Persisted in providerSpecificData.baseUrl with Zod schema validation rejecting non-http(s) schemes (#467)

🧪 Tests

  • Added 30+ unit tests and 2 e2e scenarios for Bailian Coding Plan provider covering auth validation, schema hardening, route-level behavior, and cross-layer integration

[2.7.10] — 2026-03-19

Sprint: Two new community-contributed providers (Alibaba Cloud Coding, Kimi Coding API-key) and Docker pino fix.

✨ Features

  • feat(providers): Added Alibaba Cloud Coding Plan support with two OpenAI-compatible endpoints — alicode (China) and alicode-intl (International), each with 8 models (#465, @dtk1985)
  • feat(providers): Added dedicated kimi-coding-apikey provider path — API-key-based Kimi Coding access is no longer forced through OAuth-only kimi-coding route. Includes registry, constants, models API, config, and validation test (#463, @Mind-Dragon)

🐛 Bug Fixes

  • fix(docker): Added missing split2 dependency to Docker image — pino-abstract-transport requires it at runtime but it was not being copied into the standalone container, causing Cannot find module 'split2' crashes (#459)

[2.7.9] — 2026-03-18

Sprint: Codex responses subpath passthrough natively supported, Windows MITM crash fixed, and Combos agent schemas adjusted.

✨ Features

  • feat(codex): Native responses subpath passthrough for Codex — natively routes POST /v1/responses/compact to Codex upstream, maintaining Claude Code compatibility without stripping the /compact suffix (#457)

🐛 Bug Fixes

  • fix(combos): Zod schemas (updateComboSchema and createComboSchema) now include system_message, tool_filter_regex, and context_cache_protection. Fixes bug where agent-specific settings created via the dashboard were silently discarded by the backend validation layer (#458)
  • fix(mitm): Kiro MITM profile crash on Windows fixed — node-machine-id failed due to missing REG.exe env, and the fallback threw a fatal crypto is not defined error. Fallback now safely and correctly imports crypto (#456)

[2.7.8] — 2026-03-18

Sprint: Budget save bug + combo agent features UI + omniModel tag security fix.

🐛 Bug Fixes

  • fix(budget): "Save Limits" no longer returns 422 — warningThreshold is now correctly sent as fraction (0–1) instead of percentage (0–100) (#451)
  • fix(combos): <omniModel> internal cache tag is now stripped before forwarding requests to providers, preventing cache session breaks (#454)

✨ Features

  • feat(combos): Agent Features section added to combo create/edit modal — expose system_message override, tool_filter_regex, and context_cache_protection directly from the dashboard (#454)

[2.7.7] — 2026-03-18

Sprint: Docker pino crash, Codex CLI responses worker fix, package-lock sync.

🐛 Bug Fixes

  • fix(docker): pino-abstract-transport and pino-pretty now explicitly copied in Docker runner stage — Next.js standalone trace misses these peer deps, causing Cannot find module pino-abstract-transport crash on startup (#449)
  • fix(responses): Remove initTranslators() from /v1/responses route — was crashing Next.js worker with the worker has exited uncaughtException on Codex CLI requests (#450)

🔧 Maintenance

  • chore(deps): package-lock.json now committed on every version bump to ensure Docker npm ci uses exact dependency versions

[2.7.5] — 2026-03-18

Sprint: UX improvements and Windows CLI healthcheck fix.

🐛 Bug Fixes

  • fix(ux): Show default password hint on login page — new users now see "Default password: 123456" below the password input (#437)
  • fix(cli): Claude CLI and other npm-installed tools now correctly detected as runnable on Windows — spawn uses shell:true to resolve .cmd wrappers via PATHEXT (#447)

[2.7.4] — 2026-03-18

Sprint: Search Tools dashboard, i18n fixes, Copilot limits, Serper validation fix.

🚀 Features

  • feat(search): Add Search Playground (10th endpoint), Search Tools page with Compare Providers/Rerank Pipeline/Search History, local rerank routing, auth guards on search API (#443 by @Regis-RCR)
    • New route: /dashboard/search-tools
    • Sidebar entry under Debug section
    • GET /api/search/providers and GET /api/search/stats with auth guards
    • Local provider_nodes routing for /v1/rerank
    • 30+ i18n keys in search namespace

🐛 Bug Fixes

  • fix(search): Fix Brave news normalizer (was returning 0 results), enforce max_results truncation post-normalization, fix Endpoints page fetch URL (#443 by @Regis-RCR)
  • fix(analytics): Localize analytics day/date labels — replace hardcoded Portuguese strings with Intl.DateTimeFormat(locale) (#444 by @hijak)
  • fix(copilot): Correct GitHub Copilot account type display, filter misleading unlimited quota rows from limits dashboard (#445 by @hijak)
  • fix(providers): Stop rejecting valid Serper API keys — treat non-4xx responses as valid authentication (#446 by @hijak)

[2.7.3] — 2026-03-18

Sprint: Codex direct API quota fallback fix.

🐛 Bug Fixes

  • fix(codex): Block weekly-exhausted accounts in direct API fallback (#440)
    • resolveQuotaWindow() prefix matching: "weekly" now matches "weekly (7d)" cache keys
    • applyCodexWindowPolicy() enforces useWeekly/use5h toggles correctly
    • 4 new regression tests (766 total)

[2.7.2] — 2026-03-18

Sprint: Light mode UI contrast fixes.

🐛 Bug Fixes

  • fix(logs): Fix light mode contrast in request logs filter buttons and combo badge (#378)
    • Error/Success/Combo filter buttons now readable in light mode
    • Combo row badge uses stronger violet in light mode

[2.7.1] — 2026-03-17

Sprint: Unified web search routing (POST /v1/search) with 5 providers + Next.js 16.1.7 security fixes (6 CVEs).

✨ New Features

  • feat(search): Unified web search routing — POST /v1/search with 5 providers (Serper, Brave, Perplexity, Exa, Tavily)
    • Auto-failover across providers, 6,500+ free searches/month
    • In-memory cache with request coalescing (configurable TTL)
    • Dashboard: Search Analytics tab in /dashboard/analytics with provider breakdown, cache hit rate, cost tracking
    • New API: GET /api/v1/search/analytics for search request statistics
    • DB migration: request_type column on call_logs for non-chat request tracking
    • Zod validation (v1SearchSchema), auth-gated, cost recorded via recordCost()

🔒 Security

📁 New Files

File Purpose
open-sse/handlers/search.ts Search handler with 5-provider routing
open-sse/config/searchRegistry.ts Provider registry (auth, cost, quota, TTL)
open-sse/services/searchCache.ts In-memory cache with request coalescing
src/app/api/v1/search/route.ts Next.js route (POST + GET)
src/app/api/v1/search/analytics/route.ts Search stats API
src/app/(dashboard)/dashboard/analytics/SearchAnalyticsTab.tsx Analytics dashboard tab
src/lib/db/migrations/007_search_request_type.sql DB migration
tests/unit/search-registry.test.mjs 277 lines of unit tests

[2.7.0] — 2026-03-17

Sprint: ClawRouter-inspired features — toolCalling flag, multilingual intent detection, benchmark-driven fallback, request deduplication, pluggable RouterStrategy, Grok-4 Fast + GLM-5 + MiniMax M2.5 + Kimi K2.5 pricing.

✨ New Models & Pricing

  • feat(pricing): xAI Grok-4 Fast — $0.20/$0.50 per 1M tokens, 1143ms p50 latency, tool calling supported
  • feat(pricing): xAI Grok-4 (standard) — $0.20/$1.50 per 1M tokens, reasoning flagship
  • feat(pricing): GLM-5 via Z.AI — $0.5/1M, 128K output context
  • feat(pricing): MiniMax M2.5 — $0.30/1M input, reasoning + agentic tasks
  • feat(pricing): DeepSeek V3.2 — updated pricing $0.27/$1.10 per 1M
  • feat(pricing): Kimi K2.5 via Moonshot API — direct Moonshot API access
  • feat(providers): Z.AI provider added (zai alias) — GLM-5 family with 128K output

🧠 Routing Intelligence

  • feat(registry): toolCalling flag per model in provider registry — combos can now prefer/require tool-calling capable models
  • feat(scoring): Multilingual intent detection for AutoCombo scoring — PT/ZH/ES/AR script/language patterns influence model selection per request context
  • feat(fallback): Benchmark-driven fallback chains — real latency data (p50 from comboMetrics) used to re-order fallback priority dynamically
  • feat(dedup): Request deduplication via content-hash — 5-second idempotency window prevents duplicate provider calls from retrying clients
  • feat(router): Pluggable RouterStrategy interface in autoCombo/routerStrategy.ts — custom routing logic can be injected without modifying core

🔧 MCP Server Improvements

  • feat(mcp): 2 new advanced tool schemas: omniroute_get_provider_metrics (p50/p95/p99 per provider) and omniroute_explain_route (routing decision explanation)
  • feat(mcp): MCP tool auth scopes updated — metrics:read scope added for provider metrics tools
  • feat(mcp): omniroute_best_combo_for_task now accepts languageHint parameter for multilingual routing

📊 Observability

  • feat(metrics): comboMetrics.ts extended with real-time latency percentile tracking per provider/account
  • feat(health): Health API (/api/monitoring/health) now returns per-provider p50Latency and errorRate fields
  • feat(usage): Usage history migration for per-model latency tracking

🗄️ DB Migrations

  • feat(migrations): New column latency_p50 in combo_metrics table — zero-breaking, safe for existing users

🐛 Bug Fixes / Closures

  • close(#411): better-sqlite3 hashed module resolution on Windows — fixed in v2.6.10 (f02c5b5)
  • close(#409): GitHub Copilot chat completions fail with Claude models when files attached — fixed in v2.6.9 (838f1d6)
  • close(#405): Duplicate of #411 — resolved

[2.6.10] — 2026-03-17

Windows fix: better-sqlite3 prebuilt download without node-gyp/Python/MSVC (#426).

🐛 Bug Fixes

  • fix(install/#426): On Windows, npm install -g omniroute used to fail with better_sqlite3.node is not a valid Win32 application because the bundled native binary was compiled for Linux. Adds Strategy 1.5 to scripts/postinstall.mjs: uses @mapbox/node-pre-gyp install --fallback-to-build=false (bundled within better-sqlite3) to download the correct prebuilt binary for the current OS/arch without requiring any build tools (no node-gyp, no Python, no MSVC). Falls back to npm rebuild only if the download fails. Adds platform-specific error messages with clear manual fix instructions.

[2.6.9] — 2026-03-17

CI fixes (t11 any-budget), bug fix #409 (file attachments via Copilot+Claude), release workflow correction.

🐛 Bug Fixes

  • fix(ci): Remove word "any" from comments in openai-responses.ts and chatCore.ts that were failing the t11 \bany\b budget check (false positive from regex counting comments)
  • fix(chatCore): Normalize unsupported content part types before forwarding to providers (#409 — Cursor sends {type:"file"} when .md files are attached; Copilot and other OpenAI-compat providers reject with "type has to be either 'image_url' or 'text'"; fix converts file/document blocks to text and drops unknown types)

🔧 Workflow

  • chore(generate-release): Add ATOMIC COMMIT RULE — version bump (npm version patch) MUST happen before committing feature files to ensure tag always points to a commit containing all version changes together

[2.6.8] — 2026-03-17

Sprint: Combo as Agent (system prompt + tool filter), Context Caching Protection, Auto-Update, Detailed Logs, MITM Kiro IDE.

🗄️ DB Migrations (zero-breaking — safe for existing users)

  • 005_combo_agent_fields.sql: ALTER TABLE combos ADD COLUMN system_message TEXT DEFAULT NULL, tool_filter_regex TEXT DEFAULT NULL, context_cache_protection INTEGER DEFAULT 0
  • 006_detailed_request_logs.sql: New request_detail_logs table with 500-entry ring-buffer trigger, opt-in via settings toggle

✨ Features

  • feat(combo): System Message Override per Combo (#399system_message field replaces or injects system prompt before forwarding to provider)
  • feat(combo): Tool Filter Regex per Combo (#399tool_filter_regex keeps only tools matching pattern; supports OpenAI + Anthropic formats)
  • feat(combo): Context Caching Protection (#401context_cache_protection tags responses with <omniModel>provider/model</omniModel> and pins model for session continuity)
  • feat(settings): Auto-Update via Settings (#320GET /api/system/version + POST /api/system/update — checks npm registry and updates in background with pm2 restart)
  • feat(logs): Detailed Request Logs (#378 — captures full pipeline bodies at 4 stages: client request, translated request, provider response, client response — opt-in toggle, 64KB trim, 500-entry ring-buffer)
  • feat(mitm): MITM Kiro IDE profile (#336src/mitm/targets/kiro.ts targets api.anthropic.com, reuses existing MITM infrastructure)

[2.6.7] — 2026-03-17

Sprint: SSE improvements, local provider_nodes extensions, proxy registry, Claude passthrough fixes.

✨ Features

  • feat(health): Background health check for local provider_nodes with exponential backoff (30s→300s) and Promise.allSettled to avoid blocking (#423, @Regis-RCR)
  • feat(embeddings): Route /v1/embeddings to local provider_nodesbuildDynamicEmbeddingProvider() with hostname validation (#422, @Regis-RCR)
  • feat(audio): Route TTS/STT to local provider_nodesbuildDynamicAudioProvider() with SSRF protection (#416, @Regis-RCR)
  • feat(proxy): Proxy registry, management APIs, and quota-limit generalization (#429, @Regis-RCR)

🐛 Bug Fixes

  • fix(sse): Strip Claude-specific fields (metadata, anthropic_version) when target is OpenAI-compat (#421, @prakersh)
  • fix(sse): Extract Claude SSE usage (input_tokens, output_tokens, cache tokens) in passthrough stream mode (#420, @prakersh)
  • fix(sse): Generate fallback call_id for tool calls with missing/empty IDs (#419, @prakersh)
  • fix(sse): Claude-to-Claude passthrough — forward body completely untouched, no re-translation (#418, @prakersh)
  • fix(sse): Filter orphaned tool_result items after Claude Code context compaction to avoid 400 errors (#417, @prakersh)
  • fix(sse): Skip empty-name tool calls in Responses API translator to prevent placeholder_tool infinite loops (#415, @prakersh)
  • fix(sse): Strip empty text content blocks before translation (#427, @prakersh)
  • fix(api): Add refreshable: true to Claude OAuth test config (#428, @prakersh)

📦 Dependencies


[2.6.6] — 2026-03-17

Hotfix: Turbopack/Docker compatibility — remove node: protocol from all src/ imports.

🐛 Bug Fixes

  • fix(build): Removed node: protocol prefix from import statements in 17 files under src/. The node:fs, node:path, node:url, node:os etc. imports caused Ecmascript file had an error on Turbopack builds (Next.js 15 Docker) and on upgrades from older npm global installs. Affected files: migrationRunner.ts, core.ts, backup.ts, prompts.ts, dataPaths.ts, and 12 others in src/app/api/ and src/lib/.
  • chore(workflow): Updated generate-release.md to make Docker Hub sync and dual-VPS deploy mandatory steps in every release.

[2.6.5] — 2026-03-17

Sprint: reasoning model param filtering, local provider 404 fix, Kilo Gateway provider, dependency bumps.

✨ New Features

  • feat(api): Added Kilo Gateway (api.kilo.ai) as a new API Key provider (alias kg) — 335+ models, 6 free models, 3 auto-routing models (kilo-auto/frontier, kilo-auto/balanced, kilo-auto/free). Passthrough models supported via /api/gateway/models endpoint. (PR #408 by @Regis-RCR)

🐛 Bug Fixes

  • fix(sse): Strip unsupported parameters for reasoning models (o1, o1-mini, o1-pro, o3, o3-mini). Models in the o1/o3 family reject temperature, top_p, frequency_penalty, presence_penalty, logprobs, top_logprobs, and n with HTTP 400. Parameters are now stripped at the chatCore layer before forwarding. Uses a declarative unsupportedParams field per model and a precomputed O(1) Map for lookup. (PR #412 by @Regis-RCR)
  • fix(sse): Local provider 404 now results in a model-only lockout (5 seconds) instead of a connection-level lockout (2 minutes). When a local inference backend (Ollama, LM Studio, oMLX) returns 404 for an unknown model, the connection remains active and other models continue working immediately. Also fixes a pre-existing bug where model was not passed to markAccountUnavailable(). Local providers detected via hostname (localhost, 127.0.0.1, ::1, extensible via LOCAL_HOSTNAMES env var). (PR #410 by @Regis-RCR)

📦 Dependencies

  • better-sqlite3 12.6.2 → 12.8.0
  • undici 7.24.2 → 7.24.4
  • https-proxy-agent 7 → 8
  • agent-base 7 → 8

[2.6.4] — 2026-03-17

🐛 Bug Fixes

  • fix(providers): Removed non-existent model names across 5 providers:
    • gemini / gemini-cli: removed gemini-3.1-pro/flash and gemini-3-*-preview (don't exist in Google API v1beta); replaced with gemini-2.5-pro, gemini-2.5-flash, gemini-2.0-flash, gemini-1.5-pro/flash
    • antigravity: removed gemini-3.1-pro-high/low and gemini-3-flash (invalid internal aliases); replaced with real 2.x models
    • github (Copilot): removed gemini-3-flash-preview and gemini-3-pro-preview; replaced with gemini-2.5-flash
    • nvidia: corrected nvidia/llama-3.3-70b-instructmeta/llama-3.3-70b-instruct (NVIDIA NIM uses meta/ namespace for Meta models); added nvidia/llama-3.1-70b-instruct and nvidia/llama-3.1-405b-instruct
  • fix(db/combo): Updated free-stack combo on remote DB: removed qw/qwen3-coder-plus (expired refresh token), corrected nvidia/llama-3.3-70b-instructnvidia/meta/llama-3.3-70b-instruct, corrected gemini/gemini-3.1-flashgemini/gemini-2.5-flash, added if/deepseek-v3.2

[2.6.3] — 2026-03-16

Sprint: zod/pino hash-strip baked into build pipeline, Synthetic provider added, VPS PM2 path corrected.

🐛 Bug Fixes

  • fix(build): Turbopack hash-strip now runs at compile time for ALL packages — not just better-sqlite3. Step 5.6 in prepublish.mjs walks every .js in app/.next/server/ and strips the 16-char hex suffix from any hashed require(). Fixes zod-dcb22c..., pino-..., etc. MODULE_NOT_FOUND on global npm installs. Closes #398
  • fix(deploy): PM2 on both VPS was pointing to stale git-clone directories. Reconfigured to app/server.js in the npm global package. Updated /deploy-vps workflow to use npm pack + scp (npm registry rejects 299MB packages).

✨ Features

  • feat(provider): Synthetic (synthetic.new) — privacy-focused OpenAI-compatible inference. passthroughModels: true for dynamic HuggingFace model catalog. Initial models: Kimi K2.5, MiniMax M2.5, GLM 4.7, DeepSeek V3.2. (PR #404 by @Regis-RCR)

📋 Issues Closed

  • close #398: npm hash regression — fixed by compile-time hash-strip in prepublish
  • triage #324: Bug screenshot without steps — requested reproduction details

[2.6.2] — 2026-03-16

Sprint: module hashing fully fixed, 2 PRs merged (Anthropic tools filter + custom endpoint paths), Alibaba Cloud DashScope provider added, 3 stale issues closed.

🐛 Bug Fixes

  • fix(build): Extended webpack externals hash-strip to cover ALL serverExternalPackages, not just better-sqlite3. Next.js 16 Turbopack hashes zod, pino, and every other server-external package into names like zod-dcb22c6336e0bc69 that don't exist in node_modules at runtime. A HASH_PATTERN regex catch-all now strips the 16-char suffix and falls back to the base package name. Also added NEXT_PRIVATE_BUILD_WORKER=0 in prepublish.mjs to reinforce webpack mode, plus a post-build scan that reports any remaining hashed refs. (#396, #398, PR #403)
  • fix(chat): Anthropic-format tool names (tool.name without .function wrapper) were silently dropped by the empty-name filter introduced in #346. LiteLLM proxies requests with anthropic/ prefix in Anthropic Messages API format, causing all tools to be filtered and Anthropic to return 400: tool_choice.any may only be specified while providing tools. Fixed by falling back to tool.name when tool.function.name is absent. Added 8 regression unit tests. (PR #397)

✨ Features

  • feat(api): Custom endpoint paths for OpenAI-compatible provider nodes — configure chatPath and modelsPath per node (e.g. /v4/chat/completions) in the provider connection UI. Includes a DB migration (003_provider_node_custom_paths.sql) and URL path sanitization (no .. traversal, must start with /). (PR #400)
  • feat(provider): Alibaba Cloud DashScope added as OpenAI-compatible provider. International endpoint: dashscope-intl.aliyuncs.com/compatible-mode/v1. 12 models: qwen-max, qwen-plus, qwen-turbo, qwen3-coder-plus/flash, qwq-plus, qwq-32b, qwen3-32b, qwen3-235b-a22b. Auth: Bearer API key.

📋 Issues Closed

  • close #323: Cline connection error [object Object] — fixed in v2.3.7; instructed user to upgrade from v2.2.9
  • close #337: Kiro credit tracking — implemented in v2.5.5 (#381); pointed user to Dashboard → Usage
  • triage #402: ARM64 macOS DMG damaged — requested macOS version, exact error, and advised xattr -d com.apple.quarantine workaround

[2.6.1] — 2026-03-15

Critical startup fix: v2.6.0 global npm installs crashed with a 500 error due to a Turbopack/webpack module-name hashing bug in the Next.js 16 instrumentation hook.

🐛 Bug Fixes

  • fix(build): Force better-sqlite3 to always be required by its exact package name in the webpack server bundle. Next.js 16 compiled the instrumentation hook into a separate chunk and emitted require('better-sqlite3-<hash>') — a hashed module name that doesn't exist in node_modules — even though the package was listed in serverExternalPackages. Added an explicit externals function to the server webpack config so the bundler always emits require('better-sqlite3'), resolving the startup 500 Internal Server Error on clean global installs. (#394, PR #395)

🔧 CI

  • ci: Added workflow_dispatch to npm-publish.yml with version sync safeguard for manual triggers (#392)
  • ci: Added workflow_dispatch to docker-publish.yml, updated GitHub Actions to latest versions (#392)

[2.6.0] - 2026-03-15

Issue resolution sprint: 4 bugs fixed, logs UX improved, Kiro credit tracking added.

🐛 Bug Fixes

  • fix(media): ComfyUI and SD WebUI no longer appear in the Media page provider list when unconfigured — fetches /api/providers on mount and hides local providers with no connections (#390)
  • fix(auth): Round-robin no longer re-selects rate-limited accounts immediately after cooldown — backoffLevel is now used as primary sort key in the LRU rotation (#340)
  • fix(oauth): iFlow (and other providers that redirect to their own UI) no longer leave the OAuth modal stuck at "Waiting for Authorization" — popup-closed detector auto-transitions to manual URL input mode (#344)
  • fix(logs): Request log table is now readable in light mode — status badges, token counts, and combo tags use adaptive dark: color classes (#378)

✨ Features

  • feat(kiro): Kiro credit tracking added to usage fetcher — queries getUserCredits from AWS CodeWhisperer endpoint (#337)

🛠 Chores

  • chore(tests): Aligned test:plan3, test:fixes, test:security to use same tsx/esm loader as npm test — eliminates module resolution false negatives in targeted runs (PR #386)

[2.5.9] - 2026-03-15

Codex native passthrough fix + route body validation hardening.

🐛 Bug Fixes

  • fix(codex): Preserve native Responses API passthrough for Codex clients — avoids unnecessary translation mutations (PR #387)
  • fix(api): Validate request bodies on pricing/sync and task-routing routes — prevents crashes from malformed inputs (PR #388)
  • fix(auth): JWT secrets persist across restarts via src/lib/db/secrets.ts — eliminates 401 errors after pm2 restart (PR #388)

[2.5.8] - 2026-03-15

Build fix: restore VPS connectivity broken by v2.5.7 incomplete publish.

🐛 Bug Fixes

  • fix(build): scripts/prepublish.mjs still used deprecated --webpack flag causing Next.js standalone build to fail silently — npm publish completed without app/server.js, breaking VPS deployment

[2.5.7] - 2026-03-15

Media playground error handling fixes.

🐛 Bug Fixes

  • fix(media): Transcription "API Key Required" false positive when audio contains no speech (music, silence) — now shows "No speech detected" instead
  • fix(media): upstreamErrorResponse in audioTranscription.ts and audioSpeech.ts now returns proper JSON ({error:{message}}), enabling correct 401/403 credential error detection in the MediaPageClient
  • fix(media): parseApiError now handles Deepgram's err_msg field and detects "api key" in error messages for accurate credential error classification

[2.5.6] - 2026-03-15

Critical security/auth fixes: Antigravity OAuth broken + JWT sessions lost after restart.

🐛 Bug Fixes

  • fix(oauth) #384: Antigravity Google OAuth now correctly sends client_secret to the token endpoint. The fallback for ANTIGRAVITY_OAUTH_CLIENT_SECRET was an empty string, which is falsy — so client_secret was never included in the request, causing "client_secret is missing" errors for all users without a custom env var. Closes #383.
  • fix(auth) #385: JWT_SECRET is now persisted to SQLite (namespace='secrets') on first generation and reloaded on subsequent starts. Previously, a new random secret was generated each process startup, invalidating all existing cookies/sessions after any restart or upgrade. Affects both JWT_SECRET and API_KEY_SECRET. Closes #382.

[2.5.5] - 2026-03-15

Model list dedup fix, Electron standalone build hardening, and Kiro credit tracking.

🐛 Bug Fixes

  • fix(models) #380: GET /api/models now includes provider aliases when building the active-provider filter — models for claude (alias cc) and github (alias gh) were always shown regardless of whether a connection was configured, because PROVIDER_MODELS keys are aliases but DB connections are stored under provider IDs. Fixed by expanding each active provider ID to also include its alias via PROVIDER_ID_TO_ALIAS. Closes #353.
  • fix(electron) #379: New scripts/prepare-electron-standalone.mjs stages a dedicated /.next/electron-standalone bundle before Electron packaging. Aborts with a clear error if node_modules is a symlink (electron-builder would ship a runtime dependency on the build machine). Cross-platform path sanitization via path.basename. By @kfiramar.

✨ New Features

  • feat(kiro) #381: Kiro credit balance tracking — usage endpoint now returns credit data for Kiro accounts by calling codewhisperer.us-east-1.amazonaws.com/getUserCredits (same endpoint Kiro IDE uses internally). Returns remaining credits, total allowance, renewal date, and subscription tier. Closes #337.

[2.5.4] - 2026-03-15

Logger startup fix, login bootstrap security fix, and dev HMR reliability improvement. CI infrastructure hardened.

🐛 Bug Fixes (PRs #374, #375, #376 by @kfiramar)

  • fix(logger) #376: Restore pino transport logger path — formatters.level combined with transport.targets is rejected by pino. Transport-backed configs now strip the level formatter via getTransportCompatibleConfig(). Also corrects numeric level mapping in /api/logs/console: 30→info, 40→warn, 50→error (was shifted by one).
  • fix(login) #375: Login page now bootstraps from the public /api/settings/require-login endpoint instead of the protected /api/settings. In password-protected setups, the pre-auth page was receiving a 401 and falling back to safe defaults unnecessarily. The public route now returns all bootstrap metadata (requireLogin, hasPassword, setupComplete) with a conservative 200 fallback on error.
  • fix(dev) #374: Add localhost and 127.0.0.1 to allowedDevOrigins in next.config.mjs — HMR websocket was blocked when accessing the app via loopback address, producing repeated cross-origin warnings.

🔧 CI & Infrastructure

  • ESLint OOM fix: eslint.config.mjs now ignores vscode-extension/**, electron/**, docs/**, app/.next/**, and clipr/** — ESLint was crashing with a JS heap OOM by scanning VS Code binary blobs and compiled chunks.
  • Unit test fix: Removed stale ALTER TABLE provider_connections ADD COLUMN "group" from 2 test files — column is now part of the base schema (added in #373), causing SQLITE_ERROR: duplicate column name on every CI run.
  • Pre-commit hook: Added npm run test:unit to .husky/pre-commit — unit tests now block broken commits before they reach CI.

[2.5.3] - 2026-03-14

Critical bugfixes: DB schema migration, startup env loading, provider error state clearing, and i18n tooltip fix. Code quality improvements on top of each PR.

🐛 Bug Fixes (PRs #369, #371, #372, #373 by @kfiramar)

  • fix(db) #373: Add provider_connections.group column to base schema + backfill migration for existing databases — column was used in all queries but missing from schema definition
  • fix(i18n) #371: Replace non-existent t("deleteConnection") key with existing providers.delete key — fixes MISSING_MESSAGE: providers.deleteConnection runtime error on provider detail page
  • fix(auth) #372: Clear stale error metadata (errorCode, lastErrorType, lastErrorSource) from provider accounts after genuine recovery — previously, recovered accounts kept appearing as failed
  • fix(startup) #369: Unify env loading across npm run start, run-standalone.mjs, and Electron to respect DATA_DIR/.env → ~/.omniroute/.env → ./.env priority — prevents generating a new STORAGE_ENCRYPTION_KEY over an existing encrypted database

🔧 Code Quality

  • Documented result.success vs response?.ok patterns in auth.ts (both intentional, now explained)
  • Normalized overridePath?.trim() in electron/main.js to match bootstrap-env.mjs
  • Added preferredEnv merge order comment in Electron startup

Codex account quota policy with auto-rotation, fast tier toggle, gpt-5.4 model, and analytics label fix.

✨ New Features (PRs #366, #367, #368)

  • Codex Quota Policy (PR #366): Per-account 5h/weekly quota window toggles in Provider dashboard. Accounts are automatically skipped when enabled windows reach 90% threshold and re-admitted after resetAt. Includes quotaCache.ts with side-effect free status getter.
  • Codex Fast Tier Toggle (PR #367): Dashboard → Settings → Codex Service Tier. Default-off toggle injects service_tier: "flex" only for Codex requests, reducing cost ~80%. Full stack: UI tab + API endpoint + executor + translator + startup restore.
  • gpt-5.4 Model (PR #368): Adds cx/gpt-5.4 and codex/gpt-5.4 to the Codex model registry. Regression test included.

🐛 Bug Fixes

  • fix #356: Analytics charts (Top Provider, By Account, Provider Breakdown) now display human-readable provider names/labels instead of raw internal IDs for OpenAI-compatible providers.

Major release: strict-random routing strategy, API key access controls, connection groups, external pricing sync, and critical bug fixes for thinking models, combo testing, and tool name validation.

✨ New Features (PRs #363 & #365)

  • Strict-Random Routing Strategy: Fisher-Yates shuffle deck with anti-repeat guarantee and mutex serialization for concurrent requests. Independent decks per combo and per provider.
  • API Key Access Controls: allowedConnections (restrict which connections a key can use), is_active (enable/disable key with 403), accessSchedule (time-based access control), autoResolve toggle, rename keys via PATCH.
  • Connection Groups: Group provider connections by environment. Accordion view in Limits page with localStorage persistence and smart auto-switch.
  • External Pricing Sync (LiteLLM): 3-tier pricing resolution (user overrides → synced → defaults). Opt-in via PRICING_SYNC_ENABLED=true. MCP tool omniroute_sync_pricing. 23 new tests.
  • i18n: 30 languages updated with strict-random strategy, API key management strings. pt-BR fully translated.

🐛 Bug Fixes

  • fix #355: Stream idle timeout increased from 60s to 300s — prevents aborting extended-thinking models (claude-opus-4-6, o3, etc.) during long reasoning phases. Configurable via STREAM_IDLE_TIMEOUT_MS.
  • fix #350: Combo test now bypasses REQUIRE_API_KEY=true using internal header, and uses OpenAI-compatible format universally. Timeout extended from 15s to 20s.
  • fix #346: Tools with empty function.name (forwarded by Claude Code) are now filtered before upstream providers receive them, preventing "Invalid input[N].name: empty string" errors.

🗑️ Closed Issues

  • #341: Debug section removed — replacement is /dashboard/logs and /dashboard/health.

API Key Round-Robin support for multi-key provider setups, and confirmation of wildcard routing and quota window rolling already in place.

✨ New Features

  • API Key Round-Robin (T07): Provider connections can now hold multiple API keys (Edit Connection → Extra API Keys). Requests rotate round-robin between primary + extra keys via providerSpecificData.extraApiKeys[]. Keys are held in-memory indexed per connection — no DB schema changes required.

📝 Already Implemented (confirmed in audit)

  • Wildcard Model Routing (T13): wildcardRouter.ts with glob-style wildcard matching (gpt*, claude-?-sonnet, etc.) is already integrated into model.ts with specificity ranking.
  • Quota Window Rolling (T08): accountFallback.ts:isModelLocked() already auto-advances the window — if Date.now() > entry.until, lock is deleted immediately (no stale blocking).

UI polish, routing strategy additions, and graceful error handling for usage limits.

✨ New Features

  • Fill-First & P2C Routing Strategies: Added fill-first (drain quota before moving on) and p2c (Power-of-Two-Choices low-latency selection) to combo strategy picker, with full guidance panels and color-coded badges.
  • Free Stack Preset Models: Creating a combo with the Free Stack template now auto-fills 7 best-in-class free provider models (Gemini CLI, Kiro, iFlow×2, Qwen, NVIDIA NIM, Groq). Users just activate the providers and get a $0/month combo out-of-the-box.
  • Wider Combo Modal: Create/Edit combo modal now uses max-w-4xl for comfortable editing of large combos.

🐛 Bug Fixes

  • Limits page HTTP 500 for Codex & GitHub: getCodexUsage() and getGitHubUsage() now return a user-friendly message when the provider returns 401/403 (expired token), instead of throwing and causing a 500 error on the Limits page.
  • MaintenanceBanner false-positive: Banner no longer shows "Server is unreachable" spuriously on page load. Fixed by calling checkHealth() immediately on mount and removing stale show-state closure.
  • Provider icon tooltips: Edit (pencil) and delete icon buttons in the provider connection row now have native HTML tooltips — all 6 action icons are now self-documented.

Multiple improvements from community issue analysis, new provider support, bug fixes for token tracking, model routing, and streaming reliability.

✨ New Features

  • Task-Aware Smart Routing (T05): Automatic model selection based on request content type — coding → deepseek-chat, analysis → gemini-2.5-pro, vision → gpt-4o, summarization → gemini-2.5-flash. Configurable via Settings. New GET/PUT/POST /api/settings/task-routing API.
  • HuggingFace Provider: Added HuggingFace Router as an OpenAI-compatible provider with Llama 3.1 70B/8B, Qwen 2.5 72B, Mistral 7B, Phi-3.5 Mini.
  • Vertex AI Provider: Added Vertex AI (Google Cloud) provider with Gemini 2.5 Pro/Flash, Gemma 2 27B, Claude via Vertex.
  • Playground File Uploads: Audio upload for transcription, image upload for vision models (auto-detect by model name), inline image rendering for image generation results.
  • Model Select Visual Feedback: Already-added models in combo picker now show ✓ green badge — prevents duplicate confusion.
  • Qwen Compatibility (PR #352): Updated User-Agent and CLI fingerprint settings for Qwen provider compatibility.
  • Round-Robin State Management (PR #349): Enhanced round-robin logic to handle excluded accounts and maintain rotation state correctly.
  • Clipboard UX (PR #360): Hardened clipboard operations with fallback for non-secure contexts; Claude tool normalization improvements.

🐛 Bug Fixes

  • Fix #302 — OpenAI SDK stream=False drops tool_calls: T01 Accept header negotiation no longer forces streaming when body.stream is explicitly false. Was causing tool_calls to be silently dropped when using the OpenAI Python SDK in non-streaming mode.
  • Fix #73 — Claude Haiku routed to OpenAI without provider prefix: claude-* models sent without a provider prefix now correctly route to the antigravity (Anthropic) provider. Added gemini-*/gemma-*gemini heuristic as well.
  • Fix #74 — Token counts always 0 for Antigravity/Claude streaming: The message_start SSE event which carries input_tokens was not being parsed by extractUsage(), causing all input token counts to drop. Input/output token tracking now works correctly for streaming responses.
  • Fix #180 — Model import duplicates with no feedback: ModelSelectModal now shows ✓ green highlight for models already in the combo, making it obvious they're already added.
  • Media page generation errors: Image results now render as <img> tags instead of raw JSON. Transcription results shown as readable text. Credential errors show an amber banner instead of silent failure.
  • Token refresh button on provider page: Manual token refresh UI added for OAuth providers.

🔧 Improvements

  • Provider Registry: HuggingFace and Vertex AI added to providerRegistry.ts and providers.ts (frontend).
  • Read Cache: New src/lib/db/readCache.ts for efficient DB read caching.
  • Quota Cache: Improved quota cache with TTL-based eviction.

📦 Dependencies

  • dompurify → 3.3.3 (PR #347)
  • undici → 7.24.2 (PR #348, #361)
  • docker/setup-qemu-action → v4 (PR #342)
  • docker/setup-buildx-action → v4 (PR #343)

📁 New Files

File Purpose
open-sse/services/taskAwareRouter.ts Task-aware routing logic (7 task types)
src/app/api/settings/task-routing/route.ts Task routing config API
src/app/api/providers/[id]/refresh/route.ts Manual OAuth token refresh
src/lib/db/readCache.ts Efficient DB read cache
src/shared/utils/clipboard.ts Hardened clipboard with fallback

[2.4.1] - 2026-03-13

🐛 Fix

  • Combos modal: Free Stack visible and prominent — Free Stack template was hidden (4th in 3-column grid). Fixed: moved to position 1, switched to 2x2 grid so all 4 templates are visible, green border + FREE badge highlight.

[2.4.0] - 2026-03-13

Major release — Free Stack ecosystem, transcription playground overhaul, 44+ providers, comprehensive free tier documentation, and UI improvements across the board.

✨ Features

  • Combos: Free Stack template — New 4th template "Free Stack ($0)" using round-robin across Kiro + iFlow + Qwen + Gemini CLI. Suggests the pre-built zero-cost combo on first use.
  • Media/Transcription: Deepgram as default — Deepgram (Nova 3, $200 free) is now the default transcription provider. AssemblyAI ($50 free) and Groq Whisper (free forever) shown with free credit badges.
  • README: "Start Free" section — New early-README 5-step table showing how to set up zero-cost AI in minutes.
  • README: Free Transcription Combo — New section with Deepgram/AssemblyAI/Groq combo suggestion and per-provider free credit details.
  • providers.ts: hasFree flag — NVIDIA NIM, Cerebras, and Groq marked with hasFree badge and freeNote for the providers UI.
  • i18n: templateFreeStack keys — Free Stack combo template translated and synced to all 30 languages.

[2.3.16] - 2026-03-13

📖 Documentation

  • README: 44+ Providers — Updated all 3 occurrences of "36+ providers" to "44+" reflecting the actual codebase count (44 providers in providers.ts)
  • README: New Section "🆓 Free Models — What You Actually Get" — Added 7-provider table with per-model rate limits for: Kiro (Claude unlimited via AWS Builder ID), iFlow (5 models unlimited), Qwen (4 models unlimited), Gemini CLI (180K/mo), NVIDIA NIM (~40 RPM dev-forever), Cerebras (1M tok/day / 60K TPM), Groq (30 RPM / 14.4K RPD). Includes the /usr/bin/bash Ultimate Free Stack combo recommendation.
  • README: Pricing Table Updated — Added Cerebras to API KEY tier, fixed NVIDIA from "1000 credits" to "dev-forever free", updated iFlow/Qwen model counts and names
  • README: iFlow 8→5 models (named: kimi-k2-thinking, qwen3-coder-plus, deepseek-r1, minimax-m2, kimi-k2)
  • README: Qwen 3→4 models (named: qwen3-coder-plus, qwen3-coder-flash, qwen3-coder-next, vision-model)

[2.3.15] - 2026-03-13

✨ Features

  • Auto-Combo Dashboard (Tier Priority): Added 🏷️ Tier as the 7th scoring factor label in the /dashboard/auto-combo factor breakdown display — all 7 Auto-Combo scoring factors are now visible.
  • i18n — autoCombo section: Added 20 new translation keys for the Auto-Combo dashboard (title, status, modePack, providerScores, factorTierPriority, etc.) to all 30 language files.

[2.3.14] - 2026-03-13

🐛 Bug Fixes

  • iFlow OAuth (#339): Restored the valid default clientSecret — was previously an empty string, causing "Bad client credentials" on every connect attempt. The public credential is now the default fallback (overridable via IFLOW_OAUTH_CLIENT_SECRET env var).
  • MITM server not found (#335): prepublish.mjs now compiles src/mitm/*.ts to JavaScript using tsc before copying to the npm bundle. Previously only raw .ts files were copied — meaning server.js never existed in npm/Volta global installs.
  • GeminiCLI missing projectId (#338): Instead of throwing a hard 500 error when projectId is missing from stored credentials (e.g. after Docker restart), OmniRoute now logs a warning and attempts the request — returning a meaningful provider-side error instead of an OmniRoute crash.
  • Electron version mismatch (#323): Synced electron/package.json version to 2.3.13 (was 2.0.13) so the desktop binary version matches the npm package.

✨ New Models (#334)

  • Kiro: claude-sonnet-4, claude-opus-4.6, deepseek-v3.2, minimax-m2.1, qwen3-coder-next, auto
  • Codex: gpt5.4

🔧 Improvements

  • Tier Scoring (API + Validation): Added tierPriority (weight 0.05) to the ScoringWeights Zod schema and the combos/auto API route — the 7th scoring factor is now fully accepted by the REST API and validated on input. stability weight adjusted from 0.10 to 0.05 to keep total sum = 1.0.

✨ New Features

  • Tiered Quota Scoring (Auto-Combo): Added tierPriority as a 7th scoring factor — accounts with Ultra/Pro tiers are now preferred over Free tiers when other factors are equal. New optional fields accountTier and quotaResetIntervalSecs on ProviderCandidate. All 4 mode packs updated (ship-fast, cost-saver, quality-first, offline-friendly).
  • Intra-Family Model Fallback (T5): When a model is unavailable (404/400/403), OmniRoute now automatically falls back to sibling models from the same family before returning an error (modelFamilyFallback.ts).
  • Configurable API Bridge Timeout: API_BRIDGE_PROXY_TIMEOUT_MS env var lets operators tune the proxy timeout (default 30s). Fixes 504 errors on slow upstream responses. (#332)
  • Star History: Replaced star-history.com widget with starchart.cc (?variant=adaptive) in all 30 READMEs — adapts to light/dark theme, real-time updates.

🐛 Bug Fixes

  • Auth — First-time password: INITIAL_PASSWORD env var is now accepted when setting the first dashboard password. Uses timingSafeEqual for constant-time comparison, preventing timing attacks. (#333)
  • README Truncation: Fixed a missing </details> closing tag in the Troubleshooting section that caused GitHub to stop rendering everything below it (Tech Stack, Docs, Roadmap, Contributors).
  • pnpm install: Removed redundant @swc/helpers override from package.json that conflicted with the direct dependency, causing EOVERRIDE errors on pnpm. Added pnpm.onlyBuiltDependencies config.
  • CLI Path Injection (T12): Added isSafePath() validator in cliRuntime.ts to block path traversal and shell metacharacters in CLI_*_BIN env vars.
  • CI: Regenerated package-lock.json after override removal to fix npm ci failures on GitHub Actions.

🔧 Improvements

  • Response Format (T1): response_format (json_schema/json_object) now injected as a system prompt for Claude, enabling structured output compatibility.
  • 429 Retry (T2): Intra-URL retry for 429 responses (2× attempts with 2s delay) before falling back to next URL.
  • Gemini CLI Headers (T3): Added User-Agent and X-Goog-Api-Client fingerprint headers for Gemini CLI compatibility.
  • Pricing Catalog (T9): Added deepseek-3.1, deepseek-3.2, and qwen3-coder-next pricing entries.

📁 New Files

File Purpose
open-sse/services/modelFamilyFallback.ts Model family definitions and intra-family fallback logic

Fixed

  • KiloCode: kilocode healthcheck timeout already fixed in v2.3.11
  • OpenCode: Add opencode to cliRuntime registry with 15s healthcheck timeout
  • OpenClaw / Cursor: Increase healthcheck timeout to 15s for slow-start variants
  • VPS: Install droid and openclaw npm packages; activate CLI_EXTRA_PATHS for kiro-cli
  • cliRuntime: Add opencode tool registration and increase timeout for continue

[2.3.11] - 2026-03-12

Fixed

  • KiloCode healthcheck: Increase healthcheckTimeoutMs from 4000ms to 15000ms — kilocode renders an ASCII logo banner on startup causing false healthcheck_failed on slow/cold-start environments

[2.3.10] - 2026-03-12

Fixed

  • Lint: Fix check:any-budget:t11 failure — replace as any with as Record<string, unknown> in OAuthModal.tsx (3 occurrences)

Docs

  • CLI-TOOLS.md: Complete guide for all 11 CLI tools (claude, codex, gemini, opencode, cline, kilocode, continue, kiro-cli, cursor, droid, openclaw)
  • i18n: CLI-TOOLS.md synced to 30 languages with translated title + intro

[2.3.8] - 2026-03-12

[2.3.9] - 2026-03-12

Added

  • /v1/completions: New legacy OpenAI completions endpoint — accepts both prompt string and messages array, normalizes to chat format automatically
  • EndpointPage: Now shows all 3 OpenAI-compatible endpoint types: Chat Completions, Responses API, and Legacy Completions
  • i18n: Added completionsLegacy/completionsLegacyDesc to 30 language files

Fixed

  • OAuthModal: Fix [object Object] displayed on all OAuth connection errors — properly extract .message from error response objects in all 3 throw new Error(data.error) calls (exchange, device-code, authorize)
  • Affects Cline, Codex, GitHub, Qwen, Kiro, and all other OAuth providers

[2.3.7] - 2026-03-12

Fixed

  • Cline OAuth: Add decodeURIComponent before base64 decode so URL-encoded auth codes from the callback URL are parsed correctly, fixing "invalid or expired authorization code" errors on remote (LAN IP) setups
  • Cline OAuth: mapTokens now populates name = firstName + lastName || email so Cline accounts show real user names instead of "Account #ID"
  • OAuth account names: All OAuth exchange flows (exchange, poll, poll-callback) now normalize name = email when name is missing, so every OAuth account shows its email as the display label in the Providers dashboard
  • OAuth account names: Removed sequential "Account N" fallback in db/providers.ts — accounts with no email/name now use a stable ID-based label via getAccountDisplayName() instead of a sequential number that changes when accounts are deleted

[2.3.6] - 2026-03-12

Fixed

  • Provider test batch: Fixed Zod schema to accept providerId: null (frontend sends null for non-provider modes); was incorrectly returning "Invalid request" for all batch tests
  • Provider test modal: Fixed [object Object] display by normalizing API error objects to strings before rendering in setTestResults and ProviderTestResultsView
  • i18n: Added missing keys cliTools.toolDescriptions.opencode, cliTools.toolDescriptions.kiro, cliTools.guides.opencode, cliTools.guides.kiro to en.json
  • i18n: Synchronized 1111 missing keys across all 29 non-English language files using English values as fallbacks

[2.3.5] - 2026-03-11

Fixed

  • @swc/helpers: Added permanent postinstall fix to copy @swc/helpers into the standalone app's node_modules — prevents MODULE_NOT_FOUND crash on global npm installs

[2.3.4] - 2026-03-10

Added

  • Multiple provider integrations and dashboard improvements

Don't miss a new OmniRoute release

NewReleases is sending notifications on new releases.