# Changelog ## [Unreleased] ## [3.1.8] - 2026-03-27 ### πŸ› Bug Fixes & Features - **Platform Core:** Implemented global state handling for Hidden Models & Combos preventing them from cluttering the catalog or leaking into connected MCP agents (#681). - **Stability:** Patched streaming crashes related to the native Antigravity provider integration failing due to unhandled undefined state arrays (#684). - **Localization Sync:** Deployed a fully overhauled `i18n` synchronizer detecting missing nested JSON properties and retro-fitting 30 locales sequentially (#685).## [3.1.7] - 2026-03-27 ### πŸ› Bug Fixes - **Streaming Stability:** Fixed `hasValuableContent` returning `undefined` for empty chunks in SSE streams (#676). - **Tool Calling:** Fixed an issue in `sseParser.ts` where non-streaming Claude responses with multiple tool calls dropped the `id` of subsequent tool calls due to incorrect index-based deduplication (#671). --- ## [3.1.6] β€” 2026-03-27 ### πŸ› Bug Fixes - **Claude Native Tool Name Restoration** β€” Tool names like `TodoWrite` are no longer prefixed with `proxy_` in Claude passthrough responses (both streaming and non-streaming). Includes unit test coverage (PR #663 by @coobabm) - **Clear All Models Alias Cleanup** β€” "Clear All Models" button now also removes associated model aliases, preventing ghost models in the UI (PR #664 by @rdself) --- ## [3.1.5] β€” 2026-03-27 ### πŸ› Bug Fixes - **Backoff Auto-Decay** β€” Rate-limited accounts now auto-recover when their cooldown window expires, fixing a deadlock where high `backoffLevel` permanently deprioritized accounts (PR #657 by @brendandebeasi) ### 🌍 i18n - **Chinese translation overhaul** β€” Comprehensive rewrite of `zh-CN.json` with improved accuracy (PR #658 by @only4copilot) --- ## [3.1.4] β€” 2026-03-27 ### πŸ› Bug Fixes - **Streaming Override Fix** β€” Explicit `stream: true` in request body now takes priority over `Accept: application/json` header. Clients sending both will correctly receive SSE streaming responses (#656) ### 🌍 i18n - **Czech string improvements** β€” Refined terminology across `cs.json` (PR #655 by @zen0bit) --- ## [3.1.3] β€” 2026-03-26 ### 🌍 i18n & Community - **~70 missing translation keys** added to `en.json` and 12 languages (PR #652 by @zen0bit) - **Czech documentation updated** β€” CLI-TOOLS, API_REFERENCE, VM_DEPLOYMENT guides (PR #652) - **Translation validation scripts** β€” `check_translations.py` and `validate_translation.py` for CI/QA (PR #651 by @zen0bit) --- ## [3.1.2] β€” 2026-03-26 ### πŸ› Bug Fixes - **Critical: Tool Calling Regression** β€” Fixed `proxy_Bash` errors by disabling the `proxy_` tool name prefix in the Claude passthrough path. Tools like `Bash`, `Read`, `Write` were being renamed to `proxy_Bash`, `proxy_Read`, etc., causing Claude to reject them (#618) - **Kiro Account Ban Documentation** β€” Documented as upstream AWS anti-fraud false positive, not an OmniRoute issue (#649) ### πŸ§ͺ Tests - **936 tests, 0 failures** --- ## [3.1.1] β€” 2026-03-26 ### ✨ New Features - **Vision Capability Metadata**: Added `capabilities.vision`, `input_modalities`, and `output_modalities` to `/v1/models` entries for vision-capable models (PR #646) - **Gemini 3.1 Models**: Added `gemini-3.1-pro-preview` and `gemini-3.1-flash-lite-preview` to the Antigravity provider (#645) ### πŸ› Bug Fixes - **Ollama Cloud 401 Error**: Fixed incorrect API base URL β€” changed from `api.ollama.com` to official `ollama.com/v1/chat/completions` (#643) - **Expired Token Retry**: Added bounded retry with exponential backoff (5β†’10β†’20 min) for expired OAuth connections instead of permanently skipping them (PR #647) ### πŸ§ͺ Tests - **936 tests, 0 failures** --- ## [3.1.0] β€” 2026-03-26 ### ✨ New Features - **GitHub Issue Templates**: Added standardized bug report, feature request, and config/proxy issue templates (#641) - **Clear All Models**: Added a "Clear All Models" button to the provider detail page with i18n support in 29 languages (#634) ### πŸ› Bug Fixes - **Locale Conflict (`in.json`)**: Renamed the Hindi locale file from `in.json` (Indonesian ISO code) to `hi.json` to fix translation conflicts in Weblate (#642) - **Codex Empty Tool Names**: Moved tool name sanitization before the native Codex passthrough, fixing 400 errors from upstream providers when tools had empty names (#637) - **Streaming Newline Artifacts**: Added `collapseExcessiveNewlines` to the response sanitizer, collapsing runs of 3+ consecutive newlines from thinking models into a standard double newline (#638) - **Claude Reasoning Effort**: Converted OpenAI `reasoning_effort` param to Claude's native `thinking` budget block across all request paths, including automatic `max_tokens` adjustment (#627) - **Qwen Token Refresh**: Implemented proactive pre-expiry OAuth token refreshes (5-minute buffer) to prevent requests from failing when using short-lived tokens (#631) ### πŸ§ͺ Tests - **936 tests, 0 failures** (+10 tests since 3.0.9) --- ## [3.0.9] β€” 2026-03-26 ### πŸ› Bug Fixes - **NaN tokens in Claude Code / client responses (#617):** - `sanitizeUsage()` now cross-maps `input_tokens`β†’`prompt_tokens` and `output_tokens`β†’`completion_tokens` before the whitelist filter, fixing responses showing NaN/0 token counts when providers return Claude-style usage field names ### πŸ”’ Security - Updated `yaml` package to fix stack overflow vulnerability (GHSA-48c2-rrv3-qjmp) ### πŸ“‹ Issue Triage - Closed #613 (Codestral β€” resolved with Custom Provider workaround) - Commented on #615 (OpenCode dual-endpoint β€” workaround provided, tracked as feature request) - Commented on #618 (tool call visibility β€” requesting v3.0.9 test) - Commented on #627 (effort level β€” already supported) --- ## [3.0.8] β€” 2026-03-25 ### πŸ› Bug Fixes - **Translation Failures for OpenAI-format Providers in Claude CLI (#632):** - Handle `reasoning_details[]` array format from StepFun/OpenRouter β€” converts to `reasoning_content` - Handle `reasoning` field alias from some providers β†’ normalized to `reasoning_content` - Cross-map usage field names: `input_tokens`↔`prompt_tokens`, `output_tokens`↔`completion_tokens` in `filterUsageForFormat` - Fix `extractUsage` to accept both `input_tokens`/`output_tokens` and `prompt_tokens`/`completion_tokens` as valid usage fields - Applied to both streaming (`sanitizeStreamingChunk`, `openai-to-claude.ts` translator) and non-streaming (`sanitizeMessage`) paths --- ## [3.0.7] β€” 2026-03-25 ### πŸ› Bug Fixes - **Antigravity Token Refresh:** Fixed `client_secret is missing` error for npm-installed users β€” the `clientSecretDefault` was empty in providerRegistry, causing Google to reject token refresh requests (#588) - **OpenCode Zen Models:** Added `modelsUrl` to the OpenCode Zen registry entry so "Import from /models" works correctly (#612) - **Streaming Artifacts:** Fixed excessive newlines left in responses after thinking-tag signature stripping (#626) - **Proxy Fallback:** Added automatic retry without proxy when SOCKS5 relay fails - **Proxy Test:** Test endpoint now resolves real credentials from DB via proxyId ### ✨ New Features - **Playground Account/Key Selector:** Persistent, always-visible dropdown to select specific provider accounts/keys for testing β€” fetches all connections at startup and filters by selected provider - **CLI Tools Dynamic Models:** Model selection now dynamically fetches from `/v1/models` API β€” providers like Kiro now show their full model catalog - **Antigravity Model List:** Updated with Claude Sonnet 4.5, Claude Sonnet 4, GPT 5, GPT 5 Mini; enabled `passthroughModels` for dynamic model access (#628) ### πŸ”§ Maintenance - Merged PR #625 β€” Provider Limits light mode background fix --- ## [3.0.6] β€” 2026-03-25 ### πŸ› Bug Fixes - **Limits/Proxy:** Fixed Codex limit fetching for accounts behind SOCKS5 proxies β€” token refresh now runs inside proxy context - **CI:** Fixed integration test `v1/models` assertion failure in CI environments without provider connections - **Settings:** Proxy test button now shows success/failure results immediately (previously hidden behind health data) ### ✨ New Features - **Playground:** Added Account selector dropdown β€” test specific connections individually when a provider has multiple accounts ### πŸ”§ Maintenance - Merged PR #623 β€” LongCat API base URL path correction --- ## [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** β€” `` 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** β€” `` 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/mp4` β†’ `audio/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) - **T01** β€” `requested_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 - **T04** β€” `X-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 - **T11** β€” `max` 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) - **T24** β€” `503` cooldown + `406` mapping - **T25** β€” Provider validation fallback - **T29** β€” Vertex AI Service Account JWT auth - **T33** β€” Thinking level to budget conversion - **T36** β€” `403` 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 ```bash # 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** β€” `` 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.ts`** β€” `validateEnvPath` 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) - **T24** β€” `503` 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. - **T36** β€” `403` 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) - **T01** β€” `requested_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. - **T04** β€” `X-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. - **T11** β€” `max` 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](https://github.com/lobehub/lobe-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\\...` - **#492** β€” `omniroute` 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 files** β€” `claude-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` prefix** β€” `CACHE_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 `` 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/mp4` β†’ `audio/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: `` 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 `machineId` β€” `getMachineIdRaw()` 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 `` 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 `guide` β†’ `mitm` 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 `` 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 - #484 β€” deps: bump flatted from 3.3.3 to 3.4.2 (@dependabot) --- ## [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)**: `` 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 - **deps**: Next.js 16.1.6 β†’ 16.1.7 β€” fixes 6 CVEs: - **Critical**: CVE-2026-29057 (HTTP request smuggling via http-proxy) - **High**: CVE-2026-27977, CVE-2026-27978 (WebSocket + Server Actions) - **Medium**: CVE-2026-27979, CVE-2026-27980, CVE-2026-jcc7 ### πŸ“ 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 (#399 β€” `system_message` field replaces or injects system prompt before forwarding to provider) - **feat(combo)**: Tool Filter Regex per Combo (#399 β€” `tool_filter_regex` keeps only tools matching pattern; supports OpenAI + Anthropic formats) - **feat(combo)**: Context Caching Protection (#401 β€” `context_cache_protection` tags responses with `provider/model` and pins model for session continuity) - **feat(settings)**: Auto-Update via Settings (#320 β€” `GET /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 (#336 β€” `src/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_nodes` β€” `buildDynamicEmbeddingProvider()` with hostname validation (#422, @Regis-RCR) - **feat(audio)**: Route TTS/STT to local `provider_nodes` β€” `buildDynamicAudioProvider()` 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 - Bump `vitest`, `@vitest/*` and related devDependencies (#414, @dependabot) --- ## [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-instruct` β†’ `meta/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-instruct` β†’ `nvidia/meta/llama-3.3-70b-instruct`, corrected `gemini/gemini-3.1-flash` β†’ `gemini/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](https://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-')` β€” 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 `` 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 `` 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` 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