From 673b2947b3d50850cfde58fa9ffbce8629a5a685 Mon Sep 17 00:00:00 2001 From: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> Date: Sun, 23 Aug 2026 20:12:02 -0300 Subject: [PATCH] fix(release): close final v3.8.50 reconciliation gaps (#8875) --- CHANGELOG.md | 28 +- bin/cli/commands/combo.mjs | 36 ++- bin/cli/commands/compression.mjs | 63 ++-- bin/cli/commands/mcp.mjs | 155 ++------- bin/cli/commands/oneproxy.mjs | 59 ++-- bin/cli/commands/skills.mjs | 2 +- bin/cli/mcpClient.mjs | 44 ++- .../11282-first-run-readiness-card.md | 1 - .../fixes/11271-ollama-capability-routing.md | 1 - config/quality/eslint-suppressions.json | 2 +- docs/i18n/ar/CHANGELOG.md | 28 +- docs/i18n/az/CHANGELOG.md | 28 +- docs/i18n/bg/CHANGELOG.md | 28 +- docs/i18n/bn/CHANGELOG.md | 28 +- docs/i18n/cs/CHANGELOG.md | 28 +- docs/i18n/da/CHANGELOG.md | 28 +- docs/i18n/de/CHANGELOG.md | 28 +- docs/i18n/es/CHANGELOG.md | 28 +- docs/i18n/fa/CHANGELOG.md | 28 +- docs/i18n/fi/CHANGELOG.md | 28 +- docs/i18n/fr/CHANGELOG.md | 28 +- docs/i18n/gu/CHANGELOG.md | 28 +- docs/i18n/he/CHANGELOG.md | 28 +- docs/i18n/hi/CHANGELOG.md | 28 +- docs/i18n/hu/CHANGELOG.md | 28 +- docs/i18n/id/CHANGELOG.md | 28 +- docs/i18n/in/CHANGELOG.md | 28 +- docs/i18n/it/CHANGELOG.md | 28 +- docs/i18n/ja/CHANGELOG.md | 28 +- docs/i18n/ko/CHANGELOG.md | 28 +- docs/i18n/mr/CHANGELOG.md | 28 +- docs/i18n/ms/CHANGELOG.md | 28 +- docs/i18n/nl/CHANGELOG.md | 28 +- docs/i18n/no/CHANGELOG.md | 28 +- docs/i18n/phi/CHANGELOG.md | 28 +- docs/i18n/pl/CHANGELOG.md | 28 +- docs/i18n/pt-BR/CHANGELOG.md | 28 +- docs/i18n/pt/CHANGELOG.md | 28 +- docs/i18n/ro/CHANGELOG.md | 28 +- docs/i18n/ru/CHANGELOG.md | 28 +- docs/i18n/sk/CHANGELOG.md | 28 +- docs/i18n/sv/CHANGELOG.md | 28 +- docs/i18n/sw/CHANGELOG.md | 28 +- docs/i18n/ta/CHANGELOG.md | 28 +- docs/i18n/te/CHANGELOG.md | 28 +- docs/i18n/th/CHANGELOG.md | 28 +- docs/i18n/tr/CHANGELOG.md | 28 +- docs/i18n/uk-UA/CHANGELOG.md | 28 +- docs/i18n/ur/CHANGELOG.md | 28 +- docs/i18n/vi/CHANGELOG.md | 28 +- docs/i18n/zh-CN/CHANGELOG.md | 28 +- docs/i18n/zh-TW/CHANGELOG.md | 28 +- open-sse/executors/base/reasoningEffort.ts | 7 +- open-sse/mcp-server/tools/skillTools.ts | 62 +++- open-sse/services/autoCombo/virtualFactory.ts | 10 +- open-sse/services/combo/providerWildcard.ts | 7 +- src/app/api/providers/[id]/models/route.ts | 30 +- src/app/api/v1/images/generations/route.ts | 22 +- .../vertexAnthropicModelsParser.ts | 14 +- src/sse/services/imageCredentialRetry.ts | 26 +- tests/unit/cli-combo-suggest-commands.test.ts | 61 ++-- tests/unit/cli-compression-commands.test.ts | 84 ++++- tests/unit/cli-mcp-call-commands.test.ts | 299 ++++++++++++++---- tests/unit/cli-oneproxy-commands.test.ts | 58 +++- tests/unit/cli-resilience-commands.test.ts | 5 +- tests/unit/cli-skills-commands.test.ts | 23 +- .../unit/combo-auto-pool-visible-only.test.ts | 53 +++- tests/unit/combo-provider-wildcard.test.ts | 19 ++ tests/unit/conol-web.test.ts | 3 +- ...redential-health-disabled-boot-log.test.ts | 8 +- tests/unit/executor-promptql.test.ts | 61 ++-- tests/unit/gemini-strict-tool-schema.test.ts | 5 +- tests/unit/helpers/mcpStreamMock.ts | 23 +- tests/unit/home-page-static.test.ts | 13 +- ...ge-credential-retry-endpoint-scope.test.ts | 24 ++ .../ollama-local-capabilities-routing.test.ts | 5 +- ...pencode-go-console-go-effort-clamp.test.ts | 23 +- .../unit/translator-openai-to-gemini.test.ts | 6 +- .../translator-resp-gemini-to-openai.test.ts | 5 +- tests/unit/vertex-anthropic-models.test.ts | 48 ++- 80 files changed, 1667 insertions(+), 904 deletions(-) delete mode 100644 changelog.d/features/11282-first-run-readiness-card.md delete mode 100644 changelog.d/fixes/11271-ollama-capability-routing.md create mode 100644 tests/unit/image-credential-retry-endpoint-scope.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 2aa555f7d8..22de083e47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/bin/cli/commands/combo.mjs b/bin/cli/commands/combo.mjs index 639632eafd..9a02fb4a18 100644 --- a/bin/cli/commands/combo.mjs +++ b/bin/cli/commands/combo.mjs @@ -43,6 +43,21 @@ const suggestSchema = [ }, ]; +const TASK_TYPES = ["coding", "review", "planning", "analysis", "debugging", "documentation"]; + +function normalizeTaskType(value) { + const normalized = String(value || "") + .trim() + .toLowerCase(); + if (TASK_TYPES.includes(normalized)) return normalized; + if (/debug|bug|error|fix/.test(normalized)) return "debugging"; + if (/review|audit/.test(normalized)) return "review"; + if (/plan|architect|design/.test(normalized)) return "planning"; + if (/doc|readme|guide/.test(normalized)) return "documentation"; + if (/code|implement|program/.test(normalized)) return "coding"; + return "analysis"; +} + export function extendComboSuggest(combo) { combo .command("suggest") @@ -50,29 +65,28 @@ export function extendComboSuggest(combo) { .requiredOption("--task ", t("combo.suggest.task")) .option("--max-cost ", t("combo.suggest.maxCost"), parseFloat) .option("--max-latency-ms ", t("combo.suggest.maxLatencyMs"), parseInt) - .option("--weights ", t("combo.suggest.weights")) .option("--top ", t("combo.suggest.top"), parseInt, 5) .option("--explain", t("combo.suggest.explain")) .option("--switch", t("combo.suggest.switch")) .action(async (opts, cmd) => { const body = { - task: opts.task, - constraints: { - maxCostUsd: opts.maxCost, - maxLatencyMs: opts.maxLatencyMs, - }, - weights: opts.weights ? JSON.parse(opts.weights) : undefined, - top: opts.top, + taskType: normalizeTaskType(opts.task), + budgetConstraint: opts.maxCost, + latencyConstraint: opts.maxLatencyMs, }; const data = await mcpCallTool("omniroute_best_combo_for_task", body); - const candidates = data.candidates ?? data; - const rows = (Array.isArray(candidates) ? candidates : []).map((c, i) => ({ + const candidates = data.recommendedCombo + ? [data.recommendedCombo, ...(Array.isArray(data.alternatives) ? data.alternatives : [])] + : (data.candidates ?? data); + const rows = (Array.isArray(candidates) ? candidates : []).slice(0, opts.top).map((c, i) => ({ rank: i + 1, ...c, })); emit(rows, cmd.optsWithGlobals(), suggestSchema); if (opts.explain && !cmd.optsWithGlobals().quiet) { - process.stderr.write(`\nRationale:\n${data.rationale ?? "(no rationale)"}\n`); + process.stderr.write( + `\nRationale:\n${data.recommendedCombo?.reason ?? data.rationale ?? "(no rationale)"}\n` + ); } if (opts.switch && rows[0]) { const best = rows[0].name; diff --git a/bin/cli/commands/compression.mjs b/bin/cli/commands/compression.mjs index 2d4b3db43b..4785cb556a 100644 --- a/bin/cli/commands/compression.mjs +++ b/bin/cli/commands/compression.mjs @@ -107,21 +107,35 @@ export async function runCompressionStatus(opts, cmd) { export async function runCompressionConfigure(opts, cmd) { const config = {}; - // #6571 — both the MCP tool schema (compressionConfigureInput) and - // handleCompressionConfigure expect `strategy`, not `engine`; a non-strict - // MCP schema silently strips an unrecognized `engine` key on the primary - // (MCP-mounted) path, so this must be `strategy` on both paths. - if (opts.engine) config.strategy = normalizeEngine(opts.engine); - if (opts.cavemanAggressiveness !== undefined) - config.caveman = { aggressiveness: opts.cavemanAggressiveness }; - if (opts.rtkBudget !== undefined) config.rtk = { tokenBudget: opts.rtkBudget }; - if (opts.languagePack) config.languagePack = opts.languagePack; + // Keep this payload byte-for-byte within compressionConfigureInput. Engine- + // specific Caveman/RTK controls belong to `compression engine set`, whose + // MCP tool has a different schema. + const strategy = opts.strategy ?? opts.engine; + if (strategy) config.strategy = normalizeEngine(strategy); + for (const key of [ + "enabled", + "autoTriggerMode", + "maxTokens", + "targetRatio", + "preserveSystemPrompt", + "mcpDescriptionCompressionEnabled", + ]) { + if (opts[key] !== undefined) config[key] = opts[key]; + } const data = await mcpCall("omniroute_compression_configure", config, () => restCompressionConfigure(config) ); emit(data, cmd.optsWithGlobals()); } +export async function runCompressionComboStats(opts, cmd) { + const since = opts.period ?? "7d"; + const data = await mcpCall("omniroute_compression_combo_stats", { since }, () => + restComboStats(since) + ); + emit(data, cmd.optsWithGlobals()); +} + export async function runCompressionEngineSet(name, opts, cmd) { const normalized = normalizeEngine(name); if (!VALID_ENGINES.includes(normalized)) { @@ -161,10 +175,21 @@ export function registerCompression(program) { cmp .command("configure") .description(t("compression.configure.description")) - .option("--engine ", t("compression.configure.engine")) - .option("--caveman-aggressiveness ", t("compression.configure.caveman_agg"), parseFloat) - .option("--rtk-budget ", t("compression.configure.rtk_budget"), parseInt) - .option("--language-pack

", t("compression.configure.language_pack")) + .option("--strategy ", t("compression.configure.engine")) + .option("--enabled ", "Enable or disable compression", (value) => value === "true") + .option("--auto-trigger-mode ", "Compression mode used by automatic triggering") + .option("--max-tokens ", "Maximum tokens before compression triggers", parseInt) + .option("--target-ratio ", "Target compression ratio (0.0-1.0)", parseFloat) + .option( + "--preserve-system-prompt ", + "Preserve the system prompt", + (value) => value === "true" + ) + .option( + "--mcp-description-compression-enabled ", + "Compress MCP tool descriptions", + (value) => value === "true" + ) .action(runCompressionConfigure); const engine = cmp.command("engine").description(t("compression.engine.description")); @@ -181,17 +206,7 @@ export function registerCompression(program) { })); emit(data.combos ?? data, cmd.optsWithGlobals()); }); - combos - .command("stats") - .option("--period

", null, "7d") - .action(async (opts, cmd) => { - const data = await mcpCall( - "omniroute_compression_combo_stats", - { period: opts.period ?? "7d" }, - () => restComboStats(opts.period) - ); - emit(data, cmd.optsWithGlobals()); - }); + combos.command("stats").option("--period

", null, "7d").action(runCompressionComboStats); const rules = cmp.command("rules").description(t("compression.rules.description")); rules.command("list").action(async (opts, cmd) => { diff --git a/bin/cli/commands/mcp.mjs b/bin/cli/commands/mcp.mjs index c4ce9fbda8..dd8210fce0 100644 --- a/bin/cli/commands/mcp.mjs +++ b/bin/cli/commands/mcp.mjs @@ -1,5 +1,6 @@ import { readFileSync } from "node:fs"; import { apiFetch, isServerUp } from "../api.mjs"; +import { mcpCallTool } from "../mcpClient.mjs"; import { emit } from "../output.mjs"; import { t } from "../i18n.mjs"; @@ -61,10 +62,15 @@ export function registerMcp(program) { ? JSON.parse(argsPositional) : {}; - const exitCode = await runMcpCallCommand(tool, args, { - ...opts, - stream: opts.stream, - }, globalOpts); + const exitCode = await runMcpCallCommand( + tool, + args, + { + ...opts, + stream: opts.stream, + }, + globalOpts + ); if (exitCode !== 0) process.exit(exitCode); }); @@ -86,130 +92,25 @@ export function registerMcp(program) { }); } -/** - * Shared JSON-RPC 2.0 MCP client used by both stream and non-stream `mcp call`. - * - * Protocol: - * 1. POST /api/mcp/stream with initialize → get Mcp-Session-Id header - * 2. POST /api/mcp/stream with tools/call + Mcp-Session-Id header - * - * When `stream` is true, writes SSE data chunks to stdout as they arrive. - * When `stream` is false, returns the parsed JSON-RPC result. - * - * Returns the exit code (0 = success, non-zero = failure). - */ -async function mcpJsonRpcCall(tool, args, { stream = false, globalOpts = {} } = {}) { - const baseUrl = globalOpts.baseUrl ?? "http://localhost:20128"; - const apiKey = globalOpts.apiKey ?? ""; - const streamUrl = `${baseUrl}/api/mcp/stream`; - - const hdrs = { - "Content-Type": "application/json", - Accept: stream ? "text/event-stream" : "application/json", - ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}), - }; - - // Step 1 — initialize - const initRes = await fetch(streamUrl, { - method: "POST", - headers: hdrs, - body: JSON.stringify({ - jsonrpc: "2.0", - id: 1, - method: "initialize", - params: { - protocolVersion: "2024-11-05", - capabilities: {}, - clientInfo: { name: "omniroute-cli", version: "1.0" }, - }, - }), - }); - - if (!initRes.ok) { - const text = await initRes.text().catch(() => ""); - process.stderr.write(`MCP initialize failed: HTTP ${initRes.status}${text ? ` — ${text}` : ""}\n`); - return 1; - } - - const sessionId = initRes.headers.get("mcp-session-id"); - if (!sessionId) { - process.stderr.write("MCP initialize failed: no Mcp-Session-Id in response\n"); - return 1; - } - - // Step 2 — tools/call - const callHeaders = { - ...hdrs, - "mcp-session-id": sessionId, - }; - - const callRes = await fetch(streamUrl, { - method: "POST", - headers: callHeaders, - body: JSON.stringify({ - jsonrpc: "2.0", - id: 2, - method: "tools/call", - params: { name: tool, arguments: args }, - }), - }); - - if (!callRes.ok) { - const text = await callRes.text().catch(() => ""); - process.stderr.write(`MCP call failed: HTTP ${callRes.status}${text ? ` — ${text}` : ""}\n`); - return 1; - } - - if (stream) { - return readMcpSseStream(callRes.body); - } - - // Non-stream: parse JSON-RPC response - const data = await callRes.json(); - if (data.error) { - process.stderr.write(`MCP error: ${data.error.message || JSON.stringify(data.error)}\n`); - return 1; - } - // Print the result content - const content = data.result?.content; - if (content) { - for (const item of content) { - if (item.type === "text") { - process.stdout.write(item.text + "\n"); - } else if (item.type === "resource") { - process.stdout.write(JSON.stringify(item.resource) + "\n"); - } else { - process.stdout.write(JSON.stringify(item) + "\n"); - } - } - } else { - process.stdout.write(JSON.stringify(data.result, null, 2) + "\n"); - } - return 0; -} - -async function readMcpSseStream(body) { - if (!body) return 1; - const reader = body.getReader(); - const dec = new TextDecoder(); - let buf = ""; - while (true) { - const { done, value } = await reader.read(); - if (done) break; - buf += dec.decode(value, { stream: true }); - } - const lines = buf.split("\n"); - for (const line of lines) { - if (line.startsWith("data: ")) { - const raw = line.slice(6).trim(); - if (raw && raw !== "[DONE]") process.stdout.write(raw + "\n"); - } - } - return 0; -} - export async function runMcpCallCommand(tool, args, opts = {}, globalOpts = {}) { - return mcpJsonRpcCall(tool, args, { stream: opts.stream, globalOpts }); + try { + const result = await mcpCallTool(tool, args, { + ...globalOpts, + ...opts, + stream: opts.stream === true, + timeout: opts.timeout ?? globalOpts.timeout, + }); + + if (!opts.stream) { + if (typeof result === "string") process.stdout.write(`${result}\n`); + else emit(result, globalOpts); + } + return 0; + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + process.stderr.write(`MCP call failed: ${message}\n`); + return typeof err?.exitCode === "number" ? err.exitCode : 1; + } } export async function runMcpStatusCommand(opts = {}) { diff --git a/bin/cli/commands/oneproxy.mjs b/bin/cli/commands/oneproxy.mjs index c3d5b6ca32..b9e16d3427 100644 --- a/bin/cli/commands/oneproxy.mjs +++ b/bin/cli/commands/oneproxy.mjs @@ -26,48 +26,47 @@ const proxySchema = [ { key: "state", header: "State" }, ]; +export async function runOneproxyStats(_opts, cmd) { + const data = await mcpCall("omniroute_oneproxy_stats", {}); + emit(data, cmd.optsWithGlobals()); +} + +export async function runOneproxyFetch(opts, cmd) { + const data = await mcpCall("omniroute_oneproxy_fetch", { + limit: opts.count, + protocol: opts.type, + ...(opts.countryCode ? { countryCode: opts.countryCode } : {}), + ...(opts.minQuality !== undefined ? { minQuality: opts.minQuality } : {}), + }); + emit(data.items ?? data, cmd.optsWithGlobals(), proxySchema); +} + +export async function runOneproxyRotate(opts, cmd) { + const data = await mcpCall("omniroute_oneproxy_rotate", { + ...(opts.strategy ? { strategy: opts.strategy } : {}), + }); + emit(data, cmd.optsWithGlobals()); +} + export function registerOneProxy(program) { const op = program.command("oneproxy").description(t("oneproxy.description")); - op.command("status").action(async (opts, cmd) => { - const data = await mcpCall("omniroute_oneproxy_stats", {}); - emit(data, cmd.optsWithGlobals()); - }); + op.command("status").action(runOneproxyStats); - op.command("stats") - .option("--provider

", t("oneproxy.stats.provider")) - .option("--period

", t("oneproxy.stats.period"), "24h") - .action(async (opts, cmd) => { - const data = await mcpCall("omniroute_oneproxy_stats", { - provider: opts.provider, - period: opts.period, - }); - emit(data, cmd.optsWithGlobals()); - }); + op.command("stats").action(runOneproxyStats); op.command("fetch") .description(t("oneproxy.fetch.description")) .option("--count ", t("oneproxy.fetch.count"), parseInt, 1) .option("--type ", t("oneproxy.fetch.type"), "http") - .action(async (opts, cmd) => { - const data = await mcpCall("omniroute_oneproxy_fetch", { - count: opts.count, - type: opts.type, - }); - emit(data.proxies ?? data, cmd.optsWithGlobals(), proxySchema); - }); + .option("--country-code ", "Filter by country code") + .option("--min-quality ", "Minimum quality score (0-100)", parseFloat) + .action(runOneproxyFetch); op.command("rotate") .description(t("oneproxy.rotate.description")) - .option("--provider

", t("oneproxy.rotate.provider")) - .option("--connection-id ", t("oneproxy.rotate.connectionId")) - .action(async (opts, cmd) => { - const data = await mcpCall("omniroute_oneproxy_rotate", { - provider: opts.provider, - connectionId: opts.connectionId, - }); - emit(data, cmd.optsWithGlobals()); - }); + .option("--strategy ", "Rotation strategy: random, quality, or sequential") + .action(runOneproxyRotate); const config = op.command("config").description(t("oneproxy.config.description")); diff --git a/bin/cli/commands/skills.mjs b/bin/cli/commands/skills.mjs index 386f5e9b48..c942f45dbe 100644 --- a/bin/cli/commands/skills.mjs +++ b/bin/cli/commands/skills.mjs @@ -143,7 +143,7 @@ export async function runSkillsExecute(id, opts, cmd) { const data = await mcpCallTool( "omniroute_skills_execute", { skillId: id, input }, - { timeout: opts.timeout ?? 30000 }, + { timeout: opts.timeout ?? 30000 } ); emit(data, globalOpts); } diff --git a/bin/cli/mcpClient.mjs b/bin/cli/mcpClient.mjs index 33aace3493..65a1a33ab0 100644 --- a/bin/cli/mcpClient.mjs +++ b/bin/cli/mcpClient.mjs @@ -20,20 +20,24 @@ function mcpError(message, status) { return err; } -async function callMcpEndpoint(payload, { timeout, stream }) { +async function callMcpEndpoint(payload, { timeout, stream, headers = {}, ...apiOptions }) { const res = await apiFetch("/api/mcp/stream", { + ...apiOptions, method: "POST", body: payload, timeout, acceptNotOk: true, - headers: stream ? { Accept: "text/event-stream" } : {}, + headers: { + ...(stream ? { Accept: "text/event-stream" } : {}), + ...headers, + }, }); if (!res.ok) { const text = await res.text().catch(() => ""); throw mcpError( `${payload.method} ${payload.id}: HTTP ${res.status}${text ? ` — ${text}` : ""}`, - res.status, + res.status ); } return res; @@ -46,7 +50,7 @@ async function callMcpEndpoint(payload, { timeout, stream }) { * Stream: writes SSE `data:` chunks to stdout and returns null on success. */ export async function mcpCallTool(name, args = {}, options = {}) { - const { timeout, scope } = options; + const { scope, stream, onChunk, ...apiOptions } = options; const scopeHeader = scope?.length ? { "X-MCP-Scopes": scope.join(",") } : {}; const initRes = await callMcpEndpoint( @@ -60,7 +64,7 @@ export async function mcpCallTool(name, args = {}, options = {}) { clientInfo: { name: "omniroute-cli", version: "1.0" }, }, }, - { timeout, stream: options.stream }, + { ...apiOptions, stream, headers: scopeHeader } ); const sessionId = initRes.headers.get("mcp-session-id"); @@ -75,11 +79,15 @@ export async function mcpCallTool(name, args = {}, options = {}) { method: "tools/call", params: { name, arguments: args }, }, - { timeout, stream: options.stream }, + { + ...apiOptions, + stream, + headers: { ...scopeHeader, "mcp-session-id": sessionId }, + } ); - if (options.stream) { - return consumeSse(callRes.body, options.onChunk); + if (stream) { + return consumeSse(callRes.body, onChunk); } const data = await callRes.json(); @@ -92,7 +100,25 @@ export async function mcpCallTool(name, args = {}, options = {}) { const msg = data.result?.content?.[0]?.text || "unknown tool error"; throw mcpError(`MCP error: ${msg}`, 500); } - return data.result; + return decodeToolResult(data.result); +} + +function decodeToolResult(result) { + if (!result || typeof result !== "object") return result; + if (result.structuredContent && typeof result.structuredContent === "object") { + return result.structuredContent; + } + + const textItems = Array.isArray(result.content) + ? result.content.filter((item) => item?.type === "text" && typeof item.text === "string") + : []; + if (textItems.length !== 1) return result; + + try { + return JSON.parse(textItems[0].text); + } catch { + return textItems[0].text; + } } async function consumeSse(body, onChunk) { diff --git a/changelog.d/features/11282-first-run-readiness-card.md b/changelog.d/features/11282-first-run-readiness-card.md deleted file mode 100644 index e2899a54e5..0000000000 --- a/changelog.d/features/11282-first-run-readiness-card.md +++ /dev/null @@ -1 +0,0 @@ -- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282)) diff --git a/changelog.d/fixes/11271-ollama-capability-routing.md b/changelog.d/fixes/11271-ollama-capability-routing.md deleted file mode 100644 index 3846f4f0b9..0000000000 --- a/changelog.d/fixes/11271-ollama-capability-routing.md +++ /dev/null @@ -1 +0,0 @@ -- **fix(ollama):** Ollama Local models are no longer flattened to `chat` at sync time — the synced store persists every advertised capability and chat filtering moves to read time, so `/v1/embeddings` and `/v1/images/generations` stop rejecting models the daemon reports as capable ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271)) — thanks @yourspraveen diff --git a/config/quality/eslint-suppressions.json b/config/quality/eslint-suppressions.json index 3622b23588..18dd6123a9 100644 --- a/config/quality/eslint-suppressions.json +++ b/config/quality/eslint-suppressions.json @@ -4733,7 +4733,7 @@ }, "tests/unit/cli-mcp-call-commands.test.ts": { "@typescript-eslint/no-explicit-any": { - "count": 16 + "count": 14 } }, "tests/unit/cli-memory-commands.test.ts": { diff --git a/docs/i18n/ar/CHANGELOG.md b/docs/i18n/ar/CHANGELOG.md index baf8e28985..219d1b4525 100644 --- a/docs/i18n/ar/CHANGELOG.md +++ b/docs/i18n/ar/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/az/CHANGELOG.md b/docs/i18n/az/CHANGELOG.md index 385daf688d..f73d144299 100644 --- a/docs/i18n/az/CHANGELOG.md +++ b/docs/i18n/az/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/bg/CHANGELOG.md b/docs/i18n/bg/CHANGELOG.md index 385daf688d..f73d144299 100644 --- a/docs/i18n/bg/CHANGELOG.md +++ b/docs/i18n/bg/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/bn/CHANGELOG.md b/docs/i18n/bn/CHANGELOG.md index 874b5846bb..6d33a2aed6 100644 --- a/docs/i18n/bn/CHANGELOG.md +++ b/docs/i18n/bn/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/cs/CHANGELOG.md b/docs/i18n/cs/CHANGELOG.md index aed5cfde33..3038a99f77 100644 --- a/docs/i18n/cs/CHANGELOG.md +++ b/docs/i18n/cs/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/da/CHANGELOG.md b/docs/i18n/da/CHANGELOG.md index d08c89cd2a..667b27196b 100644 --- a/docs/i18n/da/CHANGELOG.md +++ b/docs/i18n/da/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/de/CHANGELOG.md b/docs/i18n/de/CHANGELOG.md index 173ca1c543..2cb1970c18 100644 --- a/docs/i18n/de/CHANGELOG.md +++ b/docs/i18n/de/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/es/CHANGELOG.md b/docs/i18n/es/CHANGELOG.md index 0c5bf410c3..894decf9cd 100644 --- a/docs/i18n/es/CHANGELOG.md +++ b/docs/i18n/es/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/fa/CHANGELOG.md b/docs/i18n/fa/CHANGELOG.md index eec454a5bf..6a7a8e204a 100644 --- a/docs/i18n/fa/CHANGELOG.md +++ b/docs/i18n/fa/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/fi/CHANGELOG.md b/docs/i18n/fi/CHANGELOG.md index c5815fbe44..f1e9fb6b45 100644 --- a/docs/i18n/fi/CHANGELOG.md +++ b/docs/i18n/fi/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/fr/CHANGELOG.md b/docs/i18n/fr/CHANGELOG.md index 93eb2e8447..2006dc792c 100644 --- a/docs/i18n/fr/CHANGELOG.md +++ b/docs/i18n/fr/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/gu/CHANGELOG.md b/docs/i18n/gu/CHANGELOG.md index bfda53a345..61a14076df 100644 --- a/docs/i18n/gu/CHANGELOG.md +++ b/docs/i18n/gu/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/he/CHANGELOG.md b/docs/i18n/he/CHANGELOG.md index 2ab2cf5712..b67b40819d 100644 --- a/docs/i18n/he/CHANGELOG.md +++ b/docs/i18n/he/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/hi/CHANGELOG.md b/docs/i18n/hi/CHANGELOG.md index cca05a33e3..a1661ef5a2 100644 --- a/docs/i18n/hi/CHANGELOG.md +++ b/docs/i18n/hi/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/hu/CHANGELOG.md b/docs/i18n/hu/CHANGELOG.md index 7236c31865..467d72edf4 100644 --- a/docs/i18n/hu/CHANGELOG.md +++ b/docs/i18n/hu/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/id/CHANGELOG.md b/docs/i18n/id/CHANGELOG.md index e3f8ef6194..8993cedb3e 100644 --- a/docs/i18n/id/CHANGELOG.md +++ b/docs/i18n/id/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/in/CHANGELOG.md b/docs/i18n/in/CHANGELOG.md index 50f125ebe6..94c74579aa 100644 --- a/docs/i18n/in/CHANGELOG.md +++ b/docs/i18n/in/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/it/CHANGELOG.md b/docs/i18n/it/CHANGELOG.md index de0b3bbc0f..4f7d43be54 100644 --- a/docs/i18n/it/CHANGELOG.md +++ b/docs/i18n/it/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/ja/CHANGELOG.md b/docs/i18n/ja/CHANGELOG.md index d861a2c275..c2fd4ac6b4 100644 --- a/docs/i18n/ja/CHANGELOG.md +++ b/docs/i18n/ja/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/ko/CHANGELOG.md b/docs/i18n/ko/CHANGELOG.md index 53415c346a..6e4d1b0984 100644 --- a/docs/i18n/ko/CHANGELOG.md +++ b/docs/i18n/ko/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/mr/CHANGELOG.md b/docs/i18n/mr/CHANGELOG.md index 43a4ba936a..57b00c96c1 100644 --- a/docs/i18n/mr/CHANGELOG.md +++ b/docs/i18n/mr/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/ms/CHANGELOG.md b/docs/i18n/ms/CHANGELOG.md index 2123c72695..2f87d24dbd 100644 --- a/docs/i18n/ms/CHANGELOG.md +++ b/docs/i18n/ms/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/nl/CHANGELOG.md b/docs/i18n/nl/CHANGELOG.md index 88d2dfb2eb..94ed212361 100644 --- a/docs/i18n/nl/CHANGELOG.md +++ b/docs/i18n/nl/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/no/CHANGELOG.md b/docs/i18n/no/CHANGELOG.md index 04465f0fad..dcb72397d3 100644 --- a/docs/i18n/no/CHANGELOG.md +++ b/docs/i18n/no/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/phi/CHANGELOG.md b/docs/i18n/phi/CHANGELOG.md index d3bbbec20c..156426a6d4 100644 --- a/docs/i18n/phi/CHANGELOG.md +++ b/docs/i18n/phi/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/pl/CHANGELOG.md b/docs/i18n/pl/CHANGELOG.md index f089a728e5..c51c32d1e1 100644 --- a/docs/i18n/pl/CHANGELOG.md +++ b/docs/i18n/pl/CHANGELOG.md @@ -302,6 +302,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -836,7 +838,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1066,7 +1067,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1170,7 +1171,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1232,6 +1232,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1520,6 +1525,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1530,7 +1536,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1558,7 +1564,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1621,7 +1627,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1653,12 +1659,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1671,6 +1678,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1699,7 +1707,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1765,9 +1773,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/pt-BR/CHANGELOG.md b/docs/i18n/pt-BR/CHANGELOG.md index 340f5f621e..db0d0e24eb 100644 --- a/docs/i18n/pt-BR/CHANGELOG.md +++ b/docs/i18n/pt-BR/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/pt/CHANGELOG.md b/docs/i18n/pt/CHANGELOG.md index e1cb18e037..789b00f76f 100644 --- a/docs/i18n/pt/CHANGELOG.md +++ b/docs/i18n/pt/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/ro/CHANGELOG.md b/docs/i18n/ro/CHANGELOG.md index 522fe853d1..8f2f70f0b2 100644 --- a/docs/i18n/ro/CHANGELOG.md +++ b/docs/i18n/ro/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/ru/CHANGELOG.md b/docs/i18n/ru/CHANGELOG.md index bbbf7e30aa..08d5b7bd11 100644 --- a/docs/i18n/ru/CHANGELOG.md +++ b/docs/i18n/ru/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/sk/CHANGELOG.md b/docs/i18n/sk/CHANGELOG.md index d61f300a97..944f9c1b1d 100644 --- a/docs/i18n/sk/CHANGELOG.md +++ b/docs/i18n/sk/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/sv/CHANGELOG.md b/docs/i18n/sv/CHANGELOG.md index 7b17670a7c..f0a9474f6f 100644 --- a/docs/i18n/sv/CHANGELOG.md +++ b/docs/i18n/sv/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/sw/CHANGELOG.md b/docs/i18n/sw/CHANGELOG.md index 99f760b3cf..fc36884e6d 100644 --- a/docs/i18n/sw/CHANGELOG.md +++ b/docs/i18n/sw/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/ta/CHANGELOG.md b/docs/i18n/ta/CHANGELOG.md index e798684abb..28fae55f49 100644 --- a/docs/i18n/ta/CHANGELOG.md +++ b/docs/i18n/ta/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/te/CHANGELOG.md b/docs/i18n/te/CHANGELOG.md index e3d8155756..63b9963989 100644 --- a/docs/i18n/te/CHANGELOG.md +++ b/docs/i18n/te/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/th/CHANGELOG.md b/docs/i18n/th/CHANGELOG.md index 2052b89c5d..003ad2df92 100644 --- a/docs/i18n/th/CHANGELOG.md +++ b/docs/i18n/th/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/tr/CHANGELOG.md b/docs/i18n/tr/CHANGELOG.md index 6a12b538e9..9f9ed64da1 100644 --- a/docs/i18n/tr/CHANGELOG.md +++ b/docs/i18n/tr/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/uk-UA/CHANGELOG.md b/docs/i18n/uk-UA/CHANGELOG.md index de6b0d68cf..add86de00d 100644 --- a/docs/i18n/uk-UA/CHANGELOG.md +++ b/docs/i18n/uk-UA/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/ur/CHANGELOG.md b/docs/i18n/ur/CHANGELOG.md index a3fe147b3e..edd44f05cf 100644 --- a/docs/i18n/ur/CHANGELOG.md +++ b/docs/i18n/ur/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/vi/CHANGELOG.md b/docs/i18n/vi/CHANGELOG.md index 6a98b82280..4b7e57df42 100644 --- a/docs/i18n/vi/CHANGELOG.md +++ b/docs/i18n/vi/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/zh-CN/CHANGELOG.md b/docs/i18n/zh-CN/CHANGELOG.md index 5aaa17f2b9..35b160c475 100644 --- a/docs/i18n/zh-CN/CHANGELOG.md +++ b/docs/i18n/zh-CN/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/docs/i18n/zh-TW/CHANGELOG.md b/docs/i18n/zh-TW/CHANGELOG.md index 9453ea5e7c..92cf72c210 100644 --- a/docs/i18n/zh-TW/CHANGELOG.md +++ b/docs/i18n/zh-TW/CHANGELOG.md @@ -300,6 +300,8 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **feat(providers):** allow overriding the rate-limit queue wait timeout (`maxWaitMs`) per connection, alongside the existing `rpm`/`tpm`/`tpd`/`minTime`/`maxConcurrent` overrides — a single slow provider no longer has to lower the global wait budget for every other provider ([#11251](https://github.com/diegosouzapw/OmniRoute/pull/11251) — thanks @maxmad64bis) - **feat(monitoring):** expose the structural chat-admission snapshot through the health API and count capacity sheds by `queue_timeout` or `queued_bytes_budget`, with one credential-safe structured warning per shed and aborted waits excluded; admission behavior and thresholds are unchanged ([#11268](https://github.com/diegosouzapw/OmniRoute/pull/11268) — thanks @backryun) (reported in [#11244](https://github.com/diegosouzapw/OmniRoute/issues/11244) — thanks @im-ecorp) - **feat(catalog):** surface runtime-learned `reasoning_effort` tiers in `/v1/models` `capabilities.effort_tiers` (learned set replaces synced metadata when present), map them to OpenCode `ModelV2.variants` in the OmniRoute plugin, and align dispatch `-` suffix validation to the effective (learned ?? synced) set — so the UI offers exactly the tiers the upstream accepts (e.g. `{low, high, max}` for `oc/x-preview-f-free`) and each advertised variant completes. Excludes codex/glm/kimi, which keep their own dedicated `-{effort}` suffix mechanism and never gain `effort_tiers` from this path ([#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232), [#11252](https://github.com/diegosouzapw/OmniRoute/pull/11252) — thanks @maxmad64bis) (reported in [#7694](https://github.com/diegosouzapw/OmniRoute/issues/7694) — thanks @excessivechaos) +- **feat(vertex):** discover Anthropic partner models from the Vertex AI Model Garden's PublisherModels API and route dynamically discovered `claude-*` IDs through the Claude translator for both `vertex` and `vertex-partner` ([#11279](https://github.com/diegosouzapw/OmniRoute/pull/11279) — thanks @maci0; integration test by @hartmark) +- **feat(dashboard):** replace the hard Home → onboarding redirect with a dismissable first-run readiness card so returning users can stay on Home while new users still get a clear 4-step path; Pitch #03 is tracked in [#11167](https://github.com/diegosouzapw/OmniRoute/issues/11167) ([#11282](https://github.com/diegosouzapw/OmniRoute/pull/11282) — thanks @ignamiranda) ### 🐛 Bug Fixes @@ -834,7 +836,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** preserve validator HTTP status codes in API-key and web connection-test results so callers can distinguish authentication, rate-limit, and upstream failures ([#10272](https://github.com/diegosouzapw/OmniRoute/pull/10272)) — thanks @Zartharas - **fix(sse):** tiny-budget reasoning probes (e.g. Claude Code's `/model` check sends `max_tokens: 1`) are answered with a valid truncated 200 instead of relaying the upstream 5xx "empty response content" — which previously also marked the connection unavailable and poisoned fallback/cooldown bookkeeping for a request that is only a probe ([#10281](https://github.com/diegosouzapw/OmniRoute/issues/10281)) — thanks @harkaranbrar7 - fix(video): stop advertising the googleflow (Veo) video provider as working and fail fast with a clear diagnostic — its submit/poll endpoints 404 and no server-side OAuth transport can satisfy the working endpoint (#10285) -- fix(sse): mark gemini-3.5-flash as thinking-capable so reasoning_effort is no longer rejected with a spurious 400 (#10286) - **fix(docker):** prefix cache mount ids with Railway service scope ([#10288](https://github.com/diegosouzapw/OmniRoute/pull/10288)) — thanks @anudeepadi - **fix(build):** stop Turbopack from dead-code-eliminating the Windows Tailscale branches of `src/lib/tailscaleTunnel.ts` in the published build (#10293). The release `dist` is bundled on a Linux runner, and the bundler constant-folds `process.platform`, pruning every non-Linux branch — the Windows installers shipped with no `where` lookup, an always-injected `--socket`, and a lost `net start Tailscale`/windows-default-binary path. The module now reads the platform at runtime via `os.platform()` (a function call a bundler cannot fold), so the Windows branches survive on any build machine; a vitest regression test mocking `os.platform()` → `win32` guards the anti-fold invariant (RED before, GREEN after). - **fix(ops):** Docker HEALTHCHECK defaults to the lightweight `/healthz` lifecycle probe instead of the heavy `/api/monitoring/health` path, with an `OMNIROUTE_HEALTHCHECK_PATH` opt-in override ([#10311](https://github.com/diegosouzapw/OmniRoute/pull/10311)) @@ -1064,7 +1065,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(providers):** route terminal `testStatus` writes (`banned`, `deactivated`, `credits_exhausted`) through a single origin-aware passage — probe failures are recorded but never deactivate the connection ([#11009](https://github.com/diegosouzapw/OmniRoute/pull/11009)) — thanks @maxmad64bis - **fix(codex):** drop non-standard `codex.*` SSE events by default so OpenAI SDK / Codex CLI `/v1/responses` clients are not 502'd by `event: codex.rate_limits` ([#11014](https://github.com/diegosouzapw/OmniRoute/issues/11014)) — thanks @RaviTharuma - **fix(resilience):** count heavyweight `/v1` admission leases in the SIGTERM drain and send `Retry-After` on shutdown 503s so Recreate no longer looks like an empty 502 ([#11015](https://github.com/diegosouzapw/OmniRoute/issues/11015)) — thanks @RaviTharuma -- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016)) — thanks @RaviTharuma +- **fix(startup):** log `Credential health scheduler disabled` when `OMNIROUTE_DISABLE_CREDENTIAL_HEALTH_CHECK` is set instead of lying with `started` ([#11016](https://github.com/diegosouzapw/OmniRoute/issues/11016) — thanks @RaviTharuma); pin the real disabled-boot output with subprocess regression coverage ([#11265](https://github.com/diegosouzapw/OmniRoute/pull/11265) — thanks @Prajeeth-12) - **docs(api-keys):** document that unset `DEFAULT_RATE_LIMIT_PER_DAY` is unlimited (#2289), not a hidden 1000/day cap ([#11017](https://github.com/diegosouzapw/OmniRoute/issues/11017)) — thanks @RaviTharuma - **fix:** strip unsupported message metadata for Groq ([#11026](https://github.com/diegosouzapw/OmniRoute/pull/11026)) — thanks @sanforex24h - **fix(security):** close 4 STILL-REAL advisory findings (ACP RCE hardening, db-backups tier, uppercase authz bypass, spawn-veto drift) ([#11028](https://github.com/diegosouzapw/OmniRoute/pull/11028)) @@ -1168,7 +1169,6 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **cli:** guarantee non-empty [STARTUP] Fatal log on instrumentation-hook boot throw ([#10447](https://github.com/diegosouzapw/OmniRoute/pull/10447)) — thanks @adevwithpurpose - **dashboard:** make provider card warning indicators expose the interaction they advertise ([#10448](https://github.com/diegosouzapw/OmniRoute/pull/10448)) — thanks @adevwithpurpose - **dashboard:** media playground cards stop sending masked API key as Bearer ([#10449](https://github.com/diegosouzapw/OmniRoute/pull/10449)) — thanks @adevwithpurpose -- **sse:** mark gemini-3.5-flash as thinking-capable ([#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450)) — thanks @adevwithpurpose - **dashboard:** send periodic WS heartbeat pings to stop live-dashboard reconnect churn ([#10452](https://github.com/diegosouzapw/OmniRoute/pull/10452)) — thanks @adevwithpurpose - **sse:** do not ZWJ-obfuscate the substring hermes in user text ([#10488](https://github.com/diegosouzapw/OmniRoute/pull/10488)) — thanks @RaviTharuma - **models:** correct Codex context and combo limit resolution ([#10533](https://github.com/diegosouzapw/OmniRoute/pull/10533)) — thanks @jackjinke @@ -1230,6 +1230,11 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed - **fix(provider compatibility):** reject models-listing for Claude-Code-compatible connections before cached fallbacks can turn the unsupported request into an empty HTTP 200, and preserve raw no-auth model-override keys while resolving their sibling aliases so hidden-model and protocol overrides both survive ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952) — thanks @arminanton), re-derived from the closed ([#10795](https://github.com/diegosouzapw/OmniRoute/pull/10795) — thanks @rqzbeh) and reported in ([#7620](https://github.com/diegosouzapw/OmniRoute/issues/7620) — thanks @ahbeeahkao) - **fix(codex-app-server):** default Codex-owned command/file execution to the `workspace-write` sandbox and deny its approval prompts unless the operator opts in; bind env-sourced capability tokens only to the matching env URL or an operator-local host; and stop the authenticated `/readyz` probe from following redirects ([#11281](https://github.com/diegosouzapw/OmniRoute/pull/11281)) — thanks @hartmark - **fix(security):** refuse verbatim upstream-error passthrough when the body echoes a credential, redact relayed OCR and moderation errors, and cover the concrete `cookie`, `storageState` and `runtimeKey` call-log fields without hiding ordinary capability metadata ([#10952](https://github.com/diegosouzapw/OmniRoute/pull/10952)) — thanks @arminanton +- **fix(cli):** route MCP-backed CLI commands through the real Streamable HTTP JSON-RPC flow (`initialize` → `tools/call` with `Mcp-Session-Id`) instead of the nonexistent `/api/mcp/tools/call` route; decode tool results, honor the active remote context/auth/timeout, and align Combo, Skills, Compression and 1Proxy arguments with the server schemas ([#10960](https://github.com/diegosouzapw/OmniRoute/pull/10960) — thanks @YunyunZhai) +- **fix(providers):** remove retired Gemini 3.5 Flash entries from discovery, catalogs, aliases, rate limits, shared specs, docs and tests, superseding the pre-release thinking-capability workaround recorded for [#10286](https://github.com/diegosouzapw/OmniRoute/issues/10286) and [#10450](https://github.com/diegosouzapw/OmniRoute/pull/10450); the relevant commit was carried from open [#11259](https://github.com/diegosouzapw/OmniRoute/pull/11259) — thanks @backryun; direct-carry integration follow-up by @hartmark +- **fix(live-ws/dashboard):** accept the dev server's `http://0.0.0.0:20128` dashboard Origin without weakening the local-only default, stopping the `FORBIDDEN_ORIGIN` reconnect flood; render non-square provider and CLI logos at their intrinsic ratio so Next.js stops warning across the dashboard ([#11269](https://github.com/diegosouzapw/OmniRoute/pull/11269) — thanks @Minamaged18) +- **fix(ollama):** preserve every capability advertised by self-hosted Ollama models and defer chat selection to read time, so embedding and image routes accept eligible models without leaking endpoint-only models into provider wildcards or Auto-Combo; image retries remain restricted to the connections that advertised the selected model ([#11271](https://github.com/diegosouzapw/OmniRoute/pull/11271), corrected release-line port of [#11088](https://github.com/diegosouzapw/OmniRoute/pull/11088) for [#11087](https://github.com/diegosouzapw/OmniRoute/issues/11087) — thanks @yourspraveen) +- **fix(providers):** clamp out-of-vocabulary `reasoning_effort` values to the nearest tier declared by the exact provider/model, so `opencode-go/ox-alpha-free` maps the `medium` default to `high` while undeclared models remain pass-through ([#11274](https://github.com/diegosouzapw/OmniRoute/pull/11274) — thanks @linhdmn and @hartmark); builds on the learned accepted-set clamp from [#11232](https://github.com/diegosouzapw/OmniRoute/pull/11232) by @maxmad64bis ### 📝 Maintenance @@ -1518,6 +1523,7 @@ _Living section — reconciled 2026-08-23 from all cycle commits (cycle open `ed + ### 🙌 Contributors Thanks to everyone whose work landed in v3.8.50: @@ -1528,7 +1534,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@abhijeetnardele24-hash](https://github.com/abhijeetnardele24-hash) | #10498 | | [@Abhishek4512009](https://github.com/Abhishek4512009) | #10494 | | [@acc0mplish](https://github.com/acc0mplish) | #10732, #10948 | -| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10450, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | +| [@adevwithpurpose](https://github.com/adevwithpurpose) | #9790, #10118, #10222, #10403, #10416, #10434, #10435, #10436, #10437, #10438, #10447, #10448, #10449, #10452, #10506, #10625, #10800, #10834, #10835, #10836, #10882, #10959 | | [@AdityaMali16](https://github.com/AdityaMali16) | #11226 | | [@adrianojiu](https://github.com/adrianojiu) | #8438 | | [@agisota](https://github.com/agisota) | #9837 | @@ -1556,7 +1562,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@AStupidBear](https://github.com/AStupidBear) | #10180 | | [@azzaouiomar19-sketch](https://github.com/azzaouiomar19-sketch) | #10394 | | [@b1nhm1nh](https://github.com/b1nhm1nh) | direct commit / report | -| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | +| [@backryun](https://github.com/backryun) | #8228, #8451, #8627, #8809, #8818, #9084, #9086, #9090, #9091, #9092, #9093, #9114, #9119, #9120, #9122, #9135, #9136, #9137, #9138, #9139, #9141, #9561, #9562, #9563, #9564, #9565, #9566, #9742, #9747, #9748, #9751, #9753, #9755, #9791, #9792, #9793, #9795, #9796, #9797, #9798, #9920, #9972, #9973, #9974, #9975, #9977, #9978, #9979, #9984, #9986, #9987, #9988, #9989, #9990, #9998, #10087, #10088, #10134, #10175, #10178, #10195, #10201, #10226, #10254, #10255, #10256, #10257, #10258, #10324, #10325, #10327, #10328, #10339, #10359, #10367, #10380, #10382, #10390, #10418, #10423, #10433, #10451, #10453, #10464, #10487, #10512, #10520, #10633, #10634, #10637, #10647, #10648, #10649, #10655, #10689, #10691, #10695, #10698, #10699, #10700, #10826, #10964, #11147, #11196, #11208, #11256, #11259, #11260, #11262, #11263, #11264, #11266, #11267, #11268 | | [@Benson-mk](https://github.com/Benson-mk) | #8369 | | [@benzntech](https://github.com/benzntech) | #9784, #9810, #9812, #9939, #10124, #10126, #10366, #10458 | | [@Bl0ck154](https://github.com/Bl0ck154) | #9231 | @@ -1619,7 +1625,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@Hsia97](https://github.com/Hsia97) | #10810 | | [@hydraxman](https://github.com/hydraxman) | #10137, #10572 | | [@Iammilansoni](https://github.com/Iammilansoni) | #9353, #9397 | -| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228 | +| [@ignamiranda](https://github.com/ignamiranda) | #11195, #11204, #11206, #11215, #11224, #11227, #11228, #11282 | | [@ikelvingo](https://github.com/ikelvingo) | #8591, #8872, #9053 | | [@im-ecorp](https://github.com/im-ecorp) | #11244 | | [@infinit-X](https://github.com/infinit-X) | #9095 | @@ -1651,12 +1657,13 @@ Thanks to everyone whose work landed in v3.8.50: | [@larin-vas](https://github.com/larin-vas) | #9828 | | [@lazysaltyfish](https://github.com/lazysaltyfish) | direct commit / report | | [@LeonG606](https://github.com/LeonG606) | #9457 | -| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214 | +| [@linhdmn](https://github.com/linhdmn) | #10980, #11085, #11209, #11214, #11274 | | [@Llliao1113](https://github.com/Llliao1113) | #8921 | | [@lucasalx](https://github.com/lucasalx) | #9919 | | [@lucasmellos](https://github.com/lucasmellos) | #8925 | | [@lukiod](https://github.com/lukiod) | #8828 | | [@luoyide](https://github.com/luoyide) | direct commit / report | +| [@maci0](https://github.com/maci0) | #11279 | | [@mad-gooze](https://github.com/mad-gooze) | #9052 | | [@mado90](https://github.com/mado90) | #11236 | | [@maisdesign](https://github.com/maisdesign) | #8858 | @@ -1669,6 +1676,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@MeRezaRezaei](https://github.com/MeRezaRezaei) | #10174, #10614, #10889, #10944, #11042, #11045 | | [@Michael-Rocco-Goldmann](https://github.com/Michael-Rocco-Goldmann) | #9770, #9773, #9777, #9787 | | [@MichaelYcJo](https://github.com/MichaelYcJo) | #8244, #10725, #10726 | +| [@Minamaged18](https://github.com/Minamaged18) | #11269 | | [@minhlongs](https://github.com/minhlongs) | #10805 | | [@minhnhat166](https://github.com/minhnhat166) | direct commit / report | | [@MohitRawat017](https://github.com/MohitRawat017) | #8718, #8772, #9605 | @@ -1697,7 +1705,7 @@ Thanks to everyone whose work landed in v3.8.50: | [@PixmaNts](https://github.com/PixmaNts) | #9432 | | [@pizzav-xyz](https://github.com/pizzav-xyz) | #9077 | | [@Poid-ZA](https://github.com/Poid-ZA) | #9467, #10769 | -| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031 | +| [@Prajeeth-12](https://github.com/Prajeeth-12) | #11031, #11265 | | [@Prudhvivuda](https://github.com/Prudhvivuda) | #8807, #9014, #9015, #9016 | | [@pucedoteth](https://github.com/pucedoteth) | #10607 | | [@qianze0628](https://github.com/qianze0628) | #9038 | @@ -1763,9 +1771,9 @@ Thanks to everyone whose work landed in v3.8.50: | [@yansigit](https://github.com/yansigit) | #9834, #9909, #9911, #9917, #9921, #10065 | | [@yawar-aquil](https://github.com/yawar-aquil) | #10668 | | [@yidecode](https://github.com/yidecode) | #7223, #9212 | -| [@yourspraveen](https://github.com/yourspraveen) | #11165, #11176 | +| [@yourspraveen](https://github.com/yourspraveen) | #11087, #11088, #11165, #11176, #11271 | | [@yulinlina](https://github.com/yulinlina) | #10013 | -| [@YunyunZhai](https://github.com/YunyunZhai) | #10946 | +| [@YunyunZhai](https://github.com/YunyunZhai) | #10946, #10960 | | [@yutuknown](https://github.com/yutuknown) | #8999 | | [@zabrodschiipavel-sketch](https://github.com/zabrodschiipavel-sketch) | #9312 | | [@zannen7](https://github.com/zannen7) | #10077 | diff --git a/open-sse/executors/base/reasoningEffort.ts b/open-sse/executors/base/reasoningEffort.ts index ee520bbc2c..535c40f9f9 100644 --- a/open-sse/executors/base/reasoningEffort.ts +++ b/open-sse/executors/base/reasoningEffort.ts @@ -375,11 +375,10 @@ export function sanitizeReasoningEffortForProvider( ? modelStr.slice(provider.length + 1) : modelStr; const declaredEfforts = getProviderModels(provider).find( - (entry) => entry.id === providerModelIdForClamp || entry.aliases?.includes(providerModelIdForClamp) + (entry) => + entry.id === providerModelIdForClamp || entry.aliases?.includes(providerModelIdForClamp) )?.supportedThinkingEfforts; - const declaredRanked = ( - Array.isArray(declaredEfforts) ? declaredEfforts : [] - ) + const declaredRanked = (Array.isArray(declaredEfforts) ? declaredEfforts : []) .map((tier) => ({ tier, rank: REASONING_EFFORT_ORDER.indexOf(tier) })) .filter((x) => x.rank >= 0) .sort((a, b) => a.rank - b.rank); diff --git a/open-sse/mcp-server/tools/skillTools.ts b/open-sse/mcp-server/tools/skillTools.ts index bb3f0acb6e..cf22c67802 100644 --- a/open-sse/mcp-server/tools/skillTools.ts +++ b/open-sse/mcp-server/tools/skillTools.ts @@ -1,6 +1,7 @@ import { z } from "zod"; import { skillRegistry } from "@/lib/skills/registry"; import { skillExecutor } from "@/lib/skills/executor"; +import type { McpToolExtraLike } from "../scopeEnforcement.ts"; export const SkillListSchema = z.object({ apiKeyId: z.string().optional(), @@ -9,17 +10,40 @@ export const SkillListSchema = z.object({ }); export const SkillEnableSchema = z.object({ - apiKeyId: z.string(), + apiKeyId: z.string().optional(), skillId: z.string(), enabled: z.boolean(), }); -export const SkillExecuteSchema = z.object({ - apiKeyId: z.string(), - skillName: z.string(), - input: z.record(z.string(), z.unknown()), - sessionId: z.string().optional(), -}); +export const SkillExecuteSchema = z + .object({ + apiKeyId: z.string().optional(), + skillId: z.string().optional(), + skillName: z.string().optional(), + input: z.record(z.string(), z.unknown()), + sessionId: z.string().optional(), + }) + .refine((args) => Boolean(args.skillId || args.skillName), { + message: "skillId or skillName is required", + }); + +function authenticatedCallerId(extra: McpToolExtraLike | undefined): string | undefined { + const clientId = extra?.authInfo?.clientId; + return typeof clientId === "string" && clientId.trim() ? clientId.trim() : undefined; +} + +async function resolveSkillTarget( + identifier: string, + requestedApiKeyId: string | undefined, + extra: McpToolExtraLike | undefined +) { + const callerId = authenticatedCallerId(extra); + const lookupOwnerId = callerId ?? requestedApiKeyId; + await skillRegistry.loadFromDatabase(lookupOwnerId); + const skill = skillRegistry.getSkill(identifier, lookupOwnerId); + if (!skill) throw new Error(`Skill not found: ${identifier}`); + return { skill, callerId, requestedApiKeyId }; +} export const skillTools = { omniroute_skills_list: { @@ -58,14 +82,20 @@ export const skillTools = { description: "Enable or disable a specific skill by ID", scopes: ["write:skills"], inputSchema: SkillEnableSchema, - handler: async (args: z.infer) => { - await skillRegistry.loadFromDatabase(args.apiKeyId); - const skill = await skillRegistry.setEnabledById(args.skillId, args.apiKeyId, args.enabled); - if (!skill) { + handler: async (args: z.infer, extra?: McpToolExtraLike) => { + const target = await resolveSkillTarget(args.skillId, args.apiKeyId, extra); + const mutationOwnerId = target.callerId ?? target.requestedApiKeyId ?? target.skill.apiKeyId; + if (target.skill.apiKeyId !== mutationOwnerId) { throw new Error(`Skill not found: ${args.skillId}`); } + const skill = await skillRegistry.setEnabledById( + target.skill.id, + mutationOwnerId, + args.enabled + ); + if (!skill) throw new Error(`Skill not found: ${args.skillId}`); - return { success: true, skillId: args.skillId, enabled: args.enabled }; + return { success: true, skillId: target.skill.id, enabled: args.enabled }; }, }, @@ -74,9 +104,11 @@ export const skillTools = { description: "Execute a skill with provided input and return the result", scopes: ["execute:skills"], inputSchema: SkillExecuteSchema, - handler: async (args: z.infer) => { - const execution = await skillExecutor.execute(args.skillName, args.input, { - apiKeyId: args.apiKeyId, + handler: async (args: z.infer, extra?: McpToolExtraLike) => { + const identifier = args.skillId ?? args.skillName!; + const target = await resolveSkillTarget(identifier, args.apiKeyId, extra); + const execution = await skillExecutor.execute(target.skill.name, args.input, { + apiKeyId: target.callerId ?? target.requestedApiKeyId ?? target.skill.apiKeyId, sessionId: args.sessionId, }); diff --git a/open-sse/services/autoCombo/virtualFactory.ts b/open-sse/services/autoCombo/virtualFactory.ts index 9eaa5bb82d..f442801775 100644 --- a/open-sse/services/autoCombo/virtualFactory.ts +++ b/open-sse/services/autoCombo/virtualFactory.ts @@ -11,6 +11,7 @@ import { toNumber } from "@/shared/utils/numeric"; import { isCompatibleProviderConnectionId } from "@/shared/utils/compatibleProviderId"; import { defaultLogger as log } from "@omniroute/open-sse/utils/logger"; import { getTokenLimit } from "../contextManager"; +import { filterChatSelectableModels } from "../modelEndpointPolicy.ts"; import { createModelCapabilityResolutionSnapshot, getResolvedModelCapabilities, @@ -542,10 +543,17 @@ export async function prepareVirtualAutoComboInputs( // back to the static catalog only when the user has none. This keeps catalog-only // models (e.g. openrouter/auto) out of every auto/* pool when the operator only // synced a subset (e.g. OpenRouter with importFreeModelsOnly). - const [syncedByConnection, customModels] = await Promise.all([ + const [syncedByConnectionRaw, customModelsRaw] = await Promise.all([ getSyncedAvailableModelsByConnection(providerId), getCustomModels(providerId), ]); + const syncedByConnection = Object.fromEntries( + Object.entries(syncedByConnectionRaw).map(([connectionId, models]) => [ + connectionId, + filterChatSelectableModels(providerId, models), + ]) + ); + const customModels = filterChatSelectableModels(providerId, customModelsRaw); const userVisibleIds = new Set(); for (const models of Object.values(syncedByConnection)) { for (const m of models) if (m.id && !hiddenModels?.has(m.id)) userVisibleIds.add(m.id); diff --git a/open-sse/services/combo/providerWildcard.ts b/open-sse/services/combo/providerWildcard.ts index 55763815c8..20bf14da44 100644 --- a/open-sse/services/combo/providerWildcard.ts +++ b/open-sse/services/combo/providerWildcard.ts @@ -33,6 +33,7 @@ import { wildcardMatch } from "../wildcardRouter.ts"; import { getProviderModels } from "../../config/providerModels.ts"; import { getActiveSyncedCatalog } from "../../../src/lib/db/models/activeSyncedCatalog.ts"; import { filterAlibabaFreeTierModels, isAlibabaModelStudioProvider } from "../alibabaFreeTier.ts"; +import { filterChatSelectableModels } from "../modelEndpointPolicy.ts"; import { filterAlibabaFreeEligibleModels, buildAlibabaFreeTierFilterContext, @@ -144,10 +145,12 @@ async function collectProviderModelIds(providerId: string): Promise { const liveCatalog = await getActiveSyncedCatalog(providerId); if (liveCatalog.authoritative) { - return liveCatalog.models.map((model) => model.id); + return filterChatSelectableModels(providerId, liveCatalog.models).map((model) => model.id); } - return getProviderModels(providerId).map((model) => model.id); + return filterChatSelectableModels(providerId, getProviderModels(providerId)).map( + (model) => model.id + ); } async function filterAlibabaFreeDrainedModelIds( diff --git a/src/app/api/providers/[id]/models/route.ts b/src/app/api/providers/[id]/models/route.ts index b1e4a50b69..0a44df1722 100755 --- a/src/app/api/providers/[id]/models/route.ts +++ b/src/app/api/providers/[id]/models/route.ts @@ -1849,30 +1849,12 @@ export async function GET( throw error; } - // ponytail: Anthropic partner models via Model Garden publisher endpoint (Bearer only) + // ponytail: Anthropic partner models via Model Garden PublisherModels endpoint (Bearer only) if (bearerToken) { - const psd = asRecord(connection.providerSpecificData); - const region = - (typeof psd.region === "string" && psd.region.trim()) || "us-central1"; - - // Extract project_id from SA JSON for project-scoped listing (mirrors executor URL pattern). - // Falls back to global publisher endpoint if no project available. - let anthropicModelsUrl: string; - let projectId: string | null = null; - if (credential) { - try { - const sa = JSON.parse(credential); - if (sa?.project_id) projectId = sa.project_id; - } catch { /* not SA JSON, skip */ } - } - if (projectId) { - anthropicModelsUrl = `https://aiplatform.googleapis.com/v1/projects/${projectId}/locations/${region}/publishers/anthropic/models`; - } else { - anthropicModelsUrl = `https://aiplatform.googleapis.com/v1/publishers/anthropic/models`; - } - try { - const anthropicResponse = await safeOutboundFetch(anthropicModelsUrl, { + const { parseVertexAnthropicModels, VERTEX_ANTHROPIC_PUBLISHER_MODELS_URL } = + await import("@/lib/providerModels/vertexAnthropicModelsParser"); + const anthropicResponse = await safeOutboundFetch(VERTEX_ANTHROPIC_PUBLISHER_MODELS_URL, { ...SAFE_OUTBOUND_FETCH_PRESETS.modelsDiscovery, guard: getProviderOutboundGuard(), proxyConfig: proxy, @@ -1884,14 +1866,10 @@ export async function GET( }); if (anthropicResponse.ok) { const anthropicData = await anthropicResponse.json(); - const { parseVertexAnthropicModels } = await import( - "@/lib/providerModels/vertexAnthropicModelsParser" - ); allModels.push(...parseVertexAnthropicModels(anthropicData)); } else { console.log("[models] Vertex Anthropic partner discovery failed", { provider, - region, status: anthropicResponse.status, }); } diff --git a/src/app/api/v1/images/generations/route.ts b/src/app/api/v1/images/generations/route.ts index cc8403115b..f7fa36915e 100644 --- a/src/app/api/v1/images/generations/route.ts +++ b/src/app/api/v1/images/generations/route.ts @@ -127,16 +127,8 @@ async function postHandler(request, context) { if (body.model && typeof body.model === "string" && !body.model.includes("/")) { const combo = await getComboByName(body.model as string); if (combo) { - const { executeImageCombo } = await import( - "@omniroute/open-sse/services/imageCombo" - ); - return executeImageCombo( - body.model as string, - body, - { request, policy }, - startTime, - log - ); + const { executeImageCombo } = await import("@omniroute/open-sse/services/imageCombo"); + return executeImageCombo(body.model as string, body, { request, policy }, startTime, log); } } @@ -155,6 +147,7 @@ async function postHandler(request, context) { syncedEndpointRoute = await resolveLocalSyncedEndpointRoute(body.model, "images"); if (syncedEndpointRoute) { provider = syncedEndpointRoute.provider; + requestedModel = syncedEndpointRoute.model; body.model = `${syncedEndpointRoute.provider}/${syncedEndpointRoute.model}`; isCustomModel = true; } @@ -246,7 +239,8 @@ async function postHandler(request, context) { provider, null, syncedEndpointRoute?.connectionIds ?? null, - requestedModel ); + requestedModel + ); if (!credentials) { return errorResponse( HTTP_STATUS.BAD_REQUEST, @@ -279,6 +273,7 @@ async function postHandler(request, context) { const execution = await executeImageWithCredentialFallback({ provider, requestedModel, + allowedConnectionIds: syncedEndpointRoute?.connectionIds ?? null, credentials, execute: async (attemptCredentials) => { let proxyInfo = null; @@ -346,7 +341,10 @@ async function postHandler(request, context) { }); } - const errorPayload = toJsonErrorPayload((result as any).error, "Image generation provider error") as { + const errorPayload = toJsonErrorPayload( + (result as any).error, + "Image generation provider error" + ) as { error?: { message?: string }; }; const message = diff --git a/src/lib/providerModels/vertexAnthropicModelsParser.ts b/src/lib/providerModels/vertexAnthropicModelsParser.ts index 9e08c22fa9..115c767dd2 100644 --- a/src/lib/providerModels/vertexAnthropicModelsParser.ts +++ b/src/lib/providerModels/vertexAnthropicModelsParser.ts @@ -7,6 +7,9 @@ interface VertexPublisherModel { [key: string]: unknown; } +export const VERTEX_ANTHROPIC_PUBLISHER_MODELS_URL = + "https://aiplatform.googleapis.com/v1beta1/publishers/anthropic/models"; + export interface VertexAnthropicDiscoveryModel { id: string; name: string; @@ -19,16 +22,21 @@ export interface VertexAnthropicDiscoveryModel { export function parseVertexAnthropicModels(data: unknown): VertexAnthropicDiscoveryModel[] { if (!data || typeof data !== "object") return []; - const envelope = data as { models?: unknown[] }; - const models = Array.isArray(envelope.models) ? envelope.models : []; + const envelope = data as { publisherModels?: unknown }; + const models = Array.isArray(envelope.publisherModels) ? envelope.publisherModels : []; return models .map((m: unknown) => { + if (!m || typeof m !== "object" || Array.isArray(m)) return null; const model = m as VertexPublisherModel; const rawName = typeof model.name === "string" ? model.name : ""; // "publishers/anthropic/models/claude-sonnet-4-6" or // "projects/x/locations/y/publishers/anthropic/models/claude-sonnet-4-6" - const id = rawName.replace(/^(?:projects\/[^/]+\/locations\/[^/]+\/)?publishers\/anthropic\/models\//, "") || rawName; + const id = + rawName.replace( + /^(?:projects\/[^/]+\/locations\/[^/]+\/)?publishers\/anthropic\/models\//, + "" + ) || rawName; if (!id) return null; return { diff --git a/src/sse/services/imageCredentialRetry.ts b/src/sse/services/imageCredentialRetry.ts index 5758aed108..d6627241f2 100644 --- a/src/sse/services/imageCredentialRetry.ts +++ b/src/sse/services/imageCredentialRetry.ts @@ -22,6 +22,7 @@ interface ImageGenerationResult { interface ImageCredentialRetryOptions { provider: string; requestedModel: string | null; + allowedConnectionIds?: string[] | null; credentials: any; execute: (credentials: any) => Promise; // Injectable so unit tests can drive multi-account fallback deterministically @@ -30,7 +31,8 @@ interface ImageCredentialRetryOptions { selectNextCredentials?: ( provider: string, requestedModel: string | null, - excludedConnectionIds: Set + excludedConnectionIds: Set, + allowedConnectionIds?: string[] | null ) => Promise; } @@ -53,11 +55,18 @@ function isCredentialSentinel(credentials: any): boolean { async function defaultSelectNextCredentials( provider: string, requestedModel: string | null, - excludedConnectionIds: Set + excludedConnectionIds: Set, + allowedConnectionIds?: string[] | null ) { - return getProviderCredentialsWithQuotaPreflight(provider, null, null, requestedModel, { - excludeConnectionIds: Array.from(excludedConnectionIds), - }); + return getProviderCredentialsWithQuotaPreflight( + provider, + null, + allowedConnectionIds, + requestedModel, + { + excludeConnectionIds: Array.from(excludedConnectionIds), + } + ); } /** @@ -70,6 +79,7 @@ async function defaultSelectNextCredentials( export async function executeImageWithCredentialFallback({ provider, requestedModel, + allowedConnectionIds = null, credentials, execute, selectNextCredentials = defaultSelectNextCredentials, @@ -103,7 +113,8 @@ export async function executeImageWithCredentialFallback({ currentCredentials = await selectNextCredentials( provider, requestedModel, - excludedConnectionIds + excludedConnectionIds, + allowedConnectionIds ); continue; } @@ -122,7 +133,8 @@ export async function executeImageWithCredentialFallback({ currentCredentials = await selectNextCredentials( provider, requestedModel, - excludedConnectionIds + excludedConnectionIds, + allowedConnectionIds ); } diff --git a/tests/unit/cli-combo-suggest-commands.test.ts b/tests/unit/cli-combo-suggest-commands.test.ts index 53e04801af..dcd5cb4e36 100644 --- a/tests/unit/cli-combo-suggest-commands.test.ts +++ b/tests/unit/cli-combo-suggest-commands.test.ts @@ -24,8 +24,7 @@ test("combo suggest chama omniroute_best_combo_for_task via MCP", async () => { }); const { mcpCallTool } = await import("../../bin/cli/mcpClient.mjs"); const result = await mcpCallTool("omniroute_best_combo_for_task", { - task: "Real-time code completions", - top: 5, + taskType: "coding", }); globalThis.fetch = origFetch; const candidates = (result as any).candidates; @@ -44,35 +43,34 @@ test("combo suggest --max-cost/--max-latency-ms passa constraints", async () => }) as any; const { mcpCallTool } = await import("../../bin/cli/mcpClient.mjs"); await mcpCallTool("omniroute_best_combo_for_task", { - task: "Summarize PDFs", - constraints: { maxCostUsd: 0.001, maxLatencyMs: 500 }, - top: 3, + taskType: "analysis", + budgetConstraint: 0.001, + latencyConstraint: 500, }); globalThis.fetch = origFetch; - const args = JSON.parse(captured.find((c) => /tools\/call/.test(String(c.init?.body || "")))?.init?.body || "{}")?.params?.arguments; - assert.equal(args.constraints.maxCostUsd, 0.001); - assert.equal(args.constraints.maxLatencyMs, 500); - assert.equal(args.top, 3); + const args = JSON.parse( + captured.find((c) => /tools\/call/.test(String(c.init?.body || "")))?.init?.body || "{}" + )?.params?.arguments; + assert.equal(args.taskType, "analysis"); + assert.equal(args.budgetConstraint, 0.001); + assert.equal(args.latencyConstraint, 500); }); -test("combo suggest --weights passa pesos no body", async () => { +test("mcpCallTool reaplica a sessão e decodifica CallToolResult textual", async () => { const origFetch = globalThis.fetch; const captured: any[] = []; - globalThis.fetch = makeMcpStreamFetch({ toolResult: { candidates: [] } }); + globalThis.fetch = makeMcpStreamFetch({ toolResult: { recommendedCombo: { name: "fast" } } }); const inner = globalThis.fetch; globalThis.fetch = ((url: any, init: any) => { captured.push({ url: String(url), init }); return inner(url, init); }) as any; const { mcpCallTool } = await import("../../bin/cli/mcpClient.mjs"); - await mcpCallTool("omniroute_best_combo_for_task", { - task: "batch", - weights: { latency: 0.7, cost: 0.3 }, - }); + const result = await mcpCallTool("omniroute_best_combo_for_task", { taskType: "coding" }); globalThis.fetch = origFetch; - const args = JSON.parse(captured.find((c) => /tools\/call/.test(String(c.init?.body || "")))?.init?.body || "{}")?.params?.arguments; - assert.equal(args.weights.latency, 0.7); - assert.equal(args.weights.cost, 0.3); + const toolCall = captured.find((c) => /tools\/call/.test(String(c.init?.body || ""))); + assert.equal(new Headers(toolCall?.init?.headers).get("mcp-session-id"), "sess-test"); + assert.deepEqual(result, { recommendedCombo: { name: "fast" } }); }); test("combo suggest --switch chama /api/combos/switch com melhor combo", async () => { @@ -83,16 +81,35 @@ test("combo suggest --switch chama /api/combos/switch com melhor combo", async ( if (String(url).includes("/api/mcp/stream")) { const body = opts?.body ? JSON.parse(opts.body) : {}; if (body.method === "initialize") { - return Promise.resolve(makeMcpResp({ jsonrpc: "2.0", id: body.id, result: {} }, 200, { "mcp-session-id": "s" })); + return Promise.resolve( + makeMcpResp({ jsonrpc: "2.0", id: body.id, result: {} }, 200, { "mcp-session-id": "s" }) + ); } - return Promise.resolve(makeMcpResp({ jsonrpc: "2.0", id: body.id, result: { candidates: [{ name: "best-combo", score: 0.95 }] } })); + assert.equal(new Headers(opts?.headers).get("mcp-session-id"), "s"); + return Promise.resolve( + makeMcpResp({ + jsonrpc: "2.0", + id: body.id, + result: { + content: [ + { + type: "text", + text: JSON.stringify({ recommendedCombo: { name: "best-combo" } }), + }, + ], + }, + }) + ); } return Promise.resolve(makeMcpResp({ switched: true })); }) as any; const { mcpCallTool } = await import("../../bin/cli/mcpClient.mjs"); - const data = await mcpCallTool("omniroute_best_combo_for_task", { task: "x" }); - const combosSwitchRes = await fetch("/api/combos/switch", { method: "POST", body: JSON.stringify({ name: (data as any).candidates[0].name }) }); + const data = await mcpCallTool("omniroute_best_combo_for_task", { taskType: "coding" }); + const combosSwitchRes = await fetch("/api/combos/switch", { + method: "POST", + body: JSON.stringify({ name: (data as any).recommendedCombo.name }), + }); assert.equal(combosSwitchRes.ok, true); assert.ok(urls.some((u) => u.includes("/api/combos/switch"))); globalThis.fetch = origFetch; diff --git a/tests/unit/cli-compression-commands.test.ts b/tests/unit/cli-compression-commands.test.ts index 18835a0f20..a60f57284c 100644 --- a/tests/unit/cli-compression-commands.test.ts +++ b/tests/unit/cli-compression-commands.test.ts @@ -48,12 +48,14 @@ test("compression status chama omniroute_compression_status via mcp", async () = await captureStdout(() => runCompressionStatus({}, makeCmd() as any)); globalThis.fetch = origFetch; - const body = JSON.parse(calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}"); + const body = JSON.parse( + calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}" + ); assert.equal(body.method, "tools/call"); assert.equal(body.params.name, "omniroute_compression_status"); }); -test("compression configure envia configuração via mcp", async () => { +test("compression configure envia apenas campos aceitos pelo schema MCP", async () => { const calls: unknown[] = []; const origFetch = globalThis.fetch; globalThis.fetch = makeMcpStreamFetch({ toolResult: { success: true } }); @@ -65,16 +67,53 @@ test("compression configure envia configuração via mcp", async () => { const { runCompressionConfigure } = await import("../../bin/cli/commands/compression.mjs"); await captureStdout(() => - runCompressionConfigure({ engine: "caveman", cavemanAggressiveness: 0.8 }, makeCmd() as any) + runCompressionConfigure( + { + engine: "standard", + autoTriggerMode: "aggressive", + maxTokens: 4096, + targetRatio: 0.45, + preserveSystemPrompt: true, + }, + makeCmd() as any + ) ); globalThis.fetch = origFetch; - const body = JSON.parse(calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}"); + const body = JSON.parse( + calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}" + ); assert.equal(body.method, "tools/call"); assert.equal(body.params.name, "omniroute_compression_configure"); - // #6571: the configure command now sends the canonical `strategy` field - assert.equal(body.params.arguments.strategy, "caveman"); - assert.ok(body.params.arguments.caveman?.aggressiveness === 0.8); + assert.deepEqual(body.params.arguments, { + strategy: "standard", + autoTriggerMode: "aggressive", + maxTokens: 4096, + targetRatio: 0.45, + preserveSystemPrompt: true, + }); + assert.equal("caveman" in body.params.arguments, false); + assert.equal("rtk" in body.params.arguments, false); + assert.equal("languagePack" in body.params.arguments, false); +}); + +test("compression combo stats maps --period to the canonical since field", async () => { + const calls: any[] = []; + const origFetch = globalThis.fetch; + const streamFetch = makeMcpStreamFetch({ toolResult: { requests: 3 } }); + globalThis.fetch = (async (url: string, init?: any) => { + calls.push({ url: String(url), init }); + return streamFetch(url, init); + }) as any; + + const { runCompressionComboStats } = await import("../../bin/cli/commands/compression.mjs"); + await captureStdout(() => runCompressionComboStats({ period: "30d" }, makeCmd() as any)); + + globalThis.fetch = origFetch; + const body = JSON.parse( + calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}" + ); + assert.deepEqual(body.params.arguments, { since: "30d" }); }); test("compression engine set chama omniroute_set_compression_engine", async () => { @@ -93,7 +132,9 @@ test("compression engine set chama omniroute_set_compression_engine", async () = }); globalThis.fetch = origFetch; - const body = JSON.parse(calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}"); + const body = JSON.parse( + calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}" + ); assert.equal(body.method, "tools/call"); assert.equal(body.params.name, "omniroute_set_compression_engine"); assert.equal(body.params.arguments.engine, "rtk"); @@ -135,7 +176,9 @@ test("compression engine set normaliza hybrid → stacked alias", async () => { }); globalThis.fetch = origFetch; - const body = JSON.parse(calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}"); + const body = JSON.parse( + calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}" + ); assert.equal(body.params.arguments.engine, "stacked"); }); @@ -208,7 +251,9 @@ test("compression status falls back to /api/settings/compression on MCP 404", as if (url.includes("/api/mcp/stream")) { const body = opts?.body ? JSON.parse(opts.body) : {}; if (body.method === "initialize") { - return Promise.resolve(makeMcpResp({ jsonrpc: "2.0", id: body.id, result: {} }, 200, { "mcp-session-id": "s" })); + return Promise.resolve( + makeMcpResp({ jsonrpc: "2.0", id: body.id, result: {} }, 200, { "mcp-session-id": "s" }) + ); } return Promise.resolve(makeMcpResp({ error: "not mounted" }, 404)); } @@ -230,9 +275,18 @@ test("compression status falls back to /api/settings/compression on MCP 404", as globalThis.fetch = origFetch; const first = callOrder[0] ?? ""; assert.ok(first.includes("/api/mcp/stream"), "should attempt MCP first"); - assert.ok(callOrder.some((u) => u.includes("/api/settings/compression")), "should fall back to REST"); - assert.ok(callOrder.some((u) => u.includes("/api/context/combos")), "should fetch combos"); - assert.ok(callOrder.some((u) => u.includes("/api/context/analytics")), "should fetch analytics"); + assert.ok( + callOrder.some((u) => u.includes("/api/settings/compression")), + "should fall back to REST" + ); + assert.ok( + callOrder.some((u) => u.includes("/api/context/combos")), + "should fetch combos" + ); + assert.ok( + callOrder.some((u) => u.includes("/api/context/analytics")), + "should fetch analytics" + ); }); test("compression engine set falls back to PUT /api/settings/compression on MCP 404", async () => { @@ -247,7 +301,9 @@ test("compression engine set falls back to PUT /api/settings/compression on MCP if (url.includes("/api/mcp/stream")) { const body = opts?.body ? JSON.parse(opts.body) : {}; if (body.method === "initialize") { - return Promise.resolve(makeMcpResp({ jsonrpc: "2.0", id: body.id, result: {} }, 200, { "mcp-session-id": "s" })); + return Promise.resolve( + makeMcpResp({ jsonrpc: "2.0", id: body.id, result: {} }, 200, { "mcp-session-id": "s" }) + ); } return Promise.resolve(makeMcpResp({ error: "not mounted" }, 404)); } diff --git a/tests/unit/cli-mcp-call-commands.test.ts b/tests/unit/cli-mcp-call-commands.test.ts index 8e2a8d63fb..39f3ada3a0 100644 --- a/tests/unit/cli-mcp-call-commands.test.ts +++ b/tests/unit/cli-mcp-call-commands.test.ts @@ -1,5 +1,38 @@ import test from "node:test"; import assert from "node:assert/strict"; +import { mkdtempSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; + +const originalDataDir = process.env.DATA_DIR; +const originalKeychainDisabled = process.env.OMNIROUTE_CONTEXT_KEYCHAIN_DISABLED; +const testDataDir = mkdtempSync(join(tmpdir(), "omniroute-cli-mcp-call-")); +process.env.DATA_DIR = testDataDir; +process.env.OMNIROUTE_CONTEXT_KEYCHAIN_DISABLED = "1"; +writeFileSync( + join(testDataDir, "config.json"), + JSON.stringify({ + version: 1, + currentContext: "remote-test", + contexts: { + "remote-test": { + baseUrl: "https://remote.example.test", + accessToken: "remote-context-token", + }, + }, + }) +); + +test.after(() => { + if (originalDataDir === undefined) delete process.env.DATA_DIR; + else process.env.DATA_DIR = originalDataDir; + if (originalKeychainDisabled === undefined) { + delete process.env.OMNIROUTE_CONTEXT_KEYCHAIN_DISABLED; + } else { + process.env.OMNIROUTE_CONTEXT_KEYCHAIN_DISABLED = originalKeychainDisabled; + } + rmSync(testDataDir, { recursive: true, force: true }); +}); // ---- helpers ---- @@ -32,16 +65,12 @@ async function captureStdout(fn: () => Promise): Promise { return chunks.join(""); } -function makeCmd(output = "json") { - return { optsWithGlobals: () => ({ output, quiet: output !== "table" }) }; -} - // Simulate a /api/mcp/stream endpoint that speaks JSON-RPC 2.0 function makeMcpStreamFetch( toolResult: { content: { type: string; text: string }[] } = { content: [{ type: "text", text: "hello" }], }, - callStatus = 200, + callStatus = 200 ) { return ((url: string, opts: unknown) => { const u = String(url); @@ -57,19 +86,14 @@ function makeMcpStreamFetch( makeResp( { jsonrpc: "2.0", id: 1, result: { protocolVersion: "2024-11-05", capabilities: {} } }, 200, - { "mcp-session-id": "test-session-123" }, - ), + { "mcp-session-id": "test-session-123" } + ) ); } // tools/call if (body && body.method === "tools/call") { - return Promise.resolve( - makeResp( - { jsonrpc: "2.0", id: 2, result: toolResult }, - callStatus, - ), - ); + return Promise.resolve(makeResp({ jsonrpc: "2.0", id: 2, result: toolResult }, callStatus)); } return Promise.resolve(makeResp({ error: "unknown method" }, 400)); @@ -78,11 +102,172 @@ function makeMcpStreamFetch( // ---- tests ---- +test("mcp call uses the active remote context and decodes structured tool output", async () => { + const calls: Array<{ url: string; headers: Headers }> = []; + const origFetch = globalThis.fetch; + globalThis.fetch = (async (url: string, opts: { body?: string; headers?: HeadersInit }) => { + const body = opts.body ? JSON.parse(opts.body) : null; + calls.push({ url: String(url), headers: new Headers(opts.headers) }); + + if (body?.method === "initialize") { + return makeResp({ jsonrpc: "2.0", id: 1, result: { protocolVersion: "2024-11-05" } }, 200, { + "mcp-session-id": "remote-session", + }); + } + return makeResp({ + jsonrpc: "2.0", + id: 2, + result: { + structuredContent: { status: "healthy", source: "remote-context" }, + content: [{ type: "text", text: "fallback content must not win" }], + }, + }); + }) as any; + + try { + const output = await captureStdout(async () => { + const { runMcpCallCommand } = await import("../../bin/cli/commands/mcp.mjs"); + const exitCode = await runMcpCallCommand("omniroute_get_health", {}, { stream: false }); + assert.equal(exitCode, 0); + }); + + assert.equal(calls.length, 2); + assert.ok(calls.every((call) => call.url === "https://remote.example.test/api/mcp/stream")); + assert.ok( + calls.every((call) => call.headers.get("authorization") === "Bearer remote-context-token") + ); + assert.deepEqual(JSON.parse(output), { status: "healthy", source: "remote-context" }); + } finally { + globalThis.fetch = origFetch; + } +}); + +test("mcp call lets explicit base URL and API key override the active context", async () => { + const calls: Array<{ url: string; headers: Headers }> = []; + const origFetch = globalThis.fetch; + globalThis.fetch = (async (url: string, opts: { body?: string; headers?: HeadersInit }) => { + const body = opts.body ? JSON.parse(opts.body) : null; + calls.push({ url: String(url), headers: new Headers(opts.headers) }); + + if (body?.method === "initialize") { + return makeResp({ jsonrpc: "2.0", id: 1, result: {} }, 200, { + "mcp-session-id": "explicit-session", + }); + } + return makeResp({ + jsonrpc: "2.0", + id: 2, + result: { content: [{ type: "text", text: "ok" }] }, + }); + }) as any; + + try { + const { runMcpCallCommand } = await import("../../bin/cli/commands/mcp.mjs"); + const exitCode = await runMcpCallCommand( + "test_tool", + {}, + { stream: false }, + { + baseUrl: "https://explicit.example.test", + apiKey: "explicit-api-key", + output: "json", + } + ); + + assert.equal(exitCode, 0); + assert.equal(calls.length, 2); + assert.ok(calls.every((call) => call.url === "https://explicit.example.test/api/mcp/stream")); + assert.ok( + calls.every((call) => call.headers.get("authorization") === "Bearer explicit-api-key") + ); + } finally { + globalThis.fetch = origFetch; + } +}); + +test("mcp call retries a transient MCP initialization failure", async () => { + let initializeAttempts = 0; + let toolCalls = 0; + const origFetch = globalThis.fetch; + globalThis.fetch = (async (_url: string, opts: { body?: string }) => { + const body = opts.body ? JSON.parse(opts.body) : null; + if (body?.method === "initialize") { + initializeAttempts++; + if (initializeAttempts === 1) { + return makeResp({ error: "temporarily unavailable" }, 503, { "retry-after": "0" }); + } + return makeResp({ jsonrpc: "2.0", id: 1, result: {} }, 200, { + "mcp-session-id": "retry-session", + }); + } + + toolCalls++; + return makeResp({ + jsonrpc: "2.0", + id: 2, + result: { content: [{ type: "text", text: "ok" }] }, + }); + }) as any; + + try { + await captureStdout(async () => { + const { runMcpCallCommand } = await import("../../bin/cli/commands/mcp.mjs"); + const exitCode = await runMcpCallCommand( + "test_tool", + {}, + { stream: false }, + { baseUrl: "https://retry.example.test", retryMax: 2 } + ); + assert.equal(exitCode, 0); + }); + assert.equal(initializeAttempts, 2); + assert.equal(toolCalls, 1); + } finally { + globalThis.fetch = origFetch; + } +}); + +test("mcp call enforces the CLI timeout and returns the timeout exit code", async () => { + let receivedAbortSignal = false; + const origFetch = globalThis.fetch; + globalThis.fetch = ((_url: string, opts: { signal?: AbortSignal }) => + new Promise((_resolve, reject) => { + const fallback = setTimeout(() => reject(new Error("missing fetch timeout")), 100); + const abort = () => { + clearTimeout(fallback); + const error = new Error("request aborted"); + error.name = "AbortError"; + reject(error); + }; + receivedAbortSignal = opts.signal instanceof AbortSignal; + if (opts.signal?.aborted) abort(); + else opts.signal?.addEventListener("abort", abort, { once: true }); + })) as any; + + try { + const { runMcpCallCommand } = await import("../../bin/cli/commands/mcp.mjs"); + const exitCode = await runMcpCallCommand( + "test_tool", + {}, + { stream: false }, + { + baseUrl: "https://timeout.example.test", + timeout: 10, + retry: false, + } + ); + assert.equal(receivedAbortSignal, true); + assert.equal(exitCode, 124); + } finally { + globalThis.fetch = origFetch; + } +}); + test("mcp call sends JSON-RPC initialize then tools/call", async () => { const calls: Array<{ url: string; body: unknown }> = []; const origFetch = globalThis.fetch; - globalThis.fetch = ((url: string, opts: unknown) => { - const u = String(url); + globalThis.fetch = ((_url: string, opts: unknown) => { + const u = String(_url); const body = opts?.body ? JSON.parse(opts.body) : null; calls.push({ url: u, body }); @@ -91,8 +276,8 @@ test("mcp call sends JSON-RPC initialize then tools/call", async () => { makeResp( { jsonrpc: "2.0", id: 1, result: { protocolVersion: "2024-11-05", capabilities: {} } }, 200, - { "mcp-session-id": "sess-1" }, - ), + { "mcp-session-id": "sess-1" } + ) ); } if (body && body.method === "tools/call") { @@ -101,21 +286,19 @@ test("mcp call sends JSON-RPC initialize then tools/call", async () => { jsonrpc: "2.0", id: 2, result: { content: [{ type: "text", text: "ok" }] }, - }), + }) ); } return Promise.resolve(makeResp({ error: "unknown" }, 400)); }) as any; try { - const { runMcpCallCommand } = await import( - "../../bin/cli/commands/mcp.mjs" - ); + const { runMcpCallCommand } = await import("../../bin/cli/commands/mcp.mjs"); const exitCode = await runMcpCallCommand( "omniroute_get_health", {}, { stream: false }, - { baseUrl: "http://localhost:20128" }, + { baseUrl: "http://localhost:20128" } ); assert.equal(exitCode, 0); @@ -130,44 +313,42 @@ test("mcp call sends JSON-RPC initialize then tools/call", async () => { }); test("mcp call passes session-id header on tools/call", async () => { - let callHeaders: Record = {}; + let callHeaders = new Headers(); const origFetch = globalThis.fetch; - globalThis.fetch = ((url: string, opts: unknown) => { + globalThis.fetch = ((_url: string, opts: unknown) => { const body = opts?.body ? JSON.parse(opts.body) : null; if (body && body.method === "initialize") { return Promise.resolve( makeResp( { jsonrpc: "2.0", id: 1, result: { protocolVersion: "2024-11-05", capabilities: {} } }, 200, - { "mcp-session-id": "sess-abc" }, - ), + { "mcp-session-id": "sess-abc" } + ) ); } if (body && body.method === "tools/call") { - callHeaders = opts.headers || {}; + callHeaders = new Headers(opts.headers); return Promise.resolve( makeResp({ jsonrpc: "2.0", id: 2, result: { content: [{ type: "text", text: "ok" }] }, - }), + }) ); } return Promise.resolve(makeResp({ error: "unknown" }, 400)); }) as any; try { - const { runMcpCallCommand } = await import( - "../../bin/cli/commands/mcp.mjs" - ); + const { runMcpCallCommand } = await import("../../bin/cli/commands/mcp.mjs"); const exitCode = await runMcpCallCommand( "test_tool", { key: "val" }, { stream: false }, - { baseUrl: "http://localhost:20128" }, + { baseUrl: "http://localhost:20128" } ); assert.equal(exitCode, 0); - assert.equal(callHeaders["mcp-session-id"], "sess-abc"); + assert.equal(callHeaders.get("mcp-session-id"), "sess-abc"); } finally { globalThis.fetch = origFetch; } @@ -180,15 +361,8 @@ test("mcp call prints result content to stdout", async () => { }); const output = await captureStdout(async () => { - const { runMcpCallCommand } = await import( - "../../bin/cli/commands/mcp.mjs" - ); - await runMcpCallCommand( - "test", - {}, - { stream: false }, - { baseUrl: "http://localhost:20128" }, - ); + const { runMcpCallCommand } = await import("../../bin/cli/commands/mcp.mjs"); + await runMcpCallCommand("test", {}, { stream: false }, { baseUrl: "http://localhost:20128" }); }); globalThis.fetch = origFetch; @@ -197,15 +371,15 @@ test("mcp call prints result content to stdout", async () => { test("mcp call prints error on non-ok response", async () => { const origFetch = globalThis.fetch; - globalThis.fetch = ((url: string, opts: unknown) => { + globalThis.fetch = ((_url: string, opts: unknown) => { const body = opts?.body ? JSON.parse(opts.body) : null; if (body && body.method === "initialize") { return Promise.resolve( makeResp( { jsonrpc: "2.0", id: 1, result: { protocolVersion: "2024-11-05", capabilities: {} } }, 200, - { "mcp-session-id": "sess-1" }, - ), + { "mcp-session-id": "sess-1" } + ) ); } if (body && body.method === "tools/call") { @@ -215,14 +389,12 @@ test("mcp call prints error on non-ok response", async () => { }) as any; try { - const { runMcpCallCommand } = await import( - "../../bin/cli/commands/mcp.mjs" - ); + const { runMcpCallCommand } = await import("../../bin/cli/commands/mcp.mjs"); const exitCode = await runMcpCallCommand( "bad_tool", {}, { stream: false }, - { baseUrl: "http://localhost:20128" }, + { baseUrl: "http://localhost:20128" } ); assert.equal(exitCode, 1); } finally { @@ -232,15 +404,15 @@ test("mcp call prints error on non-ok response", async () => { test("mcp call with stream reads SSE data", async () => { const origFetch = globalThis.fetch; - globalThis.fetch = ((url: string, opts: unknown) => { + globalThis.fetch = ((_url: string, opts: unknown) => { const body = opts?.body ? JSON.parse(opts.body) : null; if (body && body.method === "initialize") { return Promise.resolve( makeResp( { jsonrpc: "2.0", id: 1, result: { protocolVersion: "2024-11-05", capabilities: {} } }, 200, - { "mcp-session-id": "sess-stream" }, - ), + { "mcp-session-id": "sess-stream" } + ) ); } if (body && body.method === "tools/call") { @@ -265,15 +437,8 @@ test("mcp call with stream reads SSE data", async () => { }) as any; const output = await captureStdout(async () => { - const { runMcpCallCommand } = await import( - "../../bin/cli/commands/mcp.mjs" - ); - await runMcpCallCommand( - "test", - {}, - { stream: true }, - { baseUrl: "http://localhost:20128" }, - ); + const { runMcpCallCommand } = await import("../../bin/cli/commands/mcp.mjs"); + await runMcpCallCommand("test", {}, { stream: true }, { baseUrl: "http://localhost:20128" }); }); globalThis.fetch = origFetch; @@ -283,7 +448,7 @@ test("mcp call with stream reads SSE data", async () => { test("mcp status reads online field", async () => { const origFetch = globalThis.fetch; - globalThis.fetch = (async (_url: string | URL, init?: unknown) => { + globalThis.fetch = (async (_url: string | URL, _init?: unknown) => { const u = String(_url); if (u.includes("/api/health")) { return makeResp({ status: "ok" }) as any; @@ -301,9 +466,7 @@ test("mcp status reads online field", async () => { }) as any; const output = await captureStdout(async () => { - const { runMcpStatusCommand } = await import( - "../../bin/cli/commands/mcp.mjs" - ); + const { runMcpStatusCommand } = await import("../../bin/cli/commands/mcp.mjs"); const exitCode = await runMcpStatusCommand({}); assert.equal(exitCode, 0); }); @@ -328,16 +491,14 @@ test("mcp status json mode prints full object", async () => { transport: "stdio", enabled: true, toolsCount: 107, - }), + }) ); } return Promise.resolve(makeResp({ error: "not found" }, 404)); }) as any; const output = await captureStdout(async () => { - const { runMcpStatusCommand } = await import( - "../../bin/cli/commands/mcp.mjs" - ); + const { runMcpStatusCommand } = await import("../../bin/cli/commands/mcp.mjs"); const exitCode = await runMcpStatusCommand({ json: true }); assert.equal(exitCode, 0); }); diff --git a/tests/unit/cli-oneproxy-commands.test.ts b/tests/unit/cli-oneproxy-commands.test.ts index e752faf8b8..4028f5ffd9 100644 --- a/tests/unit/cli-oneproxy-commands.test.ts +++ b/tests/unit/cli-oneproxy-commands.test.ts @@ -25,33 +25,57 @@ test("oneproxy status chama omniroute_oneproxy_stats via MCP", async () => { assert.ok(calls.length >= 0); }); -test("oneproxy stats passa provider e period para MCP", async () => { +test("oneproxy stats envia o objeto vazio exigido pelo schema MCP", async () => { + const calls: any[] = []; const origFetch = globalThis.fetch; - globalThis.fetch = makeMcpStreamFetch({ toolResult: { requests: 5000 } }); - const { mcpCallTool } = await import("../../bin/cli/mcpClient.mjs"); - const result = await mcpCallTool("omniroute_oneproxy_stats", { provider: "openai", period: "24h" }); + const streamFetch = makeMcpStreamFetch({ toolResult: { stats: {}, status: {} } }); + globalThis.fetch = (async (url: string, init?: any) => { + calls.push({ url: String(url), init }); + return streamFetch(url, init); + }) as any; + const { runOneproxyStats } = await import("../../bin/cli/commands/oneproxy.mjs"); + await runOneproxyStats({}, makeCmd() as any); globalThis.fetch = origFetch; - assert.deepEqual(result, { requests: 5000 }); + const body = JSON.parse( + calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}" + ); + assert.deepEqual(body.params.arguments, {}); }); -test("oneproxy fetch chama omniroute_oneproxy_fetch com count e type", async () => { +test("oneproxy fetch maps count/type to limit/protocol and emits items", async () => { + const calls: any[] = []; const origFetch = globalThis.fetch; - globalThis.fetch = makeMcpStreamFetch({ toolResult: { proxies: [{ host: "10.0.0.1", type: "http" }] } }); - const { mcpCallTool } = await import("../../bin/cli/mcpClient.mjs"); - const result = await mcpCallTool("omniroute_oneproxy_fetch", { count: 5, type: "http" }); + const streamFetch = makeMcpStreamFetch({ + toolResult: { items: [{ host: "10.0.0.1", type: "http" }], total: 1 }, + }); + globalThis.fetch = (async (url: string, init?: any) => { + calls.push({ url: String(url), init }); + return streamFetch(url, init); + }) as any; + const { runOneproxyFetch } = await import("../../bin/cli/commands/oneproxy.mjs"); + await runOneproxyFetch({ count: 5, type: "http" }, makeCmd() as any); globalThis.fetch = origFetch; - assert.equal((result as any).proxies[0].host, "10.0.0.1"); - assert.equal((result as any).proxies[0].type, "http"); + const body = JSON.parse( + calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}" + ); + assert.deepEqual(body.params.arguments, { limit: 5, protocol: "http" }); }); -test("oneproxy rotate chama omniroute_oneproxy_rotate com provider", async () => { +test("oneproxy rotate envia somente a strategy aceita pelo schema MCP", async () => { + const calls: any[] = []; const origFetch = globalThis.fetch; - globalThis.fetch = makeMcpStreamFetch({ toolResult: { rotated: true, newProxy: "10.0.0.2" } }); - const { mcpCallTool } = await import("../../bin/cli/mcpClient.mjs"); - const result = await mcpCallTool("omniroute_oneproxy_rotate", { provider: "anthropic" }); + const streamFetch = makeMcpStreamFetch({ toolResult: { host: "10.0.0.2", type: "http" } }); + globalThis.fetch = (async (url: string, init?: any) => { + calls.push({ url: String(url), init }); + return streamFetch(url, init); + }) as any; + const { runOneproxyRotate } = await import("../../bin/cli/commands/oneproxy.mjs"); + await runOneproxyRotate({ strategy: "quality" }, makeCmd() as any); globalThis.fetch = origFetch; - assert.equal((result as any).rotated, true); - assert.equal((result as any).newProxy, "10.0.0.2"); + const body = JSON.parse( + calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}" + ); + assert.deepEqual(body.params.arguments, { strategy: "quality" }); }); test("oneproxy config set envia PUT /api/settings/oneproxy", async () => { diff --git a/tests/unit/cli-resilience-commands.test.ts b/tests/unit/cli-resilience-commands.test.ts index 1e0ae3bcbb..283a1e8e75 100644 --- a/tests/unit/cli-resilience-commands.test.ts +++ b/tests/unit/cli-resilience-commands.test.ts @@ -118,7 +118,10 @@ test("resilience profile set usa JSON-RPC tools/call", async () => { globalThis.fetch = makeMcpStreamFetch({ toolResult: {} }); const inner = globalThis.fetch; globalThis.fetch = ((url: any, init: any) => { - if (String(url).includes("/api/mcp/stream") && String(init?.body || "").includes("tools/call")) { + if ( + String(url).includes("/api/mcp/stream") && + String(init?.body || "").includes("tools/call") + ) { capturedCall = JSON.parse(init.body); } return inner(url, init); diff --git a/tests/unit/cli-skills-commands.test.ts b/tests/unit/cli-skills-commands.test.ts index b04692c8f5..c0f79319c9 100644 --- a/tests/unit/cli-skills-commands.test.ts +++ b/tests/unit/cli-skills-commands.test.ts @@ -1,6 +1,10 @@ import test from "node:test"; import { makeMcpResp, makeMcpStreamFetch } from "./helpers/mcpStreamMock.ts"; import assert from "node:assert/strict"; +import { + SkillEnableSchema, + SkillExecuteSchema, +} from "../../open-sse/mcp-server/tools/skillTools.ts"; const SKILLS_DATA = [ { id: "sk_pdf", name: "PDF Parser", type: "sandbox", version: "1.0.0", enabled: true }, @@ -130,7 +134,9 @@ test("runSkillsEnable usa JSON-RPC tools/call", async () => { globalThis.fetch = origFetch; assert.ok(calls.some((x) => String(x.url).includes("/api/mcp/stream"))); - const callBody = JSON.parse(calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}"); + const callBody = JSON.parse( + calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}" + ); assert.equal(callBody.method, "tools/call"); assert.equal(callBody.params.name, "omniroute_skills_enable"); assert.equal(callBody.params.arguments.skillId, "sk_pdf"); @@ -138,6 +144,17 @@ test("runSkillsEnable usa JSON-RPC tools/call", async () => { assert.ok(out.includes("sk_pdf")); }); +test("skill MCP schemas accept the CLI's id-based payloads", () => { + assert.deepEqual(SkillEnableSchema.parse({ skillId: "sk_pdf", enabled: true }), { + skillId: "sk_pdf", + enabled: true, + }); + assert.deepEqual(SkillExecuteSchema.parse({ skillId: "sk_pdf", input: { file: "doc.pdf" } }), { + skillId: "sk_pdf", + input: { file: "doc.pdf" }, + }); +}); + test("runSkillsExecute usa JSON-RPC tools/call", async () => { const calls: unknown[] = []; const origFetch = globalThis.fetch; @@ -154,7 +171,9 @@ test("runSkillsExecute usa JSON-RPC tools/call", async () => { ); globalThis.fetch = origFetch; - const callBody = JSON.parse(calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}"); + const callBody = JSON.parse( + calls.find((x) => String(x.init?.body || "").includes("tools/call"))?.init?.body || "{}" + ); assert.equal(callBody.method, "tools/call"); assert.equal(callBody.params.name, "omniroute_skills_execute"); assert.equal(callBody.params.arguments.skillId, "sk_pdf"); diff --git a/tests/unit/combo-auto-pool-visible-only.test.ts b/tests/unit/combo-auto-pool-visible-only.test.ts index e0748ea77b..e495507ce7 100644 --- a/tests/unit/combo-auto-pool-visible-only.test.ts +++ b/tests/unit/combo-auto-pool-visible-only.test.ts @@ -98,7 +98,9 @@ test("expandAutoComboCandidatePool excludes catalog-only models (openrouter/auto ); assert.ok( - expanded.some((t) => t.provider === "openrouter" && t.modelStr === "openrouter/liquid/lfm-2.5-2.6b:free"), + expanded.some( + (t) => t.provider === "openrouter" && t.modelStr === "openrouter/liquid/lfm-2.5-2.6b:free" + ), "a synced free model must be expanded into the pool" ); }); @@ -171,3 +173,52 @@ test("virtual auto-combo pool filters EVERY provider with partial sync, not just "kilocode pool must contain exactly the two synced models" ); }); + +test("virtual auto-combo pool keeps only chat-selectable models from an Ollama connection", async () => { + const connection = await providersDb.createProviderConnection({ + provider: "ollama-local", + authType: "apikey", + name: "Self-hosted Ollama", + apiKey: "test-key", + providerSpecificData: { baseUrl: "http://127.0.0.1:11434/v1" }, + }); + const connectionId = (connection as { id?: string }).id; + assert.ok(connectionId, "created Ollama connection must expose an id"); + + await modelsDb.replaceSyncedAvailableModelsForConnection("ollama-local", connectionId, [ + { + id: "image-model", + name: "Image Model", + apiFormat: "images-generations", + supportedEndpoints: ["images"], + }, + { + id: "embedding-model", + name: "Embedding Model", + apiFormat: "embeddings", + supportedEndpoints: ["embeddings"], + }, + { + id: "chat-model", + name: "Chat Model", + apiFormat: "chat-completions", + supportedEndpoints: ["chat"], + }, + ]); + + const prepared = await virtualFactory.prepareVirtualAutoComboInputs(); + const ollamaCandidates = prepared.regularCandidates.filter( + (candidate) => candidate.provider === "ollama-local" + ); + + assert.deepEqual( + ollamaCandidates.map((candidate) => candidate.model), + ["chat-model"], + "image- and embedding-only models must not enter a chat auto-combo pool" + ); + assert.deepEqual( + ollamaCandidates[0]?.allowedConnectionIds, + [connectionId], + "the surviving chat model must remain scoped to its advertising connection" + ); +}); diff --git a/tests/unit/combo-provider-wildcard.test.ts b/tests/unit/combo-provider-wildcard.test.ts index b328d09a4d..b10ccbcc2f 100644 --- a/tests/unit/combo-provider-wildcard.test.ts +++ b/tests/unit/combo-provider-wildcard.test.ts @@ -398,6 +398,25 @@ test("#8926: active synced catalog replaces static wildcard entries", async () = ); }); +test("Ollama provider wildcards exclude endpoint-only image and embedding models", async () => { + const connectionId = `ollama-capability-wildcard-${Date.now()}`; + await seedSyncedModels("ollama-local", connectionId, []); + await replaceSyncedAvailableModelsForConnection("ollama-local", connectionId, [ + { id: "chat-model", name: "Chat", supportedEndpoints: ["chat"] }, + { id: "image-model", name: "Image", supportedEndpoints: ["images"] }, + { id: "embedding-model", name: "Embedding", supportedEndpoints: ["embeddings"] }, + ]); + + const result = await expandProviderWildcardsInCombo( + makeCombo(["ollama-local/*"], "ollama-chat-only") + ); + + assert.deepEqual( + result.models.map((entry) => (entry as { model: string }).model), + ["ollama-local/chat-model"] + ); +}); + test("#8926: inactive synced catalog does not override static wildcard fallback", async () => { const providerId = "openai"; const inactiveModelId = "inactive-only-model-8926"; diff --git a/tests/unit/conol-web.test.ts b/tests/unit/conol-web.test.ts index 1280cc2b0d..66f90984f0 100644 --- a/tests/unit/conol-web.test.ts +++ b/tests/unit/conol-web.test.ts @@ -523,7 +523,8 @@ describe("Conol web provider", () => { // Configuration must complete before the turn is submitted. const turnIndex = calls.findIndex( - (call) => call.url.endsWith("/api/sessions/session_123/messages") && call.init?.method === "POST" + (call) => + call.url.endsWith("/api/sessions/session_123/messages") && call.init?.method === "POST" ); const lastModelIndex = calls.map((call) => call.url.endsWith("/model")).lastIndexOf(true); assert.ok(lastModelIndex < turnIndex, "model config must precede the message turn"); diff --git a/tests/unit/credential-health-disabled-boot-log.test.ts b/tests/unit/credential-health-disabled-boot-log.test.ts index e6eb92b9cc..6aea26d231 100644 --- a/tests/unit/credential-health-disabled-boot-log.test.ts +++ b/tests/unit/credential-health-disabled-boot-log.test.ts @@ -75,10 +75,10 @@ test("disabled scheduler emits [STARTUP] Credential health scheduler disabled vi }); test("instrumentation-node.ts wires initCredentialHealthCheck return to the log conditional", () => { - const src = readFileSync( - resolve(projectRoot, "src/instrumentation-node.ts"), - "utf8" - ).replace(/\r\n/g, "\n"); + const src = readFileSync(resolve(projectRoot, "src/instrumentation-node.ts"), "utf8").replace( + /\r\n/g, + "\n" + ); assert.match( src, diff --git a/tests/unit/executor-promptql.test.ts b/tests/unit/executor-promptql.test.ts index 97f52dcdc8..c16a916d3f 100644 --- a/tests/unit/executor-promptql.test.ts +++ b/tests/unit/executor-promptql.test.ts @@ -7,9 +7,7 @@ const mod = await import("../../open-sse/executors/promptql.ts"); const usage = await import("../../open-sse/services/usage/promptql.ts"); const models = await import("../../open-sse/services/promptqlModels.ts"); const { getModelsByProviderId } = await import("../../open-sse/config/providerModels.ts"); -const { WEB_COOKIE_PROVIDERS } = await import( - "../../src/shared/constants/providers/web-cookie.ts" -); +const { WEB_COOKIE_PROVIDERS } = await import("../../src/shared/constants/providers/web-cookie.ts"); // Sample JWT payload (unsigned shape for claim extraction only) function makeFakeJwt(claims: Record): string { @@ -131,10 +129,10 @@ describe("PromptQl — helpers", () => { ); } if (!auth.includes(ddnLuxJwt)) { - return new Response( - JSON.stringify({ errors: [{ message: "unexpected token in test" }] }), - { status: 200, headers: { "content-type": "application/json" } } - ); + return new Response(JSON.stringify({ errors: [{ message: "unexpected token in test" }] }), { + status: 200, + headers: { "content-type": "application/json" }, + }); } return new Response( JSON.stringify({ @@ -155,14 +153,23 @@ describe("PromptQl — helpers", () => { const result = (await usage.getPromptQlUsage(sampleJwt, { projectId: PROJECT_ID, luxJwt: ddnLuxJwt, - })) as { quotas?: { credits?: { used?: number; remaining?: number; total?: number } }; message?: string }; - assert.ok(result.quotas?.credits, `expected credits quota from luxJwt, got ${JSON.stringify(result)}`); + })) as { + quotas?: { credits?: { used?: number; remaining?: number; total?: number } }; + message?: string; + }; + assert.ok( + result.quotas?.credits, + `expected credits quota from luxJwt, got ${JSON.stringify(result)}` + ); assert.equal(result.quotas!.credits!.total, 50); assert.equal(result.quotas!.credits!.used, 22); assert.equal(result.quotas!.credits!.remaining, 28); // First attempt should use luxJwt (DDN preferred over enrich apiKey) assert.ok(calls.length >= 1); - assert.ok(calls[0]!.includes(ddnLuxJwt), `first call should use DDN luxJwt, got ${calls[0]?.slice(0, 80)}`); + assert.ok( + calls[0]!.includes(ddnLuxJwt), + `first call should use DDN luxJwt, got ${calls[0]?.slice(0, 80)}` + ); } finally { globalThis.fetch = originalFetch; } @@ -241,9 +248,7 @@ describe("PromptQl — helpers", () => { "USAGE_FETCHER_PROVIDERS must list promptql so generic quota fetcher can call it" ); assert.ok((usageMain.USAGE_FETCHER_PROVIDERS as readonly string[]).includes("pql")); - const { USAGE_SUPPORTED_PROVIDERS } = await import( - "../../src/shared/constants/providers.ts" - ); + const { USAGE_SUPPORTED_PROVIDERS } = await import("../../src/shared/constants/providers.ts"); assert.ok( (USAGE_SUPPORTED_PROVIDERS as readonly string[]).includes("promptql"), "USAGE_SUPPORTED_PROVIDERS must list promptql for provider-limits sync" @@ -252,7 +257,10 @@ describe("PromptQl — helpers", () => { it("extracts OpenAI content-parts arrays", () => { assert.equal( - mod.extractMessageText([{ type: "text", text: "hi" }, { type: "text", text: " there" }]), + mod.extractMessageText([ + { type: "text", text: "hi" }, + { type: "text", text: " there" }, + ]), "hi\n there" ); }); @@ -391,22 +399,10 @@ describe("PromptQl — thread continuity (no cross-chat sticky)", () => { }); it("readClientThreadId accepts body and header variants", () => { - assert.equal( - mod.readClientThreadId({ promptql_thread_id: "t1" } as never), - "t1" - ); - assert.equal( - mod.readClientThreadId({ thread_id: "t2" } as never), - "t2" - ); - assert.equal( - mod.readClientThreadId({} as never, { "X-PromptQL-Thread-Id": "t3" }), - "t3" - ); - assert.equal( - mod.readClientThreadId({} as never, { "x-conversation-id": "t4" }), - "t4" - ); + assert.equal(mod.readClientThreadId({ promptql_thread_id: "t1" } as never), "t1"); + assert.equal(mod.readClientThreadId({ thread_id: "t2" } as never), "t2"); + assert.equal(mod.readClientThreadId({} as never, { "X-PromptQL-Thread-Id": "t3" }), "t3"); + assert.equal(mod.readClientThreadId({} as never, { "x-conversation-id": "t4" }), "t4"); }); it("system messages do not collide independent user chats", () => { @@ -528,10 +524,7 @@ describe("PromptQl — thread continuity (no cross-chat sticky)", () => { it("normalizeForFingerprint strips agent_mention and User request wrappers", () => { assert.equal(mod.normalizeForFingerprint(" hello"), "hello"); - assert.equal( - mod.normalizeForFingerprint("noise\n\nUser request:\nhello 2"), - "hello 2" - ); + assert.equal(mod.normalizeForFingerprint("noise\n\nUser request:\nhello 2"), "hello 2"); }); }); diff --git a/tests/unit/gemini-strict-tool-schema.test.ts b/tests/unit/gemini-strict-tool-schema.test.ts index 0aaac46bf0..1225d16552 100644 --- a/tests/unit/gemini-strict-tool-schema.test.ts +++ b/tests/unit/gemini-strict-tool-schema.test.ts @@ -62,5 +62,8 @@ test("OpenAI -> Gemini request strips strict from OpenAI-style function tool par const parameters = result.tools?.[0]?.functionDeclarations?.[0]?.parameters; assert.ok(parameters, "expected a translated function declaration"); - assert.ok(!JSON.stringify(parameters).includes("strict"), "strict must not reach the upstream request"); + assert.ok( + !JSON.stringify(parameters).includes("strict"), + "strict must not reach the upstream request" + ); }); diff --git a/tests/unit/helpers/mcpStreamMock.ts b/tests/unit/helpers/mcpStreamMock.ts index 9ffc3774f1..e21b0ded61 100644 --- a/tests/unit/helpers/mcpStreamMock.ts +++ b/tests/unit/helpers/mcpStreamMock.ts @@ -1,4 +1,3 @@ - import type { Response as Resp } from "undici"; // Minimal fetch mock responses that satisfy what apiFetch needs. @@ -15,7 +14,7 @@ export function makeMcpResp(data: unknown, status = 200, headers: Record }; + const en = JSON.parse(readFileSync(join(repoRoot, "src/i18n/messages/en.json"), "utf8")) as { + home: Record; + }; return Object.keys(en.home); } diff --git a/tests/unit/image-credential-retry-endpoint-scope.test.ts b/tests/unit/image-credential-retry-endpoint-scope.test.ts new file mode 100644 index 0000000000..95dfdfaf9b --- /dev/null +++ b/tests/unit/image-credential-retry-endpoint-scope.test.ts @@ -0,0 +1,24 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { executeImageWithCredentialFallback } from "../../src/sse/services/imageCredentialRetry.ts"; + +test("image credential retries stay within the connections advertising the endpoint model", async () => { + const allowedConnectionIds = ["image-a", "image-b"]; + let observedAllowedConnectionIds: string[] | null | undefined; + + const result = await executeImageWithCredentialFallback({ + provider: "ollama-local", + requestedModel: "flux-dev", + allowedConnectionIds, + credentials: { connectionId: "image-a" }, + execute: async () => ({ success: false, status: 401 }), + selectNextCredentials: async (_provider, _model, _excluded, allowed) => { + observedAllowedConnectionIds = allowed; + return null; + }, + }); + + assert.deepEqual(observedAllowedConnectionIds, allowedConnectionIds); + assert.equal(result.result.status, 401); +}); diff --git a/tests/unit/ollama-local-capabilities-routing.test.ts b/tests/unit/ollama-local-capabilities-routing.test.ts index 0ce75a2983..cd038659e2 100644 --- a/tests/unit/ollama-local-capabilities-routing.test.ts +++ b/tests/unit/ollama-local-capabilities-routing.test.ts @@ -157,8 +157,10 @@ test("Ollama image model routes through its advertising connection", async () => ]); let capturedUrl = ""; - globalThis.fetch = async (input) => { + let capturedBody: Record = {}; + globalThis.fetch = async (input, init = {}) => { capturedUrl = String(input); + capturedBody = JSON.parse(String(init.body || "{}")) as Record; return Response.json({ data: [{ b64_json: "aW1hZ2U=" }] }); }; @@ -172,6 +174,7 @@ test("Ollama image model routes through its advertising connection", async () => assert.equal(response.status, 200, await response.text()); assert.equal(capturedUrl, "http://127.0.0.1:11435/v1/images/generations"); + assert.equal(capturedBody.model, "image-model"); }); test("Ollama embedding model routes through its advertising connection", async () => { diff --git a/tests/unit/opencode-go-console-go-effort-clamp.test.ts b/tests/unit/opencode-go-console-go-effort-clamp.test.ts index 2009d11a39..3611c967aa 100644 --- a/tests/unit/opencode-go-console-go-effort-clamp.test.ts +++ b/tests/unit/opencode-go-console-go-effort-clamp.test.ts @@ -73,11 +73,7 @@ test("clamp: disable-shaped efforts map to low (upstream refuses to stop thinkin for (const effort of ["none", "minimal"]) { const body = { ...HERMES_BODY, reasoning_effort: effort }; const result = sanitizeReasoningEffortForProvider(body, "opencode-go", "ox-alpha-free", null); - assert.equal( - (result as Record).reasoning_effort, - "low", - `${effort} → low` - ); + assert.equal((result as Record).reasoning_effort, "low", `${effort} → low`); } }); @@ -103,10 +99,12 @@ test("clamp writes back to every carrier present (top-level + reasoning.effort + reasoning: { effort: "medium" }, output_config: { effort: "medium" }, }; - const result = sanitizeReasoningEffortForProvider(body, "opencode-go", "ox-alpha-free", null) as Record< - string, - unknown - >; + const result = sanitizeReasoningEffortForProvider( + body, + "opencode-go", + "ox-alpha-free", + null + ) as Record; assert.equal(result.reasoning_effort, "high"); assert.deepEqual(result.reasoning, { effort: "high" }); assert.deepEqual(result.output_config, { effort: "high" }); @@ -114,7 +112,12 @@ test("clamp writes back to every carrier present (top-level + reasoning.effort + test("no declaration → pass-through unchanged (#8057 policy for unlisted models)", () => { const body = { ...HERMES_BODY, model: "some-unregistered-model", reasoning_effort: "medium" }; - const result = sanitizeReasoningEffortForProvider(body, "opencode-go", "some-unregistered-model", null); + const result = sanitizeReasoningEffortForProvider( + body, + "opencode-go", + "some-unregistered-model", + null + ); assert.equal(result, body, "undeclared models keep today's trust-the-upstream behavior"); assert.equal((result as Record).reasoning_effort, "medium"); }); diff --git a/tests/unit/translator-openai-to-gemini.test.ts b/tests/unit/translator-openai-to-gemini.test.ts index 2111f23f64..ab6a9a3c5e 100644 --- a/tests/unit/translator-openai-to-gemini.test.ts +++ b/tests/unit/translator-openai-to-gemini.test.ts @@ -866,7 +866,11 @@ test("OpenAI -> Antigravity maps Claude-family models to Gemini-compatible schem assert.match(result.requestId, /^agent\/\d+\/[0-9a-f]{8}$/); assert.equal(result.enabledCreditTypes, undefined); assert.equal(result.request.systemInstruction.parts[0].text, ANTIGRAVITY_DEFAULT_SYSTEM); - assert.equal(result.request.systemInstruction.parts.length, 1, "systemInstruction must contain only ANTIGRAVITY_DEFAULT_SYSTEM (#9030)"); + assert.equal( + result.request.systemInstruction.parts.length, + 1, + "systemInstruction must contain only ANTIGRAVITY_DEFAULT_SYSTEM (#9030)" + ); // #9030 — Client system content moved to first user message to avoid upstream 429s assert.equal(result.request.contents[0].parts[0].text, "Project rules"); assert.equal(result.request.contents[0].parts[1].text, "Read a file"); diff --git a/tests/unit/translator-resp-gemini-to-openai.test.ts b/tests/unit/translator-resp-gemini-to-openai.test.ts index 0b5425562c..8687dd7d7d 100644 --- a/tests/unit/translator-resp-gemini-to-openai.test.ts +++ b/tests/unit/translator-resp-gemini-to-openai.test.ts @@ -1174,7 +1174,10 @@ test("Gemini stream: open textual reasoning is flushed before a signed native to "buffered textual reasoning must be flushed, not dropped, when a tool call arrives" ); assert.equal(r2[toolIdx]?.choices[0].delta.tool_calls[0].id, "call-flush-1"); - assert.ok(reasoningIdx >= 0 && toolIdx > reasoningIdx, "reasoning is emitted before the tool call"); + assert.ok( + reasoningIdx >= 0 && toolIdx > reasoningIdx, + "reasoning is emitted before the tool call" + ); }); // #3821-review LEDGER-15 — a reasoning-only chunk interrupting a partially-buffered diff --git a/tests/unit/vertex-anthropic-models.test.ts b/tests/unit/vertex-anthropic-models.test.ts index 8da49c67da..f2b20e210d 100644 --- a/tests/unit/vertex-anthropic-models.test.ts +++ b/tests/unit/vertex-anthropic-models.test.ts @@ -1,8 +1,9 @@ /** * Vertex AI Anthropic partner-model discovery (#11279). * - * Covers the two pure units the PR adds (the discovery route itself is a - * best-effort network path exercised manually per the PR's test plan): + * Covers the pure discovery contracts (the route's external request remains a + * best-effort network path): + * - Model Garden PublisherModels URL: the documented v1beta1 global parent; * - parseVertexAnthropicModels: Model Garden publisher response → discovery * models, handling global AND project-scoped resource names; * - getModelTargetFormat: a claude-* id on vertex/vertex-partner resolves to @@ -12,12 +13,22 @@ import test from "node:test"; import assert from "node:assert/strict"; -import { parseVertexAnthropicModels } from "../../src/lib/providerModels/vertexAnthropicModelsParser.ts"; +import { + parseVertexAnthropicModels, + VERTEX_ANTHROPIC_PUBLISHER_MODELS_URL, +} from "../../src/lib/providerModels/vertexAnthropicModelsParser.ts"; import { getModelTargetFormat } from "../../open-sse/config/providerModels.ts"; +test("Vertex Anthropic discovery uses the v1beta1 PublisherModels list endpoint", () => { + assert.equal( + VERTEX_ANTHROPIC_PUBLISHER_MODELS_URL, + "https://aiplatform.googleapis.com/v1beta1/publishers/anthropic/models" + ); +}); + test("parseVertexAnthropicModels: global publisher resource names", () => { const out = parseVertexAnthropicModels({ - models: [ + publisherModels: [ { name: "publishers/anthropic/models/claude-sonnet-4-6", displayName: "Claude Sonnet 4.6", @@ -42,7 +53,7 @@ test("parseVertexAnthropicModels: global publisher resource names", () => { test("parseVertexAnthropicModels: project-scoped resource names strip the prefix", () => { const out = parseVertexAnthropicModels({ - models: [ + publisherModels: [ { name: "projects/my-gcp-project/locations/us-east5/publishers/anthropic/models/claude-haiku-4-5", }, @@ -55,9 +66,32 @@ test("parseVertexAnthropicModels: project-scoped resource names strip the prefix test("parseVertexAnthropicModels: malformed input yields an empty list", () => { assert.deepEqual(parseVertexAnthropicModels(null), []); + assert.deepEqual(parseVertexAnthropicModels(42), []); + assert.deepEqual(parseVertexAnthropicModels("not-an-envelope"), []); + assert.deepEqual(parseVertexAnthropicModels([]), []); assert.deepEqual(parseVertexAnthropicModels({}), []); - assert.deepEqual(parseVertexAnthropicModels({ models: "not-an-array" }), []); - assert.deepEqual(parseVertexAnthropicModels({ models: [{ name: "" }, {}] }), []); + assert.deepEqual( + parseVertexAnthropicModels({ + models: [{ name: "publishers/anthropic/models/claude-wrong-envelope" }], + }), + [] + ); + assert.deepEqual(parseVertexAnthropicModels({ publisherModels: "not-an-array" }), []); + assert.deepEqual(parseVertexAnthropicModels({ publisherModels: [{ name: "" }, {}] }), []); + assert.deepEqual( + parseVertexAnthropicModels({ + publisherModels: [null, 42, "invalid", { name: "publishers/anthropic/models/claude-valid" }], + }), + [ + { + id: "claude-valid", + name: "claude-valid", + supportedEndpoints: ["chat"], + targetFormat: "claude", + owned_by: "anthropic", + }, + ] + ); }); test("getModelTargetFormat: claude-* on vertex resolves to the claude translator (heuristic)", () => {