Compare commits

...

59 Commits

Author SHA1 Message Date
diegosouzapw
5635565595 chore(release): preserve reconciled changelog 2026-09-02 08:26:27 -03:00
diegosouzapw
f89093def1 Merge remote-tracking branch 'origin/release/v3.8.51' into fix/v3851-streamhandler-public-errors 2026-09-02 08:20:29 -03:00
diegosouzapw
54e2cc7aa0 test(streaming): isolate public error boundary fixture 2026-09-02 08:20:20 -03:00
Diego Rodrigues de Sa e Souza
6da2418247 chore(providers): remove a keyless provider integration at its operator's request (#12440)
The service operator asked in writing (2026-08-30) that their service be
removed from OmniRoute entirely: executor, registry entry, no-auth catalog
entry and alias, icon mapping, env var, docs rows, dedicated tests and
snapshots, and every passing mention in comments, fixtures and CHANGELOG
entries. Provider count drops from 355 to 354 on every canonical surface.

Co-authored-by: Markus Hartung <diegosouzapw@users.noreply.github.com>
2026-09-02 07:11:38 -03:00
diegosouzapw
4c39274a96 fix(streaming): sanitize generic stream failures 2026-09-02 06:52:40 -03:00
Diego Rodrigues de Sa e Souza
93fdc16e72 chore(lint): adopt eslint-plugin-react-hooks 7.1.1 (#12428)
* chore(lint): adopt eslint-plugin-react-hooks 7.1.1

The #12146 migration (284 react-hooks compiler-rule violations resolved in 8
batches) completed on 2026-09-01, unblocking the 7.1.1 adoption the pin test
was holding back. Exact pin kept in both devDependencies and overrides; the
pin test moves to 7.1.1 (the dependabot-level ignore from #12329 stays — a
lint plugin coupled to the compiler rules always bumps via its own reviewed
PR, never riding a group).

* chore(lint): lockfile for the react-hooks 7.1.1 adoption

Generated with a bare 'npm install --package-lock-only' (naming the package
on the CLI rewrites the devDependency with a caret, which npm 11 then rejects
against the exact override). Validated on the .113 with a fresh npm ci +
cold NODE_OPTIONS=8G lint:json --max-warnings 0 → exit 0 (zero new
violations from the 7.1.1 rule set) and the re-pinned version test green.
2026-09-02 06:22:30 -03:00
Diego Rodrigues de Sa e Souza
7802f6ea16 fix(uc): route UC error strings through sanitizeErrorMessage; allowlist the retired codex id (#12437)
Drains the two remaining Fast Quality Gates reds the #11513 (UC) merge left
on the tip:

- error-helper: ucTts.ts and uc/ws.ts built error payloads from raw
  err.message (Hard Rule #12) — now wrapped in sanitizeErrorMessage(),
  behavior otherwise identical (uc suites 51/51).
- model-lifecycle: the UC catalog registers the vendor-retired gpt-5.2-codex
  (bare id; only the prefixed openai/gpt-5.2-codex was allowlisted). Added to
  allowedRetiredInCatalog per its policy — forwarding globally would rewrite
  the just-approved provider's model. Tracking: Refs #12436.

file-size, the third red of this window, was already drained by #12434.
2026-09-02 05:12:11 -03:00
Diego Rodrigues de Sa e Souza
6d556c2422 fix(quality): record the 2026-09-02 merged growth in the file-size baseline (#12434)
check-file-size was red on release/v3.8.51 with nine violations — seven source files and two test files that the 2026-09-02 merge waves grew at existing chokepoints (#12359-#12404, #11461, #11513, #12423).

The growth itself was reviewed: each file was measured and justified while validating those batches. What went wrong is the propagation — the rebaseline was computed in the throwaway combined validation worktree, and the PRs were then merged individually through their own branches, so the code landed and the caps did not. A shared-file edit made only in the validation tree reaches nothing.

This records the caps against the merged state, each entry attributed to the PR that grew it, under one _rebaseline annotation. Verified mechanically: 9 caps recorded, 0 raised beyond the file's real merged LOC, 0 unrelated entries moved — the ratchet #12411 re-tightened is intact.

Verified: check-file-size OK (135 frozen source entries across 4515 files; 39 frozen test entries across 5365), prettier clean.
2026-09-02 04:27:08 -03:00
Diego Rodrigues de Sa e Souza
9704195417 fix(providers): repair the maxai credential block truncated by merge auto-resolve (#12433)
The #11461 × #11513 merge ate the closing '],' + '},' of the maxai entry in
webSessionCredentials.ts — 11 syntax errors (TS1005/1137/1128) on the tip,
which also masked one real TS2322 the MaxAI block introduced in the models
route (providerSpecificData is unknown on the connection; cast to the exact
shape resolveMaxaiCredential already takes, zero runtime change).

API Route Typecheck gate: OK — 289 pre-existing, all baselined. typecheck:core: 0.
2026-09-02 04:00:37 -03:00
backryun
752aac65d6 fix(ci): repair release-root regressions — pack dedup, web-session syntax, uc-image ids (#12423)
Three regressions inherited by every PR rebased onto release/v3.8.51, caught and documented with the exact failing output.

The one that mattered most: src/shared/providers/webSessionCredentials.ts did not parse. The UC merge (#11513) inserted the uc: entry inside maxai.storageKeys and lost the array's closing ], plus the entry's }, leaving `ERROR: Expected "]" but found ":"` at line 351. That module is imported by the provider API routes, bulk-web-session, autoCombo's virtualFactory, keepaliveThreshold and dashboard components, so the break was live on the tip and flooded unrelated catalog tests with transform failures. That was my conflict resolution, not the contributor's code — thank you for catching it and for tracing it to the root commit rather than patching around the symptom.

Also fixed: the duplicate bin/cli/utils/volatileEnvPath.mjs entry in PACK_ARTIFACT_REQUIRED_PATHS (findMissingArtifactPaths reported it twice), and UC image models made prefix-addressable without letting them claim historical bare model ids belonging to other providers.

Reconciled on merge: #12394 landed the busy_timeout/probe work first, so src/lib/db/core.ts takes the tip's side. probeUtils.ts is the union of both rather than either side — this PR's message regex is wider (SQLite also reports "database table is locked", "database schema is locked" and "database is busy"), while #12394 added the driver code/errcode path that keeps a transient lock from being classified as corruption and renaming the database away. Taking either alone would have dropped the other half; this PR's own ENOENT test is what surfaced it.

Verified: 76/76 across uc-image, probe-9541-repro, web-session-contract, pack-artifact-policy, bulk-web-session-import and exclusive-connection-leases, and every changed .ts file parses.

Thanks @backryun.
2026-09-02 03:57:46 -03:00
Paco Cartones
2c6e6cd13e fix(providers): list gemini-business models in the registry (#12389)
GET /v1/providers/gemini-business/models returned nothing because gemini-business had no RegistryEntry: the listing route resolves the provider through getRegistryEntry and filters the unified catalog by owned_by, and open-sse/config/providers/index.ts only registered gemini and gemini-web.

Adds a registry entry mirroring gemini_webProvider — id gemini-business, alias gembiz, cookie auth — with the twelve ids from the executor's MODEL_CATEGORY_MAP. Each model is declared toolCalling: false, supportsReasoning: false, the same live-behaviour contract applied to gemini-web in #9356: the executor returns plain text, hard-wires the thinking mode and parses no tool calls.

Reconciled on merge: the only conflict was the reserved-prefix count assertion, which the tip had moved. Took the tip's text and measured the real value with this PR applied — 406 to 408, the gemini-business id plus its gembiz alias — rather than carrying the branch's number.

Validated in a combined worktree with all 25 PRs of this batch boarded together (typecheck:core clean, 443/443 node-runner plus 14/14 vitest, all static gates green), and re-verified standalone on the current tip after the other 24 landed: 33/33 across provider-node-reserved-prefix, gemini-business-model-registry-12107 and web-cookie-validation-fallback, with check:provider-consistency OK at 272 REGISTRY entries and 355 canonical providers.

Thanks @pacocartones.
2026-09-02 03:19:08 -03:00
Paco Cartones
f41a9bd835 feat(admin): localize the anomalies page and add it to the sidebar (#12401)
The gamification anomalies page had hard-coded English for its loading state, Status column header and Suspicious badge, and was the only standalone non-redirect dashboard page without a sidebar entry. Both are fixed: the strings come from the common catalog, and the page joins the Gamification sidebar group as a hideable section item shown only by the "all" preset, like its siblings. The loading and empty states also become role="status" aria-live="polite" live regions with aria-busy, matching profile/page.tsx and health/page.tsx. Three new keys in en.json, propagated to the other 42 locales with the __MISSING__ sentinel.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:15:42 -03:00
Paco Cartones
26d20a0009 fix(api-manager): preserve allowedCombos entries the Combo picker cannot render (#12397)
The API key permissions modal silently dropped allowedCombos entries its Combo picker cannot render — routing-rule names such as rt-*, which matchesComboAccessRule() already honours. Stored entries rendered as zero selected, and clicking All then Restrict then Save persisted allowedCombos: [], which is deny-all for combo requests.

Those entries now survive the All toggle, are listed read-only under the combo list so the header count and the list agree, and are saved back verbatim. The UI does not learn routing-rule semantics (option 1 from the issue). The Allowed Combos section moves out of the frozen ApiManagerPageClient.tsx into its own component following the UsageLimitSettings pattern.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:15:31 -03:00
Paco Cartones
990aeca1db fix(api): list self-aliased providers in canonical models catalog mode (#12381)
GET /v1/models with MODELS_CATALOG_PREFIX_MODE=canonical dropped every chat row of a provider whose registry alias is undefined (antigravity) or equal to its own id (agy, most built-ins). Each emission loop pushes alias/model only when includeAlias, and canonicalProviderId/model only when the ids differ — for a self-aliased provider both are the same string, so neither fired. #11918 fixed the class for custom nodes but not built-ins, and not the static loop. The alias row is now treated as the canonical row whenever the ids coincide, across the static, synced, custom and alias-backed loops; the canonical branch's !== alias guard is untouched, so dual and alias output cannot double up. Docs that described the omission as intended are corrected.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:15:24 -03:00
Paco Cartones
0ec7504024 fix(sse): preserve ZWNJ and ZWJ in sanitized responses (#12359)
The response de-obfuscation stripped the whole U+200B..U+200D range, so Persian/Kurdish half-spaces (U+200C), Arabic/Indic shaping and emoji ZWJ sequences (U+200D) were deleted from every assistant response — text, reasoning and tool-call arguments, streaming and non-streaming, every provider: ارائه‌دهنده came back as ارائهدهنده.

The request side only ever inserts a U+200D between two ASCII word characters, so the new stripObfuscationZeroWidth() removes a joiner only there, or at a string edge next to one so a word split across streaming deltas is still cleaned; U+200B and U+FEFF keep their unconditional removal. All seven copies of the old regex now go through the helper.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:15:19 -03:00
Paco Cartones
5a34111125 fix(resilience): count resolved 5xx results against the provider breaker (#12360)
CircuitBreaker.execute() treated every resolved promise as a success, but handleChatCore() reports most upstream failures by resolving with { success: false, status: 5xx }. On the chat path that spurious _onSuccess() decayed failureCount right before the call site's _onFailure() for the same attempt, so a provider answering 503s indefinitely stayed CLOSED at failureCount: 1 and kept receiving traffic — the breaker was structurally unable to open. Combo dispatches hit the same cancellation through the shared per-provider breaker.

execute() now takes an optional per-call classifyResult; without it the resolved-means-success contract every throw-based caller relies on is unchanged. executeChatWithBreaker() passes ignore and the chat path accounts for the outcome exactly once where the request context lives, so a combo success is no longer counted twice.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:14:54 -03:00
Paco Cartones
62e2481eef fix(resilience): derive the chat_admission_busy Retry-After from observed lease occupancy (#12395)
The retryable chat_admission_busy 503 advertised a fixed Retry-After of 1s or 2s while the heavyweight lease it waits on is held for the entire SSE lifetime. Clients that honour the header — Codex CLI, agent fan-out — re-sent the same ~1 MiB /v1/responses body every second into a gate that could not have cleared, producing the queue_timeout retry storm that persisted even after OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT was raised.

ChatAdmissionController now tracks each live heavy lease's acquisition time and derives the hint from observed occupancy: the larger of the queue window the waiter already exhausted and the age of the youngest live lease, rounded up and capped at 60s. Both builders floor it at the historical 1s / 2s, so an idle gate answers exactly as before. Using the youngest rather than the oldest lease avoids a pessimistic hint when several slots are in flight.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:14:50 -03:00
Paco Cartones
5a490b19e2 feat(gamification): show API key names on the leaderboard (#12385)
The Leaderboard rendered apiKeyId.slice(0, 8)… under a column translated as "name". The route now enriches each entry with the key's display name — route-local, so the shared getTopN helper and the federation leaderboard stay id-only — and the page renders name ?? shortId with the full id in a title attribute. The lookup selects only id and name from api_keys, chunked at 200 ids, with unknown ids and blank names omitted; no key material leaves the DB layer.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:14:46 -03:00
Paco Cartones
4f4aa74199 feat(gamification): show the real daily streak on the profile page (#12377)
The Profile page already rendered a streak card but fed it a hard-coded useState(0) with a "streak data comes from future API" note — while streaks.ts tracked per-key streaks all along and the MCP gamification_profile tool already returned them. GET /api/gamification/level now returns streak: { current, longest } next to level: the key's own streak with apiKeyId, the operator-wide maximum otherwise, matching the aggregate mode getAggregateXp uses (#3484). No new route, no OpenAPI change, no new i18n keys; a missing or zero streak keeps the card hidden exactly as before.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:14:41 -03:00
Paco Cartones
01d97beb8b fix(translator): drop unsigned thinking blocks instead of fabricating a Claude signature (#12386)
A thinking content part arriving with no signature — typical after a cross-provider hop where reasoning_content was converted into a thinking block — was stamped with DEFAULT_THINKING_CLAUDE_SIGNATURE. prepareClaudeRequest treats any non-empty signature on the latest assistant turn as genuine and preserves it verbatim, so the fabricated one reached Anthropic and the replay failed with "Invalid signature". A missing signature is now treated the same as an empty one, aligned with the stricter check claudeHelper.ts already used: the block is dropped rather than fabricated. Real signatures are still preserved verbatim and redacted_thinking is unchanged.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:14:18 -03:00
Paco Cartones
70f33e323c fix(executors): let the ambient proxy stand when an OpenCode account has none (#12380)
A proxy assigned to an opencode / opencode-go connection is pinned by the chat handler as the ambient proxy context before the executor runs. OpencodeExecutor only reads per-account proxies from providerSpecificData.accountProxies, so an API-key connection with none took the single-account fast path — which wrapped the dispatch in runWithDirectFetchContext(), and that direct sentinel makes patchedFetch bypass the ambient context and hit native fetch. The assigned proxy was discarded and the request egressed from the host IP, giving `403 This model is not available in your country` on geoblocked hosts. The fast path now applies the direct pin only when no ambient context exists.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:14:13 -03:00
Paco Cartones
8d16a50df5 fix(api): keep the images wrapper on combo routes and default Codex to b64_json (#12362)
POST /v1/images/generations through a combo returned a bare array instead of the OpenAI {created, data} payload: executeImageCombo() unwrapped one level too many, and the n used for cost calculation read the same double-nested shape, so it was always 0. The combo path now returns the handler payload unchanged, matching the direct-model path.

Second half: Codex image results emitted a data: URI in url whenever response_format was not b64_json, but OpenAI returns b64_json for the gpt-image-* family — clients that omit the field, Codex CLI's built-in image_gen among them, could decode neither shape. Codex now defaults to b64_json; an explicit response_format: "url" keeps its previous behaviour. Both land together because fixing one leaves Codex CLI failing at the other.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:14:09 -03:00
Paco Cartones
3a5641839e fix(sse): name the shadowed custom provider node in the no-credentials error (#12365)
When a built-in provider's id or alias reserves the prefix of an existing OpenAI/Anthropic-compatible node — v3.8.50 added openference with alias of, shadowing nodes created earlier with prefix of — the runtime error `No active credentials for provider: openference` gave the operator nothing to act on. It now explains that the prefix routed to the built-in, names the shadowed node, and logs an AUTH warning. Precedence is unchanged and the lookup runs only on the credential-failure path when no connection was tried, so the hot routing path is byte-identical.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:14:05 -03:00
Paco Cartones
c8e2cb3ffc fix(db): install busy_timeout before the connection's first statement (#12394)
getDbInstance() ran PRAGMA journal_mode = WAL as the connection's first statement, before PRAGMA busy_timeout, and openSqliteDatabase() passes no driver-level timeout. A process opening the database while another closed its WAL connection — checkpoint plus WAL delete hold an EXCLUSIVE lock for a few hundred microseconds — therefore died with `database is locked` instead of waiting. That is the flake behind exclusive-connection-leases.test.ts on release/v3.8.51 runs 33525300898 and 33493797519 and on unrelated PR runs.

The second half is worse than the flake: isTransientProbeError matched /SQLITE_BUSY/ against error.message, but both drivers report the plain text `database is locked` and put the code in .code / .errcode. A transient lock during the corruption probe therefore took the corrupt-database path and renamed the file to storage.sqlite.probe-failed-… with "Manual recovery required". The probe now recognises the drivers' real BUSY/PROTOCOL/IOERR signals.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:13:41 -03:00
Paco Cartones
bb5c6d148e feat(gamification): enforce the per-key XP rate limit on the award path (#12390)
validateScoreChange() — the documented 1000 XP/min per-API-key limit plus the velocity anomaly check — was exported but never called, so the award path applied every XP delta unconditionally. It now runs before addXp; a rejected award is logged at warn level and skipped, and the fire-and-forget path never throws.

The second finding is the one that made the first invisible: getRecentXp's window query was inert. created_at is stored by the table default as YYYY-MM-DD HH:MM:SS and was compared lexically against a JS ISO string, so same-day rows never matched and the limit could not have tripped even if it had been wired. The window start is now computed in SQLite, matching the style computeZScore already used.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:13:37 -03:00
Paco Cartones
eb09e894cb docs: align env and troubleshooting docs with the code (#12404)
Four documentation claims contradicted the code: .env.example called OMNIROUTE_USE_TURBOPACK dev-only and said the production build still uses webpack (it reads the same flag and defaults to Turbopack); the README's Bun section said `bun run build` auto-detects Bun and switches to Webpack (only `bun run dev` does — the production bundler is decided by the flag alone); TROUBLESHOOTING.md gave OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT a default of 1 when unset means no request-count cap; and it quoted the pre-#12223 wording of the structural 503 chat_admission_busy message. The Retry-After bullet in the same section is deliberately untouched because #12395 rewrites it.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:13:31 -03:00
Paco Cartones
1146c9b5b5 fix(catalog): write NUL key separators as escape sequences instead of raw bytes (#12403)
Four files embedded the U+0000 separator of a memo/group key as a raw NUL byte rather than the \\0 escape the codebase uses for the same idiom elsewhere. The runtime value is identical, but the raw byte trips the binary heuristics of git, GitHub and ripgrep: git diff --numstat reported `-  -`, the introducing PRs rendered three of the files as "Binary file not shown", and rg silently skipped them in recursive mode. Rewritten as escapes, with a guard test keeping raw NUL bytes out of src/, open-sse/ and tests/.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:13:27 -03:00
Paco Cartones
674d39137d fix(cli): resolve the Bun preload path against the package root (#12387)
Under Bun the server child is spawned with --preload <path>/open-sse/utils/setupPolyfill.ts, and all three spawn sites built that path next to the server bundle — but the polyfill only ships at the package root and nothing copies it into dist/. Every `bun install -g omniroute` start died with `error: preload not found`. The preload now resolves from the supervisor module's own location and is shared by the two serve.mjs spawns, with the child argv moved into a pure buildServerSpawnArgs() so both branches are directly assertable (same seam as #8131). Node users are unaffected.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:13:00 -03:00
Paco Cartones
290f723ec0 fix(guardrails): keep auto combos exempt from the vision bridge credential guard (#12373)
getBestVisionModel() validates a configured fixedModel with hasUsableCredentialsForModel() before short-circuiting (#8430). auto / auto/* ids are virtual combos with no provider row, so that check always reported a confirmed false and the combo was silently discarded in favour of global auto-selection — it never got the chance to rotate its members. This mirrors the exemption the reroute guard in visionBridge.ts already carries; concrete fixedModel ids keep the #8430 fall-through unchanged.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:12:55 -03:00
Paco Cartones
393c305a71 fix(providers): resolve the Codex auto-ping model from the live catalog instead of a retired id (#12361)
The opt-in Codex quota auto-ping pinned gpt-5.1-codex-mini. OpenAI shut that model down on 2026-07-23 and the repo's own lifecycle registry already rejects it on the request path, but the scheduler never consulted that gate — every window slide sent a dead id, hit the 15-minute failure cooldown, and retried the same id forever. The ping model now resolves per tick from the provider catalog through isModelSelectable(), the same gate chatCore uses, with the registry import kept lazy because this module sits on the instrumentation boot path (#12074). When nothing is selectable the provider is paused before any throttle slot, usage read or executor call, with one warning per state change.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:12:51 -03:00
Paco Cartones
d337c5d30d test(executors): restore the #10986 reasoning-only fallback guards (#12364)
The #10265 rewrite of command-code-executor.test.ts (b6412c6fe) deleted the two regression tests #10986 added for reasoning-only Command Code output, while the production fallback in createJsonResponse / createStreamResponse survived — leaving it unguarded. Both are restored, now routed through the /alpha/generate fallback that is the only way to reach the CLI translator since #10265, via a shared goPlanFallbackFetch() helper.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:12:46 -03:00
Paco Cartones
0389b07257 fix(auth): prefer accounts without backoff in least-used rotation (#12375)
The least-used strategy ranked candidates by lastUsedAt alone, so after a 429 excluded the active account the replacement could be one that was merely oldest while still carrying its own backoff — it served a single request before the next one settled on a healthy account, the one-request detour with two cache misses reported on Codex. least-used now applies the backoffLevel tie-break the round-robin fallback branch already had, ahead of the existing never-used / oldest / priority order.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:12:25 -03:00
Paco Cartones
e7b1448281 fix(combo): name output_tokens as the exclusion reason instead of structured output (#12374)
When every combo target is excluded because the request's max_tokens exceeds each target's known output limit, the terminal 400 now says so — requested max_tokens against the pool's highest known ceiling — instead of the unrelated "supports structured output for this request". Diagnostics (unmet, excluded[].reason, terminalReason) are unchanged; only the message for the output_tokens primary reason moves.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:12:22 -03:00
Paco Cartones
8e474914ea fix(providers): mark groq compound and allam-2-7b as non-reasoning models (#12379)
groq/compound and allam-2-7b were absent from the curated Groq registry, so the capability heuristic defaulted them to reasoning-capable and forwarded reasoning_effort verbatim — Groq answers HTTP 400. Declaring supportsReasoning: false makes applyThinkingBudget() strip reasoning_effort, output_config.effort and thinking, same class as #3258. The gpt-oss reasoning models keep the field.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:12:18 -03:00
Paco Cartones
090ae83e12 fix(docker): find the Chrome binary in chrome-linux64 for the codex browser image (#12376)
The playwright:v1.62.0-noble base ships Chromium as a Chrome for Testing build, which extracts to chrome-linux64/chrome. The CMD's find -path '*/chrome-linux/chrome' matched nothing, $chrome_path came out empty, and the container crash-looped on `exec: --headless=new: not found`. Widening the glob to '*/chrome-linux*/chrome' resolves both the legacy and the Chrome for Testing layout.

Validated in a combined worktree with all 25 PRs of this batch boarded together: typecheck:core clean, 443/443 node-runner tests plus 14/14 vitest across every test file the batch touches, and check-changelog-integrity, check:cycles (418 files), check:provider-consistency (272 REGISTRY entries, 355 canonical providers), check:docs-counts, check:docs-sync (42 locales) and check-file-size all green.

Thanks @pacocartones.
2026-09-02 03:12:13 -03:00
Diego Rodrigues de Sa e Souza
6a91002b39 fix(release): drain the 2026-09-02 base-red — rerank-providers import + api-typecheck baseline ratchet (#12414)
* fix(memory): point the rerank-providers dynamic import at the real db module

#11390 landed with a dynamic import of the localDb barrel, which #12052 had
already removed from the base (and which Hard Rule #2 forbids) — the API
Route Typecheck gate reds on the tip with TS2307. getCachedProviderNodes
lives in src/lib/db/readCache.

* chore(quality): ratchet the api-typecheck baseline down (163 stale entries gone)

Regenerated with --update on a faithful npm ci environment (the .113 box)
against the current tip plus the rerank-providers import fix — the gate now
reads OK at 289 pre-existing errors, all baselined. No new entries added.
2026-09-02 02:54:12 -03:00
Armin Anton” ∴
530096a3be feat(providers): add UC (uncensored.com) — persona (un-metered) + direct (metered) (#11513)
Adds uncensored.com as two OpenAI-compatible providers mirroring UC's own surfaces: uc, the persona/subscription side over WebSocket with a durable Clerk credential minting a short-lived per-connect token (no API key, un-metered), as a full multimodal port — chat, tools, vision, doc-RAG, image, video, TTS; and uc-direct, the metered Developer API over REST with X-api-key. Same underlying models, two billing surfaces.

Reconciled on merge. 57 files conflicted; only seven carried UC content, the rest was drift from the older release line and took the tip's side.

- executors/index.ts: the tip has since refactored the executor map to lazy dynamic imports, so uc is registered in that shape. uc-direct needs no entry — it routes through the default OpenAI-compatible executor.
- imageGeneration.ts: the branch still carried the retired designerWeb import alongside ucImage; kept only the UC one.
- config/providers/index.ts, webSessionCredentials.ts and web-cookie.ts resolved additively against the MaxAI entries #11461 put on the tip an hour earlier.
- web-cookie.ts: the uc entry declared no serviceKinds, required since #11392, so provider validation would have thrown at load. Declared ["llm"]. uc-direct already declared it at the end of its own entry — an earlier pass of mine added a second one after id and TypeScript caught the duplicate (TS1117); the author's placement is what shipped.

Every count was measured against the merged tree rather than taken from the branch, and all three would have been wrong: reserved prefixes are 406, not 399; APIKEY_PROVIDERS is 237, not 234; providers are 355. PROVIDER_REFERENCE.md regenerated, the count updated across README/AGENTS.md/llm.txt and its 42 mirrors, package.json and 6 SVGs — every changed line in the protected surfaces is a digit substitution and nothing else, verified by masking digits and comparing the removed and added sets (90 lines each, identical). The executor-map golden snapshot went 134 -> 135.

The branch's file-size-baseline.json predates #12411's ratchet re-tightening and was discarded rather than merged; imageGeneration.ts (+12 for the uc-image format branch) was entered against the current baseline under a _rebaseline annotation, and no other cap moves.

Verified: typecheck:core clean, check:provider-consistency OK (271 REGISTRY entries, 355 canonical providers), check:docs-counts exit 0, check-file-size OK, check:cycles OK, 119/119 across the PR's test files, and 2/2 executor-map-golden.

Thanks @arminanton — two providers for two real billing surfaces, rather than one entry pretending to be both, is the right modelling.
2026-09-02 02:23:33 -03:00
Armin Anton” ∴
cabbbe410a feat(providers): add MaxAI — signed OpenAI-compatible provider (chat, tools, vision, image-gen, doc-RAG) (#11461)
MaxAI joins as a first-class signed provider: 13 chat models discovered live from /models/get_config plus 6 image models, routed through the standard /v1 endpoints with per-request X-Authorization signing, browserless onboarding, prompted tool-calling, vision input, image generation and document RAG.

Reconciled on merge — worth reading, because the branch forked 227 commits back and 77 files conflicted. Only five carried MaxAI content; the rest was drift from the older release line and took the tip's side, taking the diff from 113 files to 37 (then 93 as counted against the current base).

- executors/index.ts: the tip has since refactored the executor map to lazy dynamic imports, so MaxAI is registered in that shape rather than the branch's static import.
- imageRegistry.ts: kept only the maxai block. The branch still carried microsoft-designer-web, which #11754 retired.
- models/route.ts: the conflicting hunk was an unrelated Vertex/Anthropic URL change, not MaxAI — tip's side.
- volcengine agent-plan/coding-plan registries: git auto-merged both sides and produced a duplicated supportsVision key, which TypeScript rejects (TS1117). Removed.

One real integration break that only the combined state shows: the MaxAI entry declared no serviceKinds, which #11392 made required a few hours ago. Provider validation threw at load time and check:provider-consistency crashed outright. Declared ["llm"] — the image kinds derive from imageRegistry, per the convention in that PR's backfill.

Every count was measured rather than taken from the branch, and each would have been wrong: reserved prefixes are 402, not the 397 the branch computed from its stale 395 base; providers are 353, not 354. PROVIDER_REFERENCE.md regenerated, the count updated across README/AGENTS.md/llm.txt and its 42 mirrors, package.json and 6 SVGs — every changed line in those files is a digit substitution and nothing else, verified by masking digits and comparing the removed and added sets (90 lines, identical). The executor-map golden snapshot was regenerated: keyCount 133 -> 134.

The branch's file-size-baseline.json predates #12411's ratchet re-tightening, so it was discarded rather than merged — taking it would have silently undone that. The three files this PR grows (proxyFetch.ts +20 for the Windows/firefox_150 TLS profile, imageGeneration.ts +12, models/route.ts +48) were entered against the current baseline under one _rebaseline annotation; no other cap moves.

Verified: typecheck:core clean, check:provider-consistency OK (269 REGISTRY entries, 353 canonical providers), check:docs-counts exit 0, check-file-size OK, check:cycles OK, and 79/79 across the MaxAI suites plus 21/21 reserved-prefix and 2/2 executor-map-golden.

Thanks @arminanton — the provider work itself is thorough; it was the 227 commits of base that needed the attention.
2026-09-02 01:55:42 -03:00
Diego Rodrigues de Sa e Souza
382e2e85d2 chore(quality): re-tighten the file-size ratchet to the real LOC (plan 3.8.52 task 0) (#12411)
The +30% loosening of 2026-08-10 (fbbef4eaaf) left this gate inert: combo.ts carried a 5,691-line cap against 4,023 real lines and chatCore.ts 7,895 against 5,946. Both god-files grew roughly 600 lines in two weeks without the gate ever firing.

Mechanical check:file-size --update against the tip. No source touched. combo.ts 5,691 -> 4,023, chatCore.ts 7,895 -> 5,946, frozen source entries 178 -> 135 (43 already fit the 1,200 cap), frozen test entries 49 -> 39. From here every 3.8.52 decomposition slice lowers the cap again.

Reconciled on merge, and worth recording because neither PR could see it alone: #11460 (flat-rate cost estimates) landed first and grew CostOverviewTab.tsx from 1,282 to 1,319 lines. This PR had frozen that entry at 1,283 — measured before #11460 existed — so the two together would have turned the tip red while each was green on its own. --update correctly refuses to raise a cap, so the entry was set to the real post-merge LOC with a _rebaseline_2026_09_02_11460_flat_rate_estimates annotation naming #11460 as the growth, following the own-growth precedent already in the file (_rebaseline_2026_08_20_10531_freebuff_provider).

The ratchet invariant is intact and was checked rather than assumed: across the whole baseline, 45 caps decrease and 0 increase; CostOverviewTab.tsx still falls 2,002 -> 1,319.

Verified: check-file-size OK (135 frozen source entries, 4,481 files checked; 39 frozen test entries, 5,338 checked), and prettier clean on the baseline.
2026-09-02 01:23:11 -03:00
Diego Rodrigues de Sa e Souza
6b4519c317 feat(dashboard): orchestration canvas fase 2 — agents WS channel (2.1) (#12409)
* feat(dashboard): agents WS channel + agent.task.updated event

* feat(a2a): publish agent.task.updated on cloud-agent and a2a task writes

* feat(dashboard): mirror conductor fleet transitions into agents channel

* feat(dashboard): orchestration snapshot rides the agents WS channel (2.1)

---------

Co-authored-by: Markus Hartung <diegosouzapw@users.noreply.github.com>
2026-09-02 01:19:49 -03:00
小妍儿 ✨
afb91a83bd fix(analytics): expose flat-rate estimates on cost dashboards (#11460)
Claude Code (claude / cc) is correctly classified as a flat-rate subscription, so the analytics API reports $0 — accurate as billed cost, and useless as a view of what the subscription actually consumed. Neither the Costs nor the Analytics dashboard had a token-price-equivalent view.

The fix keeps both meanings rather than picking one: ordinary analytics callers keep billed-cost semantics ($0 for flat-rate), /dashboard/costs and /dashboard/analytics opt in explicitly via includeFlatRateEstimates=true, the response reports whether estimates were included so a caller cannot mistake them for vendor billing records, and the figures on /dashboard/costs are labelled as flat-rate estimates rather than presented as spend. Omitted, false and unknown values all retain the existing behaviour.

Scope note carried from the description: this is a checkpoint on #11459, not its full closure — the issue stays open.

Verified in a combined worktree with three sibling PRs of this batch: typecheck:core clean, 134/134 focused tests (4 skipped), and i18n UI coverage PASS across all 42 locales for the 43-file locale pass.

One cross-PR interaction worth recording, since it is invisible from either side: this grows CostOverviewTab.tsx from 1282 to 1318 lines, which is fine against the tip's current 2002 cap but exceeds the 1283 that #12411 (file-size ratchet re-tightening) would freeze. Neither PR fails alone. Merged first on purpose so #12411's mechanical --update recomputes against the real post-merge LOC — the cap still only goes down.

Thanks @xiaoyaner0201 — the opt-in contract plus the "were estimates included" flag is the right shape for this.
2026-09-02 01:18:47 -03:00
Diego Rodrigues de Sa e Souza
c1ac943c70 refactor(video): unify the JPEG frame data-URI contract (#12322)
The contact sheet, the dedup comparator and the drill-down each validated JPEG data-URIs independently. They now share src/lib/guardrails/videoBridgeFrameContract.ts. No behaviour change; the sibling tests that asserted a per-module message were aligned to the shared one. Closes the Standards-4 residue from the 2026-08-18 Video Bridge review.

Verified in a combined worktree with three sibling PRs of this batch: typecheck:core clean, 134/134 focused tests (4 skipped), i18n UI coverage PASS across all 42 locales.
2026-09-02 01:18:03 -03:00
Diego Rodrigues de Sa e Souza
e26a649d26 perf(ci): cache node_modules in the npm-ci-retry composite (#8084 D3) (#12408)
Every job installs through this composite — 36 times per ci.yml run, 8 per
quality.yml run — and each call paid ~80-90 s of npm ci even with setup-node's
npm tarball cache warm (measured 2026-09-01: 3,327 runner-seconds per ci.yml run
just installing). A node_modules cache keyed on runner.os + runner.arch + the
resolved Node version + hashFiles(package-lock.json, .npmrc, postinstall.mjs and
its five helpers) lets an exact hit skip the install entirely.

- No restore-keys, same rule as the ESLint cache (#11600): exact key or a full
  npm ci, never a partial tree from another lockfile / Node / postinstall.
- The retry loop is unchanged and remains the miss path; --no-audit --no-fund
  because audit:deps is its own gate.
- cache input (default true) lets a caller opt out.
- actions/cache pinned to the v6.1.0 hash already used in nightly-mutation.yml
  (zizmor unpinned-uses blanket policy).
- tests/unit/build/npm-ci-retry-composite.test.ts pins the key contents, the
  no-restore-keys rule and the miss path.

Refs #8084
2026-09-02 01:16:14 -03:00
Diego Rodrigues de Sa e Souza
713440be0a revert(ui): point CTAs back at their real destinations (#12410)
The link.omniroute.online shortener no longer resolves -- every slug
answers 404 -- after the domain moved to omniskill.online. Three dashboard
CTAs went through it, so all three were dead links:

  cheaper -> https://cheaperinference.com/?utm_source=omniroute
  vsx     -> https://marketplace.visualstudio.com/items?itemName=diegosouzapw.omnicopilot
  adapta  -> https://agent.adapta.one/agentic-chat

The two Vitest files pinned the short URLs as literals, so they are
updated in the same commit and still assert the exact href.

Click metrics are lost until a shortener exists on the new domain; a live
CTA is worth more than a tracked dead one.
2026-09-02 00:50:04 -03:00
Tushar Agarwal
a298dc6b73 feat(check): make serviceKinds required and add the reverse-walk provider consistency gate (#11392)
serviceKinds now drops .optional() in providerSchema.ts, and check-provider-consistency gains the reverse walk: a canonical provider whose serviceKinds include "llm" must have a REGISTRY entry unless it is in the new KNOWN_CATALOG_ONLY allowlist (providers routed through a connection baseUrl or a specialised executor). That turns "catalog entry outlived its registry entry" — the half-finished provider:remove — into a checkable invariant instead of something a reviewer has to notice.

Reconciled on merge, and worth reading before comparing diffs. The branch's 18 files had landed at the repository ROOT: git diff --name-status showed A gateways.ts, A providerSchema.ts, A check-provider-consistency.test.ts, A backfill-servicekinds.mjs with no directory component. The real provider files, schema, gate and test were never touched, so the +5093/-0 diff was root files AGENTS.md forbids (a test outside tests/, a script outside scripts/) and a no-op for the feature. The content was also 227 commits stale — the root gateways.ts was missing oneminai, among 267 divergent lines.

So each file's actual delta was reapplied onto the current tip rather than copied: the schema one-liner; the gate's KNOWN_CATALOG_ONLY, findCatalogOnlyLlmProviders(), the main() check and the summary line (the branch's copy also repeated the file header and imports at the end — 12 lines of residue from the same accident, dropped); the test's import block and five reverse-walk cases; and backfill-servicekinds.mjs placed at scripts/ad-hoc/, the path its own docstring names, then run against the current catalog: 315 insertions, 352/352 entries declaring serviceKinds, idempotent on a second run.

Two entries the mechanical pass could not get right, both surfaced by doing it against the live tree:

- github in oauth.ts is a single-line object, so the script's id:-per-line regex skipped it — the one failure it reported. Declared ["llm"] by hand, which is what the script's own rule computes.
- magnific came out as ["llm"] but is an image provider (icon: "image", registered in imageRegistry.ts). It is freepik renamed by migration 160, and freepik is in the script's NO_LLM set, so the rename left that set no longer matching. Your reverse walk caught it on its first run — a fair demonstration of why the gate is worth having. Corrected to [], with magnific added to NO_LLM and a note so a re-run cannot reintroduce it.

Verified: check:provider-consistency OK (268 REGISTRY entries, 352 canonical providers, 0 registry-only exceptions, 32 catalog-only), typecheck:core clean, 137/137 across the provider/schema/serviceKinds suites, check-file-size and check:cycles green.

Thanks @Tushar49 — the design is sound and the backfill script did the heavy lifting; only its placement and freshness needed fixing.
2026-09-02 00:32:53 -03:00
Rouzbeh†
451dd73870 fix(memory): list and serve embedding/rerank models from every configured provider (#11390)
On dashboard/memory?tab=engine the Embedding Model quick-select (and the rerank selector) built their lists from a keyword heuristic over the CHAT catalog (AI_MODELS) plus OpenRouter live discovery. Providers whose embedding models are not in that catalog never appeared — mistral, gemini, nvidia nim, groq, vercel-ai-gateway and others that serve embeddings on a standard OpenAI-compatible /embeddings endpoint — and typing such a model by hand failed at runtime with "Unknown embedding provider".

The fix is one generic mechanism rather than a list of per-provider patches: deriveEmbeddingProviderForChatProvider() turns any chat-registry entry with a /chat/completions base into an OpenAI-compatible /embeddings config, with curated EMBEDDING_PROVIDERS entries always winning; the embeddings service resolves a derived config for unknown-but-configured providers instead of rejecting them; deriveRerankProviderForChatProvider() does the same for Cohere-compatible /rerank; and both memory selectors fall back to a free-text provider/model input when no static catalog exists. No provider is special-cased by name, so adding one to the chat registry now makes it embedding- and rerank-capable here automatically.

Verified on the current release tip: merged clean, typecheck:core clean, check:cycles OK across 417 files, and 35/35 across the PR's five new suites (qdrant-quick-select-catalog, memory-provider-listings, rerank-provider-listings, embedding-generic-provider-fallback, rerank-generic-provider-fallback) plus the updated hard-session-lease-bypass-inventory and embeddings-handler.

Note: the base-red disclaimer in the description referenced #9985 against release/v3.8.50 — that window is closed and the current tip carries no open base-red, so nothing was inherited here.

Thanks @rqzbeh — deriving the capability instead of enumerating providers is the version of this that stays correct as the registry grows.
2026-09-02 00:27:29 -03:00
Nguyen Thanh Dat
9327990be6 fix(memory): measure the embedding width instead of waiting for a probe (#12180)
* fix(memory): measure the embedding width instead of waiting for a probe

resolveEmbeddingSource() reports dimensions: null for any source the
hard-coded registry does not describe, and a self-hosted endpoint is by
definition absent from it. Both write paths then deadlocked on that null:

- scheduleVectorUpsert called ensureReady() with the null resolution, which
  declines to create vec_memories, and then ignored the {ready:false} answer
  and upserted anyway -- straight into the catch, so every memory was stored,
  marked needs_reindex, and never vectorized;
- reindexPending refused to embed until the width was known, and the width
  could only ever come from an embedding.

Nothing surfaced it: POST /api/memory returned 200 and the health check
stayed green while rowCount stayed at 0.

The comment on EmbeddingResolution.dimensions already calls this a lazy
probe; nobody performed the probe. The upsert path holds a finished vector
when it calls ensureReady, so measure it there, and let reindex spend one
embedding up front to measure -- reusing that vector rather than paying for
it twice. withMeasuredDimensions rebuilds the signature the same way the
resolution did, identity first, so two endpoints serving the same model id
still reindex independently.

scheduleVectorUpsert now also honours a {ready:false} answer instead of
upserting into a table that is not there.

Fixes #12154

* chore(changelog): point the fragment at the real PR number

* fix(memory): extract reindex helpers so the complexity ratchet stays green

runReindexBatch grew past max-lines-per-function and cognitive-complexity
when the lazy-probe path landed. Split measure/ready/item helpers without
changing the #12154 behavior.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-09-02 00:12:22 -03:00
Chewji
af0a9609f4 feat(sse): support native max reasoning effort and per-model clamping (#11875)
* fix(sse): map normalized xhigh to max for GLM-5.x+, DeepSeek-V4+, and provider aliases

* feat(sse): support native max reasoning effort and per-model clamping

* test(sse): add unit tests for Qwen 3.8, Claude 4.7+, GPT-5.6, and 2026 reasoning models

* fix(sse): align tests and file-size split for native max effort

Keep `max` as a first-class canonical tier. Split the new sanitizer
coverage out of base-executor-sanitize-effort.test.ts so the file stays
under testCap, and update discovery/catalog/vscode assertions to expect
native max instead of the old xhigh alias.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* fix(sse): keep combo effort lists and drop unused collectSSE helper

Combo vscode routes still advertise the 5-tier list. Canonical `max` is
preserved in discovery (#9160) and github model metadata. Remove the
unused collectSSE helper that failed the absolute ESLint gate.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Chewji <Chewji9875@users.noreply.github.com>
2026-09-02 00:12:13 -03:00
WebPerson
24b784e9bb [Performance] Enable React Compiler for automatic memoization (#11783)
* feat(ui): enable React Compiler (#67)

Enable reactCompiler: true in next.config.mjs (Next 16 + React 19.2.8).
This automates memoization at build time, removing manual useCallback/useMemo
debt (591 + 283 instances respectively) and preventing stale-closure bugs.

Test results (pre-existing failures unchanged):
  vitest UI: 282/295 files pass (13 fail = missing router/ReactFlow mocks)
  vitest:    1805/1857 tests pass (52 fail = same pre-existing mock issues)
  node:test: api/services/db all pass (except platform-specific
             serviceSupervisorSpawnError — Windows spawn("ls") issue)

No new failures introduced by the compiler transform.
Optional cleanup: remove now-redundant useCallback/useMemo in hot components.

* fix(build): add babel-plugin-react-compiler peer dependency (#67)

React Compiler (reactCompiler: true in next.config.mjs) requires
babel-plugin-react-compiler as an explicit peer dependency — Next.js
declares it as optional ("*") and does not auto-install it.

Installed babel-plugin-react-compiler@1.0.0 as a devDependency.
Resolves correctly from both the project root and the next package
context (Turbopack resolution path).

* fix(ci): allowlist babel-plugin-react-compiler for React Compiler

The React Compiler peer is a real npm package (facebook/react, MIT) required
by Next 16 `reactCompiler: true`. Adding it to the anti-slopsquat allowlist
unblocks check:deps and the 6A.8 unit-test gate.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* fix(ci): drop unused collectSSE helper that trips ESLint

The helper was leftover from #12151 and fails the absolute
lint:json --max-warnings 0 gate on every PR that includes it.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: WebPerson <jonlwheat2-gif@users.noreply.github.com>
2026-09-02 00:10:59 -03:00
ragnar-claude
96824288f5 feat(compression): make proactive context-compression threshold a live setting (#11564)
* feat(compression): make proactive context-compression threshold a live setting

The proactive compression trigger ratio was a hardcoded COMPRESSION_THRESHOLD =
0.7 in chatCore. Operators could not move compression relative to a client's own
compaction point (e.g. Codex Desktop self-compacts at ~0.85 of its window, so
the 0.7 proxy threshold always preempts the client's compaction with the
proxy's lossier one — see #8932 for what that produced before 3.8.50).

New: key_value namespace 'compression', key 'proactiveConfig',
{"thresholdRatio": 0.7}. Clamped [0.1, 0.99], 30s TTL cache, ipFilter
persistence pattern (#6131), synchronous read stays in the hot path. Default
unchanged; missing/invalid rows fall back to 0.7.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* test(compression): cover the live proactive-compression threshold (read, validity bounds, fallback, TTL)

Locks in getProactiveCompressionRatio() (src/lib/db/compression.ts), the
key_value-backed replacement for chatCore's hardcoded 0.7:

  - shipped default 0.7 when no compression/proactiveConfig row exists
  - 30s TTL cache: a fresh DB write stays invisible until the TTL lapses
    (clock mocked via node:test mock timers, Date API — the module keeps
    its cache private with no reset hook)
  - valid override read from key_value, boundary values 0.1/0.99 included
  - out-of-range ratios fall back to the DEFAULT (a validity window, not
    clamping to the nearest bound — matching the shipped comment)
  - broken JSON / non-numeric thresholdRatio: 0.7, without throwing

Guard verified by mutation: switching the window to clamping fails the
out-of-range case.

---------

Co-authored-by: root-cli (Hermes ops) <info@livewellwith.us>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-09-02 00:02:45 -03:00
Deftera
678e6077e4 fix(kiro): do not permanently ban on 'User is not authorized to make this call' (#11809)
* fix(kiro): do not permanently ban on 'User is not authorized to make this call'

* test(kiro): regression cover the 403 'User is not authorized' non-ban classification

---------

Co-authored-by: Deftera186 <Deftera186@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-09-02 00:02:31 -03:00
Mr White
5a0a131bc7 feat(usage): devin-cli agentic quota + openrouter credits in Provider Limits (#12256)
* feat(usage): devin-cli agentic quota + openrouter credits in Provider Limits

Two provider families with live quota APIs were missing from the Provider
Limits dashboard because their list entries were absent:

- devin-cli: new usage leaf querying the Codeium seat-management Connect API
  (exa.seat_management_pb.SeatManagementService/GetUserStatus, protobuf over
  POST with the raw `Basic <token>-<token>` auth header the CLI itself uses).
  Surfaces the plan name plus daily/weekly agentic quota percentages with
  reset timestamps from the GetUserStatus plan_status payload, via a minimal
  hand-rolled protobuf encoder/reader (no proto dependency warranted for two
  fixed messages).
- openrouter: the /key + /credits quota fetcher (#6842) was already wired
  into the dispatcher but gated out of the bulk sync — add it to
  USAGE_SUPPORTED_PROVIDERS and PROVIDER_LIMITS_APIKEY_PROVIDERS so key
  limits and account credits actually surface.

* fix(build): externalize tiktoken so tiktoken_bg.wasm resolves at runtime

The vendored ChatGPT Web connector v4.0.7 (#12181) imports tiktoken
(get_encoding) at module level. tiktoken's node build reads
tiktoken_bg.wasm via a __dirname-relative fs.readFileSync during import;
when Next bundles the package the wasm asset is not traced into the server
chunk, and page-data collection for every route reaching the tokenizer
(e.g. /api/providers/[id]/chatgpt-web-codex-doctor) aborts with
"Missing tiktoken_bg.wasm" — breaking the whole standalone build.

Externalize it like the other runtime-resolved native/wasm packages
(sql.js, sqlite-vec, better-sqlite3): the require stays at runtime, where
node_modules/tiktoken/tiktoken_bg.wasm resolves normally.

* fix(openrouter): /credits balance survives a /key failure

OpenRouter is credit-based, not subscription-based: the authoritative
remaining-credits signal is GET /api/v1/credits (total_credits -
total_usage, the documented "get remaining credits" endpoint), while the
/key limit fields are optional per-key caps that most accounts never set.

fetchOpenrouterQuota previously treated /key as mandatory — any /key
failure (429 rate limit, transient error, unexpected shape) discarded the
whole payload and the Usage dashboard showed "OpenRouter (usage endpoint
unreachable)" even though /credits was reachable. Now:

- /key unavailable + /credits OK → credits-only quota (creditBalance =
  total_credits - total_usage) instead of null
- /key 401/403 alone no longer means an invalid token; only a double
  auth-rejection (both endpoints) does
- null is returned only when both endpoints fail, and the dashboard label
  reflects that ("credits endpoint unreachable")

* fix(openrouter): render AI Credits as a USD credit count in Provider Limits

The Provider Limits card's dollar renderer only activates on
isCredits/creditCount rows (QuotaCardExpanded), but openrouter went through
parseGeneric — which drops `currency` and never sets those flags — so the
credits balance rendered as a meaningless "100% left" (the unlimited-credits
row is always 100%) instead of the actual credit count.

Route openrouter's `credits` quota through buildCreditsQuota() like the
DeepSeek/AgentRouter credits rows: label "AI Credits", dollar-formatted
balance. Free-tier request windows keep the generic percentage treatment.

* fix(usage): document DEVIN_SEAT_API_URL and split quota parsers

Keep fetchOpenrouterQuota and decodeProtoFields under the complexity
ratchets, and add the seat-management URL to the env/docs contract.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* test(usage): drop duplicated GLM quota-ordering test in provider-limits-ui

* test(usage): drop stale openrouter ACCEPTED_DIVERGENCE

OpenRouter is now in both USAGE_FETCHER_PROVIDERS and
USAGE_SUPPORTED_PROVIDERS, so the recorded aggregator divergence
is no longer real. Add the changelog fragment.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-09-02 00:02:15 -03:00
Andrew B.
c702a27eda perf(compression): OOM mitigations for large payload hashing, memoization, and token estimation (#7847) (#11844)
* perf(compression): memory and OOM mitigations for large payload hashing and token estimation

* fix(compression): implement getMemoStats observability for result memo (#7847)

Adds the missing memo observability layer referenced by
tests/unit/compression/oom-memo-memory.test.ts and the monitoring API:

- resultMemo.ts: lifetime hit/miss counters + bounded time-ordered ring
  buffer (10k entries, ~90KB) powering 1m/5m/15m/1h hit-rate windows;
  getMemoStats() reports size/capacity/hits/misses/hitRate + windows.
- memoLookup() tags served results with stats.memoHit = true.
- clearMemoStore() also resets counters and the ring.
- compression/index.ts re-exports getMemoStats for the monitoring route.
- types.ts: optional memoHit field on CompressionStats.
- New GET /api/monitoring/compression route exposing the stats snapshot
  (lightweight, no DB) for operators to track cache-hit efficiency.

* fix(compression): align memo contract with upstream #11727 — return caller object, reset lookup counter in clearMemoStore

* fix(compression): restore unwrapEventEnvelope in stream payload collector summaries

The OOM-mitigation commit accidentally replaced unwrapEventEnvelope(evt.data)
with asRecord(evt.data) in the summary builders and live push, breaking
translate-mode {event, data} envelope unwrapping (clientPayload type detection)
and failing 2 stream-payload-collector tests. Restored upstream semantics;
kept the jsonLength OOM optimization as the only delta in this file.

* refactor(compression): break down writeValue and writeEncodedString to pass complexity ratchets

Refactors jsonSha256 internal helpers (writeValue, writeEncodedString)
into small, single-responsibility sub-functions under the complexity
threshold (max cyclomatic 15, max cognitive 15). Preserves exact
JSON.stringify parity, circular reference guards on both arrays and
plain objects, and escape behavior (all 530 relevant tests pass).

* test(compression): make oom-memo heap assertion robust without expose-gc

The CI unit-test shard runner does not pass --expose-gc, so global.gc is
undefined and heapUsed can still momentarily hold GC-pending transients
(observed 53.4 MiB after a 3MiB body). Gate the retained-heap assertion
on forced collection being available (3 forced cycles for array buffers)
instead of skipping it silently, and keep it fully active when
--expose-gc is present.

* fix(compression): restore worker-pool offload path in runCompressionAsync

The OOM-mitigation refactor dropped the isCompressionWorkerEligible /
runCompressionInWorker dispatch at the top of runCompressionAsync, silently
removing the base's worker-thread offload for eligible large payloads.
Restore the block exactly as on release/v3.8.51, ahead of the result-memo
path, keeping the memoization and hashing improvements intact.

* docs(api): document GET /api/monitoring/compression and log route errors via pino

Add the new monitoring endpoint to docs/openapi.yaml following the
neighboring System entries, and replace the route's console.error with
the repo-standard pino logger.

* fix(skills): regenerate omni-resilience and add changelog fragment

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Andrian Balanescu <AndrianBalanescu@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-09-02 00:01:59 -03:00
Jacob Stoner
cf53b9220f feat(combos): add universal handoff feature flag (#12167)
* feat(combos): add universal handoff feature flag

Add a default-enabled runtime flag that lets operators disable universal context handoffs globally without changing existing combo configuration or requiring a restart.

* fix(i18n): seed the universal-handoff flag description key across locales

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-09-02 00:01:42 -03:00
Diego Rodrigues de Sa e Souza
d2a027a156 feat(dashboard): orchestration canvas fase 2 — quick wins + hardening (2.3/2.4/2.8/2.11/2.12, #12270, #12271) (#12393)
* feat(dashboard): orchestration pure snapshot filter (search + chips)

* feat(dashboard): orchestration collapse-by-source in flow projection

* refactor(dashboard): orchestration model polish (#12271 model items)

* feat(dashboard): theme-aware orchestration status tokens (2.12)

* feat(dashboard): particle StatusEdge for orchestration canvas (2.11)

* feat(dashboard): orchestration search/filter chips + collapse in URL (2.3+2.4)

* feat(dashboard): drawer trace copy + error/a11y hardening (2.8, #12270)

* chore(dashboard): orchestration UI hardening (#12270)

* fix(dashboard): type-safe source read in AgentsTab collapse handler

* fix(dashboard): pass staleSince into the sourceStale message

* test(dashboard): orchestration missing coverage + fase2 i18n (#12271)

* refactor(dashboard): split orchestration page/toolbar/drawer helpers under complexity ratchet

---------

Co-authored-by: Markus Hartung <diegosouzapw@users.noreply.github.com>
2026-09-01 23:13:47 -03:00
Diego Rodrigues de Sa e Souza
17a53d2eb9 feat(quality): complete test:scoped — --full map rebuild, stdin selection, CI loader parity (#8084 D1) (#12353)
- test:scoped:full (documented in the script header since #9143 but never wired) rebuilds
  config/quality/test-impact-map.json and then selects.
- select-impacted-tests.mjs gains --stdin so --staged selects from the index; the git-diff
  path only ever saw commits, so staged-only runs silently fell back to the heuristic.
- Loader parity with npm run test:unit / quality.yml TIA step (#6787): tests/unit/dashboard/**
  under --import tsx (CJS transform), tests/unit/serial/** at --test-concurrency=1, the rest
  under tsx/esm. The single tsx/esm invocation false-redded every dashboard test the map
  selected ("Unexpected token 'export'").
- CONTRIBUTING.md → Running Tests documents the three modes and the fail-safe exit 1.

Refs #8084
2026-09-01 23:01:40 -03:00
Diego Rodrigues de Sa e Souza
7f25d67d07 feat(radar): explain access rules before opt-in (#12342)
* feat(radar): explain access rules before opt-in

* docs(radar): pin D32 evidence boundary

* chore(changelog): number Radar D32 fragment

* fix(radar): clarify single-use account scope

* fix(radar): use a reliable activation icon

* fix(radar): complete Vietnamese D32 copy

* fix(radar): mark stale D32 locale copy
2026-09-01 20:20:50 -03:00
Diego Rodrigues de Sa e Souza
1586476183 fix(release): drain the 2026-09-01 base-red window — passthrough usage regression + radarPage i18n keys (#12327)
* fix(sse): forward the upstream's real trailing usage in passthrough; estimate only at flush

#12151 injected estimated usage into the finish chunk and dropped the real
trailing usage block that genuine OpenAI upstreams send afterwards — metered
clients got estimates instead of real token counts. The estimate now leaves
via a canonical usage-only chunk at flush, only when the upstream stayed
silent; a real trailing block is forwarded verbatim and wins. The tool_calls
finish_reason normalization now materializes its own rewrite (it piggybacked
on the removed finish-time rewrite), and the dead collectSSE helper goes with
it (subsumes #12324).

* fix(i18n): seed the radarPage limits/training keys the #12320 UI already consumes

RadarCatalogTable.tsx references radarPage.colLimits / trainsOnPrompts /
trainsOnPromptsHelp but #12320 never added them to en.json, so the EN
fallback could not resolve the __MISSING__ markers across 42 locales.
Real translations for pt-BR and vi; the rest resolve via the EN fallback.

* fix(sse): carry the chat stream id into flush-time synthetic chunks

The estimated usage-only chunk emitted at flush used passthroughResponsesId,
which is only ever set on the Responses path — on the chat path the synthetic
chunk shipped id: null, breaking the string-id invariant pinned by
stream-numeric-ids.test.ts. Track the upstream chat-completion id in the
passthrough loop and reuse it (falling back to the Responses id, then a
generated one). Sibling sweep: 74 files importing utils/stream — 603/603.
2026-09-01 16:17:48 -03:00
Dizzle
c9f9b6274e feat(providers): expose usage-supported in provider plugin manifest (#12214)
The provider plugin manifest already exposed usage-fetch (40 providers, #11903); this publishes the second capability, usage-supported, so integrators can tell without reading TypeScript whether the server usage routes accept a provider. #11903 closed #11722 after shipping only half of it and said so at the time — this is the follow-up it promised.

The two scopes genuinely differ and the docs now say how: usage-fetch resolves on id or alias (the dispatcher accepts both), usage-supported on id alone, because the runtime guard does a plain USAGE_SUPPORTED_PROVIDERS.includes(providerId) with no alias resolution. 42 providers carry both tags, 4 carry only usage-fetch (opencode, opencode-zen, openrouter, xai) and 3 only usage-supported (adobe-firefly, firefly, xiaomi-mimo-token-plan) — 7 measured differences, so neither tag implies the other. No list mutation, no new route, schemaVersion stays 1.

USAGE_SUPPORTED_PROVIDERS moved out of src/shared/constants/providers.ts into an import-free leaf at open-sse/services/usage/supportedProviders.ts, keeping the manifest's import graph light — the same move fetcherProviders.ts got in #11903, landed on the correct side of the workspace boundary.

Base note: the branch forked 46 commits before kilocode joined the list, so a wholesale take of its providers.ts would have silently dropped that id. Verified against the current release tip before merging — both sides hold the same 46 ids, nothing lost.

Verified on the current tip: typecheck:core clean, check:cycles OK across 417 files (the import-free-leaf claim holds), and 63/63 focused tests across provider-plugin-manifest, usage-fetcher-registration-coverage, adobe-firefly and agentrouter-quota-dashboard-rendering.

Thanks @maxmad64bis — and for finishing the half of #11722 that was left open rather than letting it sit.
2026-09-01 16:02:46 -03:00
557 changed files with 28329 additions and 3588 deletions

View File

@@ -240,7 +240,7 @@ PORT=20128
# Used by: src/app/api/v1/relay/chat/completions/route.ts
# RELAY_IP_PER_MINUTE=30
# Bundler selection for `npm run dev`. Set to 0 to fall back to webpack.
# Bundler selection for `npm run dev` and `npm run build`. Set to 0 to fall back to webpack.
# Default is 1 (Turbopack). PR #4092 had forced webpack because earlier
# Turbopack 16.2.x panicked on the OmniRoute module graph with "internal error:
# entered unreachable code: there must be a path to a root"
@@ -250,8 +250,9 @@ PORT=20128
# /api/v1/models, /api/mcp) and repeated HMR rebuilds: zero panics. Turbopack
# also keeps dev memory far lower on the edit→rebuild loop (HMR rebuild RSS stays
# ~flat vs webpack's monotonic growth), which mitigates the dev-server OOM on
# this 60+ route app. The production build still uses webpack (build pipeline is
# unaffected by this dev-only flag).
# this 60+ route app. The production build (scripts/build/build-next-isolated.mjs)
# reads the same flag: Turbopack by default, 0 builds with webpack (`npm run
# build:contributor` sets it for you).
OMNIROUTE_USE_TURBOPACK=1
# Disable systemd sd_notify (Type=notify / WatchdogSec=) even when running
@@ -1151,11 +1152,6 @@ CODEX_OAUTH_CLIENT_ID=app_EMoamEEZ73f0CkXaXp7hrann
# Trae OAuth token override. Used by: open-sse/executors/trae.ts.
# TRAE_TOKEN=
# ── The Old LLM (theoldllm) ──
# Playwright navigation timeout (ms) for the browser-backed token capture.
# Used by: open-sse/executors/theoldllm.ts. Default: 30000 (30s).
# THEOLDLLM_NAV_TIMEOUT_MS=30000
# ── Gemini / Antigravity (Google-based) ──
# These providers ship public OAuth client_id/secret values embedded in their
# public CLIs. Defaults are baked into the code via
@@ -1829,7 +1825,7 @@ APP_LOG_TO_FILE=true
# short alias prefix and the canonical provider prefix for each model (cc/claude-sonnet-4-6
# AND claude/claude-sonnet-4-6) so client configs that hardcoded either form keep working —
# which roughly doubles the catalog. "alias" emits one id per model; "canonical" emits only
# the full provider-id prefix (and drops providers whose alias is already canonical).
# the full provider-id prefix (providers whose alias is already canonical keep their one id).
# A client can override per request with GET /v1/models?prefix=alias instead.
# Also configurable from Dashboard > Settings > Feature Flags.
# Used by: src/shared/constants/featureFlagDefinitions.ts, src/app/api/v1/models/catalog.ts
@@ -2267,6 +2263,16 @@ APP_LOG_TO_FILE=true
# Cursor image-generation wall clock (ms). Default: 210000.
# CURSOR_IMG_TIMEOUT_MS=210000
# UC (uncensored.com) image-generation result-poll cadence + wall clock (ms).
# Used by: open-sse/handlers/imageGeneration/providers/ucImage.ts. Defaults: 2000 / 60000.
# UC_IMAGE_POLL_INTERVAL_MS=2000
# UC_IMAGE_POLL_TIMEOUT_MS=60000
# UC (uncensored.com) video-generation result-poll cadence + wall clock (ms).
# Used by: open-sse/handlers/videoGeneration/providers/ucVideo.ts. Defaults: 3000 / 300000.
# UC_VIDEO_POLL_INTERVAL_MS=3000
# UC_VIDEO_POLL_TIMEOUT_MS=300000
# Shared-seat concurrency gate for Cursor image jobs. Default: 2.
# CURSOR_IMG_MAX_CONCURRENT=2
@@ -2398,6 +2404,9 @@ APP_LOG_TO_FILE=true
# Bundled Codeium/language-server extension_version, distinct from Desktop.
# Must use x.y.z format; invalid/unset values use the bundled default 1.48.2.
# DEVIN_DESKTOP_EXTENSION_VERSION=1.48.2
# Optional override for the Codeium seat-management API used by Devin CLI quota.
# Used by: open-sse/services/usage/devinCli.ts. Default: https://server.codeium.com
# DEVIN_SEAT_API_URL=https://server.codeium.com
# ── Command Code (custom CLI) callback ──
# Local port used for OAuth-style callbacks from the Command Code CLI helper.

View File

@@ -1,9 +1,45 @@
name: npm ci with retry
description: Run npm ci with retries for transient registry/network failures.
description: >-
Install dependencies. Restores node_modules from the Actions cache when the exact
lockfile / runner / Node version / postinstall inputs match; otherwise runs npm ci
with retries for transient registry/network failures and saves the tree for the
next run.
inputs:
cache:
description: Set to "false" to skip the node_modules cache and always run npm ci.
required: false
default: "true"
runs:
using: composite
steps:
- shell: bash
- name: Resolve Node version for the cache key
id: node
shell: bash
run: echo "version=$(node --version)" >> "$GITHUB_OUTPUT"
# #8084 D3 (plan 3.8.51 task 5): every job used to pay ~80-90 s of `npm ci` even
# with setup-node's npm tarball cache warm — 36 jobs per ci.yml run, ~55 min of
# runner time per run just installing. A node_modules cache keyed on EVERYTHING
# that shapes the tree lets a hit skip the install entirely.
#
# No restore-keys on purpose (same rule as the ESLint cache, #11600): a partial
# tree from another lockfile / Node / postinstall script is exactly the kind of
# silent drift a lockfile-pinned CI must never inherit. Exact key or a full npm ci.
#
# postinstall (scripts/build/postinstall.mjs + helpers) only mutates node_modules
# on a plain install — its dist/ branch is gated on dist/ existing, which never
# holds at install time in CI — so the cached tree already carries its effects.
- name: Restore node_modules
id: node-modules
if: inputs.cache == 'true'
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: node_modules
key: node-modules-${{ runner.os }}-${{ runner.arch }}-${{ steps.node.outputs.version }}-${{ hashFiles('package-lock.json', '.npmrc', 'scripts/build/postinstall.mjs', 'scripts/build/postinstallSupport.mjs', 'scripts/build/colocateOptionals.mjs', 'scripts/build/fixTlsClientNodeBinary.mjs', 'scripts/build/fixPlaywrightAndroid.mjs', 'scripts/build/native-binary-compat.mjs') }}
- name: npm ci (with retry)
if: steps.node-modules.outputs.cache-hit != 'true'
shell: bash
run: |
set -euo pipefail
@@ -15,7 +51,8 @@ runs:
echo "npm ci attempt $attempt/$max_attempts after transient failure"
fi
if npm ci; then
# --no-audit: `audit:deps` is its own gate; the inline audit only adds latency.
if npm ci --no-audit --no-fund; then
exit 0
fi
@@ -27,3 +64,8 @@ runs:
sleep "$delay_seconds"
delay_seconds=$((delay_seconds * 2))
done
- name: node_modules restored from cache
if: steps.node-modules.outputs.cache-hit == 'true'
shell: bash
run: echo "node_modules restored from cache (key hit) — npm ci skipped"

View File

@@ -3477,7 +3477,7 @@ export function createOmniRouteProviderHook(
// ── Combo LCD across nested combo-refs (T-NN) ───────────────────────
// Combos can nest other combos via `kind: "combo-ref"` members
// (e.g. MASTER-LIGHT contains OldLLM, KIRO, Opecode Zen FREE). The
// (e.g. MASTER-LIGHT contains LEGACY, KIRO, Opecode Zen FREE). The
// nested combo's own `limit.context` is computed below in this same
// loop, so we need a fixpoint iteration: if a combo-ref points at a
// combo not yet processed, defer this combo and try again after the
@@ -4495,7 +4495,7 @@ export function buildStaticProviderEntry(
// ── Combo LCD across nested combo-refs (T-NN mirror) ─────────────────
// Mirror of the dynamic-catalog fixpoint iteration: combos can nest
// other combos via `kind: "combo-ref"` members (e.g. MASTER-LIGHT
// contains OldLLM, KIRO, Opecode Zen FREE). The nested combo's own
// contains LEGACY, KIRO, Opecode Zen FREE). The nested combo's own
// capabilities and limits are computed in this same loop, so we need
// a fixpoint pass: if a combo-ref points at a combo not yet processed,
// defer this combo and try again after the sibling combos catch up.

View File

@@ -641,13 +641,13 @@ test("models(): combos fetcher receives the resolved baseURL + apiKey", async ()
test("models(): nested combo-ref context is the min of nested + raw members", async () => {
// Top-level combo MASTER-LIGHT has 1 raw model (claude-primary, 200k)
// and 2 combo-refs: OldLLM (8k member) and KIRO (32k member). The OLD
// and 2 combo-refs: LEGACY (8k member) and KIRO (32k member). The OLD
// plugin would advertise 200k (only the raw model); the fix should
// make it advertise 8k (the bottleneck across the member graph).
const modelsFetcher = stubModelsFetcher([
MODEL_PRIMARY,
{
id: "oldllm-member-1",
id: "legacy-member-1",
context_length: 8_000,
max_output_tokens: 4_000,
capabilities: {
@@ -677,9 +677,9 @@ test("models(): nested combo-ref context is the min of nested + raw members", as
]);
const combosFetcher = stubCombosFetcher([
{
id: "oldllm",
name: "OldLLM",
models: [{ id: "s1", kind: "model", model: "oldllm-member-1", weight: 100 }],
id: "legacy",
name: "LEGACY",
models: [{ id: "s1", kind: "model", model: "legacy-member-1", weight: 100 }],
},
{
id: "kiro",
@@ -691,7 +691,7 @@ test("models(): nested combo-ref context is the min of nested + raw members", as
name: "MASTER-LIGHT",
models: [
{ id: "r1", kind: "model", model: "claude-primary", weight: 50 },
{ id: "r2", kind: "combo-ref", comboName: "OldLLM", weight: 25 },
{ id: "r2", kind: "combo-ref", comboName: "LEGACY", weight: 25 },
{ id: "r3", kind: "combo-ref", comboName: "KIRO", weight: 25 },
],
},
@@ -706,6 +706,6 @@ test("models(): nested combo-ref context is the min of nested + raw members", as
assert.equal(
masterLight.limit.context,
8_000,
`expected 8_000 (OldLLM bottleneck), got ${masterLight.limit.context}`
`expected 8_000 (LEGACY bottleneck), got ${masterLight.limit.context}`
);
});

View File

@@ -46,7 +46,7 @@ Repository map and Reference Documentation sections below.
## Project at a Glance
**OmniRoute** — unified AI proxy/router. One endpoint, 352 LLM providers, auto-fallback.
**OmniRoute** — unified AI proxy/router. One endpoint, 354 LLM providers, auto-fallback.
| Layer | Location | Purpose |
| ------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

View File

@@ -97,6 +97,10 @@ _Living section — cycle opened at the v3.8.50 freeze (parallel-cycle model). B
### 🐛 Bug Fixes
- **security(streaming):** sanitize generic mid-stream error messages before emitting OpenAI,
Responses, or Claude SSE failure frames and before diagnostic logging, while preserving raw
failures for internal classification and keeping client disconnects out of provider failure state.
### 📝 Maintenance
---
@@ -716,7 +720,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -888,7 +891,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -3000,7 +3003,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3442,7 +3444,7 @@ _Living section — bullets land here as PRs merge into `release/v3.8.47` (paral
- **fix(cli):** `omniroute serve` no longer hangs silently on a readiness timeout ([#6321](https://github.com/diegosouzapw/OmniRoute/issues/6321)) — the child server's stdout was piped to `"ignore"` whenever `--log`/`OMNIROUTE_SHOW_LOG` wasn't set (the default), discarding any debug output, and `runWithSupervisor`'s `waitForServer(...).then((up) => { if (up) {...} })` had no `else` branch, so a boot that never became ready produced zero further output after "⏳ Starting server...". Stdout is now buffered alongside stderr (`ServerSupervisor.getRecentLog()`), and a timeout prints a clear diagnostic plus the buffered output instead of staying silent. Does not by itself explain why boot never completes on a given machine — see the issue for further reproduction. Regression guard: `tests/unit/cli-serve-readiness-timeout-6321.test.ts`.
- **fix(pricing):** Pricing Sync dashboard no longer stuck on "Next Sync: Never" / "Synced Models: 0" ([#6325](https://github.com/diegosouzapw/OmniRoute/issues/6325)) — `pricingSync.ts` kept sync state (`lastSyncTime`, `lastSyncModelCount`) in module-level vars, but the background periodic sync (`instrumentation-node.ts`) and the dashboard status route (`/api/pricing/sync`) each import the module from separate Next.js standalone webpack chunks, giving each its own independent state; `getSyncStatus()` read the (empty) API-route instance's vars. Sync status is now additionally persisted to a new `pricing_sync_status` `key_value` namespace and `getSyncStatus()` falls back to it when the local module instance never ran a sync itself. Regression guard: `tests/unit/pricing-sync-cross-instance.test.ts`.
- **fix(api):** stop spuriously 403-ing "Invalid request origin" on `POST /api/providers/health-autopilot/actions` for Docker/LAN dashboard requests ([#6277](https://github.com/diegosouzapw/OmniRoute/issues/6277)) — the route carried a duplicate per-route `validateBrowserMutationOrigin` check re-added by the v3.8.42 release squash after PR #5278 centralized origin enforcement in the authz pipeline; the pipeline strips `PEER_IP_HEADER` before forwarding, so the stale duplicate check could no longer resolve the LAN "direct-local-host" candidate and rejected legitimate same-origin LAN mutations (e.g. clicking "remove cooldown" when accessed via a LAN IP). Removed the duplicate check — origin validation is now solely enforced by the centralized pipeline check, which already handles this case correctly. Regression guard: `tests/unit/serial/provider-health-autopilot.test.ts`.
- **fix(resilience):** a bare, unrecognized `403` from a no-credential (`authType:"none"`) provider like mimocode or theoldllm no longer permanently bans the connection ([#6315](https://github.com/diegosouzapw/OmniRoute/issues/6315), [#6345](https://github.com/diegosouzapw/OmniRoute/issues/6345)) — `classifyProviderError()`'s 403 branch only exempted `apikey` providers from the terminal `FORBIDDEN` classification, so these free/stateless proxies (no real account/credential to revoke) fell through to `FORBIDDEN` on the first unmatched 403 and got `isActive:false, testStatus:"banned"` with no cooldown or retry. The exemption now also covers `authType:"none"` providers, returning `null` (recoverable) so the existing connection-cooldown/retry layer handles it. Regression guard: `tests/unit/errorClassifier-noauth-403-6315.test.ts`.
- **fix(resilience):** a bare, unrecognized `403` from a no-credential (`authType:"none"`) provider like mimocode no longer permanently bans the connection ([#6315](https://github.com/diegosouzapw/OmniRoute/issues/6315), [#6345](https://github.com/diegosouzapw/OmniRoute/issues/6345)) — `classifyProviderError()`'s 403 branch only exempted `apikey` providers from the terminal `FORBIDDEN` classification, so these free/stateless proxies (no real account/credential to revoke) fell through to `FORBIDDEN` on the first unmatched 403 and got `isActive:false, testStatus:"banned"` with no cooldown or retry. The exemption now also covers `authType:"none"` providers, returning `null` (recoverable) so the existing connection-cooldown/retry layer handles it. Regression guard: `tests/unit/errorClassifier-noauth-403-6315.test.ts`.
- **fix(providers):** the **Auggie (Augment CLI)** executor no longer fails on Windows with `spawn EINVAL` ([#6304](https://github.com/diegosouzapw/OmniRoute/issues/6304)) — the global-npm install exposes `auggie` as a `.cmd` shim, which Node's `child_process.spawn` cannot launch on win32 without `shell: true`. Both spawn sites (streaming + the `auggie --version` test) now go through a shared `buildAuggieSpawnOptions()` that sets `shell: process.platform === "win32"`; the argv (built by `buildAuggieArgs()` with a registry-validated `model` and a trailing `--` end-of-options marker) is unchanged, so the argument-injection surface stays closed on non-Windows. Regression guard: `tests/unit/auggie-win32-spawn-6304.test.ts`.
- **fix(api):** the dashboard **"Test model"** action is now a clean connection test ([#6240](https://github.com/diegosouzapw/OmniRoute/issues/6240)) — `modelTestRunner` sent its probe request without an explicit compression override, so whenever the operator's global `compression.enabled` flag was on the test call inherited compression (and any Output-Styles system prompt), polluting the result. The internal test requests now send `X-OmniRoute-Compression: off`, and `chatCore` honors an explicit `off` header even when `compression.enabled` is globally true. Regression guards: `tests/unit/model-test-runner-compression-off-6240.test.ts`, `tests/integration/test-model-compression-off-6240.test.ts`.
- **fix(startup):** an update/restart could crash the whole server at boot with `TypeError: Cannot create property 'message' on string 'Database closed'`, masking the real failure and 500-ing every request until manually restarted ([#6560](https://github.com/diegosouzapw/OmniRoute/issues/6560), plausibly the root cause of #6594's post-upgrade 500) — `driverFactory.ts::preInitSqlJs()` cached its sql.js WASM adapter per file path in a `globalThis`-backed map for idempotency, but never checked whether the cached adapter had since been closed (e.g. by `gracefulShutdown`/`resetDbInstance` racing a reload); reusing that dead handle made the very next query throw sql.js's own bare string `"Database closed"` (not an `Error`) straight out of `instrumentation-node.ts`'s previously-unguarded `ensureDbInitialized()` call, and Next.js's internal `registerInstrumentation()` wrapper unconditionally does `err.message = ...` on whatever `register()` rejects with — assigning `.message` on a primitive string throws in strict mode, so the secondary `TypeError` is what actually crashed the process. Fixed in two parts: `preInitSqlJs()` now evicts a closed cached adapter and creates a fresh one instead of returning it; a new `ensureDbReadyForBoot()` wraps the DB-init call, normalizes any non-Error throw via `normalizeBootError()`, and retries once specifically for a transient "database closed" message (now succeeding against the fresh adapter) before re-throwing anything else as a real `Error`. Regression guard: `tests/unit/instrumentation-database-closed-6560.test.ts`.
@@ -3998,7 +4000,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5644,7 +5645,6 @@ Thanks to everyone whose work landed in v3.8.43:
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))
@@ -6304,7 +6304,6 @@ Thanks to everyone whose work landed in v3.8.43:
- **fix(catalog):** Codex CLI model-catalog refresh no longer errors — `GET /v1/models` now returns a top-level `models: []` array for Codex clients (detected via the `originator` / `user-agent` = `codex_*` headers it sends on `GET /v1/models?client_version=...`), so `codex_models_manager` stops failing to decode the OpenAI-standard response and no longer logs `failed to refresh available models` on every startup. The array is intentionally empty: Codex replaces its built-in per-model agent prompt (`base_instructions`, ~21k chars) with whatever a populated entry carries for the selected model, so emitting our catalog would break Codex's agent behaviour — an empty list keeps Codex on its built-in model info (same inference as before, minus the error). Non-Codex OpenAI clients receive the unchanged `{object,data}` response. ([#3481](https://github.com/diegosouzapw/OmniRoute/pull/3481) — thanks @diegosouzapw)
- **fix(provider):** Cursor's Responses-API-shaped bodies on `/chat/completions` are detected and handled — a body with `input` but no `messages` is now classified as `openai-responses` (instead of forcing `openai` and building from undefined `messages` → upstream 400); standard OpenAI clients are unaffected by the `messages===undefined` guard. ([#3490](https://github.com/diegosouzapw/OmniRoute/pull/3490) — thanks @borodulin)
- **fix(sse):** numeric provider IDs normalized to strings across 4 more surfaces — extends #3427 to the Responses-API SSE passthrough (`response_id`/`item_id`/`call_id`), the buffered/flush path in `stream.ts`, the dedup-key builders, and `sseParser.ts`, preventing `undefined` lookups when IDs arrive as numbers. ([#3451](https://github.com/diegosouzapw/OmniRoute/pull/3451) — thanks @disafronov)
- **fix(theoldllm):** `X-Request-Token` generated server-side, dropping the Playwright dependency — replicates the site's client `rie()` token (djb2 hash + `oldllm-client-2026` seed + UA prefix + 8-hex `crypto.randomUUID` suffix) directly, so The Old LLM no longer needs a headless browser to mint tokens. ([#3491](https://github.com/diegosouzapw/OmniRoute/pull/3491) — thanks @borodulin / @diegosouzapw)
- **fix(combo):** parallel pre-screen + circuit-breaker fast-exit for priority combos — provider profiles and model availability for all targets are pre-screened concurrently (max 5), and targets whose circuit breaker is OPEN are skipped immediately, reducing first-token latency on multi-target priority combos. ([#3169](https://github.com/diegosouzapw/OmniRoute/pull/3169) — thanks @pizzav-xyz)
- **fix(authz):** URL-tokenized client endpoints (`/api/v1/vscode/<key>/...`) authenticate again when the caller sends its own non-OmniRoute `Authorization` header — a non-`Bearer <token>` header (e.g. VS Code Copilot's own, or an empty `Bearer `) no longer short-circuits auth; it falls through to the path-scoped URL token (still validated downstream), instead of 401'ing under `REQUIRE_API_KEY=true`. ([#3504](https://github.com/diegosouzapw/OmniRoute/pull/3504) — thanks @zhiru / @diegosouzapw)
- **fix(playground):** the dashboard provider Test playground works under `REQUIRE_API_KEY=true` — it previously sent the **masked** key (`sk-xxxx****yyyy`) as a bearer (always invalid → 401). It now authenticates via the dashboard session and sends only the key **id** (`x-omniroute-playground-key-id`); the gateway resolves the secret server-side, honored **only** for an authenticated session and never putting the key secret on the wire. ([#3503](https://github.com/diegosouzapw/OmniRoute/pull/3503) — thanks @zhiru / @diegosouzapw)
@@ -6337,7 +6336,7 @@ Thanks to everyone whose work landed in v3.8.43:
- **fix(translator):** Vertex AI tool calls no longer fail with `400 Unknown name "id"` — the OpenAI-style `id` field is stripped from `functionCall`/`functionResponse` parts for `vertex`/`vertex-partner`; the public Gemini API still receives `id` as required for Gemini 3+ signature matching. ([#3457](https://github.com/diegosouzapw/OmniRoute/pull/3457) — thanks @nullbytef0x / @diegosouzapw)
- **fix(claude):** Claude Code `claude-opus-4-8` tool calls no longer break with `tool call could not be parsed` — OmniRoute no longer force-injects `interleaved-thinking` / `advanced-tool-use` / `effort` beta flags the client never negotiated; clients sending their own `anthropic-beta` header control those betas themselves. ([#3458](https://github.com/diegosouzapw/OmniRoute/pull/3458) — thanks @Forcerecon / @diegosouzapw)
- **fix(catalog):** imported/custom models on no-auth providers (e.g. The Old LLM) now appear in `GET /api/v1/models` and the Playground model selector — the eligibility gate required a DB connection row which no-auth providers never have, silently dropping every imported model for them. ([#3463](https://github.com/diegosouzapw/OmniRoute/pull/3463) — thanks @tjengbudi / @diegosouzapw)
- **fix(catalog):** imported/custom models on no-auth providers now appear in `GET /api/v1/models` and the Playground model selector — the eligibility gate required a DB connection row which no-auth providers never have, silently dropping every imported model for them. ([#3463](https://github.com/diegosouzapw/OmniRoute/pull/3463) — thanks @tjengbudi / @diegosouzapw)
- **fix(browser):** optional `cloakbrowser` import no longer causes bundle errors when the package is absent — the import is now wrapped in a dynamic require so the build succeeds on environments that don't install the optional dep. ([#3460](https://github.com/diegosouzapw/OmniRoute/pull/3460) — thanks @rdself)
- **fix(claude-web):** claude-web session handling cleanup — corrects an edge case where session cookies were not properly refreshed after a Turnstile challenge, and removes stale wrapper code left over from the provider split. ([#3449](https://github.com/diegosouzapw/OmniRoute/pull/3449) — thanks @androw)
- **fix(analytics):** SQL named params are now scoped per query context — a shared params object was being mutated across concurrent analytics queries, causing `SQLITE_MISUSE: named parameter not found` errors under load. ([#3447](https://github.com/diegosouzapw/OmniRoute/pull/3447) — thanks @ReqX)
@@ -6513,8 +6512,7 @@ Thanks to everyone whose work landed in v3.8.14:
- **fix(dashboard):** Agent Bridge page (`/dashboard/tools/agent-bridge`) no longer crashes with "Internal Server Error" — the page replaced its well-shaped state with the raw `/api/tools/agent-bridge/state` response (`{ server, agents }`), leaving `serverState` undefined and throwing `Cannot read properties of undefined (reading 'running')`. A shared `normalizeAgentBridgeState()` now maps the route shape into the page contract (incl. `server.certExists → certTrusted`) and always returns safe defaults, used by both the SSR loader and the polling hook. (#3318 — thanks @tycronk20)
- **fix(codex):** strip client-only params (`prompt_cache_retention`, `safety_identifier`, `user`) on the native `codex/` `/v1/responses` passthrough — Codex upstream rejects them with `400 Unsupported parameter`, which broke Factory Droid and any client injecting those fields. The chat-completions path already stripped them; the responses→responses passthrough now does too. (#3317 — thanks @tycronk20)
- **fix(theoldllm):** stop the `[502]: Body is unusable: Body has already been read` error on the cached-token path — the executor read the same upstream `Response` body with `.text()` twice; it now reads it once and only re-reads after a token-rejection refetch. (#3296 — thanks @onizukashonan14-png)
- **fix(dashboard):** keep no-auth providers (opencode, duckduckgo-web, theoldllm, veoaifree-web) visible under the "Show configured only" filter — they never create a connection row (`stats.total === 0`) but are always usable and already appear in `/v1/models`, so the filter now treats `displayAuthType === "no-auth"` as configured. (#3290 — thanks @uniQta)
- **fix(dashboard):** keep no-auth providers (opencode, duckduckgo-web, veoaifree-web) visible under the "Show configured only" filter — they never create a connection row (`stats.total === 0`) but are always usable and already appear in `/v1/models`, so the filter now treats `displayAuthType === "no-auth"` as configured. (#3290 — thanks @uniQta)
- **fix(dashboard):** refresh the connection list after a Codex/Claude/Gemini auth import — the import modals called `fetchData()` (which only reloads provider metadata), so a freshly-imported connection stayed invisible until a manual reload; they now call `fetchConnections()`. ([#3320](https://github.com/diegosouzapw/OmniRoute/pull/3320) — thanks @zhiru)
- **fix(cli):** `omniroute update` no longer always fails on a global install — `getCurrentVersion()` and `createBackup()` now resolve `package.json`/`bin` relative to the script (`import.meta.url`) instead of `process.cwd()` (the user's working dir on a global npm/brew install → _"Could not determine current version"_), and the backup copies the `cli` directory with `cpSync({recursive:true})` instead of `copyFileSync`, which threw a swallowed `EISDIR`_"Failed to create backup. Aborting"_. (#3295 — thanks @uniQta)
- **fix(sse):** harden the passthrough stream against empty upstream responses — emit a synthetic retry chunk on an empty `choices: []` (fixes a Copilot Chat crash) and log empty post-`tool_calls` completions; also registers **MiniMax M3** (1M context) across 8 provider tiers. ([#3297](https://github.com/diegosouzapw/OmniRoute/pull/3297), #3110 — thanks @wilsonicdev)
@@ -6606,7 +6604,6 @@ Thanks to everyone whose work landed in v3.8.12:
### ✨ New Features
- **theoldllm:** add The Old LLM — a free, Playwright-backed provider with dual-mode operation (cached browser token + direct fetch) bridged through a Vercel relay (#3217 — thanks @oyi77)
- **codex:** add Codex login via OpenAI's browser-driven device authorization flow, exposed as a shareable "Adicionar Externo" public link (`/connect/codex/{token}`) so a third party can complete the OpenAI device login without dashboard access (#3195 — thanks @zhiru)
- **proxy:** per-connection proxy distribution — `proxy_enabled` DB schema + Zod-validated resolution backend, automatic proxy-fallback selection when provider validation hits a network error, and a dashboard UI with per-connection toggles and a tag-filtered "Distribute Proxies" button (#3170, #3171, #3172 — thanks @pizzav-xyz)
- **api:** `/v1/images/generations` and `/v1/images/edits` now resolve a bare combo/alias model name (e.g. `image`) to its single image target, and `/v1/images/edits` forwards multipart edits to custom OpenAI-compatible providers' `{base_url}/images/edits` (also accepting JSON/data-URL edit input) instead of rejecting everything but chatgpt-web (#3214, #3215 — thanks @ngocquynh85)

View File

@@ -177,6 +177,13 @@ npm run test:all
# Single test file (Node.js native test runner — most tests use this)
node --import tsx/esm --test tests/unit/your-file.test.ts
# Only the unit tests impacted by your change (same TIA selector as the CI gate, #8084)
npm run test:scoped # changes in the last commit (or the working tree)
npm run test:scoped:staged # staged changes only — pairs well with a pre-commit run
npm run test:scoped:full # rebuild the import-graph map first (after adding/moving files)
# Exit 1 + "run the full suite" means a hub file (tsconfig, package.json, …) or an
# unmapped source changed — the selector fails safe, it never silently skips.
# Vitest (MCP server, autoCombo, cache)
npm run test:vitest

View File

@@ -7,7 +7,7 @@
# 🚀 OmniRoute — The Free AI Gateway
<img src="./docs/diagrams/readme-hero.svg" width="100%" alt="OmniRoute — Never stop coding. Every AI tool → 352 providers — 150+ free — through one endpoint. Claude Code, Codex, Cursor, Cline, Copilot & Antigravity into FREE Claude / GPT / Gemini with auto-fallback. RTK + Caveman stacked compression saves 1595% tokens (~89% avg) — never hit limits. 352 AI providers · 150+ free tiers · ~1.51B free tokens/mo · 19 routing strategies · $0 to start."/>
<img src="./docs/diagrams/readme-hero.svg" width="100%" alt="OmniRoute — Never stop coding. Every AI tool → 354 providers — 150+ free — through one endpoint. Claude Code, Codex, Cursor, Cline, Copilot & Antigravity into FREE Claude / GPT / Gemini with auto-fallback. RTK + Caveman stacked compression saves 1595% tokens (~89% avg) — never hit limits. 354 AI providers · 150+ free tiers · ~1.51B free tokens/mo · 19 routing strategies · $0 to start."/>
</div>
@@ -210,7 +210,7 @@ curl http://localhost:20128/v1/chat/completions \
</div>
<img src="./docs/diagrams/promise-pillars.svg" width="100%" alt="The Promise — One endpoint and 352 providers. Automatic fallback keeps routing while another healthy target is available. Six pillars: resilient fallback across 352 providers · up to 95% token savings on eligible workloads · $0 to start with 150+ free tiers and 53 recurring/keyless free-forever providers · 36 CLI/agent integrations through one config · OpenAI, Claude, Gemini and Responses API compatibility at /v1 · production controls including circuit breakers, TLS stealth, MCP 110 tools, A2A, memory, guardrails, evals and 39,000+ static test declarations across 5,100+ tracked test files."/>
<img src="./docs/diagrams/promise-pillars.svg" width="100%" alt="The Promise — One endpoint and 354 providers. Automatic fallback keeps routing while another healthy target is available. Six pillars: resilient fallback across 354 providers · up to 95% token savings on eligible workloads · $0 to start with 150+ free tiers and 53 recurring/keyless free-forever providers · 36 CLI/agent integrations through one config · OpenAI, Claude, Gemini and Responses API compatibility at /v1 · production controls including circuit breakers, TLS stealth, MCP 110 tools, A2A, memory, guardrails, evals and 39,000+ static test declarations across 5,100+ tracked test files."/>
<br/>
<br/>
@@ -463,7 +463,7 @@ All **19** strategies — mix & match per combo step:
</div>
<img src="./docs/diagrams/comparison-table.svg" width="100%" alt="What sets OmniRoute apart — a dated feature snapshot vs 9router, OpenRouter, CLIProxyAPI and LiteLLM across 13 capabilities. OmniRoute: 352 providers, 150+ free tiers built in, 19 routing strategies, 12-engine token compression, built-in MCP server with 110 tools, A2A agent protocol, persistent memory, guardrails, cloud agents, TLS fingerprint stealth, Desktop/Termux/PWA and 43 i18n UI locales. OmniRoute is MIT-licensed and self-hostable. Competitor capabilities and counts may change; see the linked methodology."/>
<img src="./docs/diagrams/comparison-table.svg" width="100%" alt="What sets OmniRoute apart — a dated feature snapshot vs 9router, OpenRouter, CLIProxyAPI and LiteLLM across 13 capabilities. OmniRoute: 354 providers, 150+ free tiers built in, 19 routing strategies, 12-engine token compression, built-in MCP server with 110 tools, A2A agent protocol, persistent memory, guardrails, cloud agents, TLS fingerprint stealth, Desktop/Termux/PWA and 43 i18n UI locales. OmniRoute is MIT-licensed and self-hostable. Competitor capabilities and counts may change; see the linked methodology."/>
<sub>📊 Full methodology &amp; per-feature detail vs 9router, OpenRouter, CLIProxyAPI &amp; LiteLLM → [`docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md`](docs/comparison/OMNIROUTE_VS_ALTERNATIVES.md)</sub>
@@ -1020,7 +1020,7 @@ Full table: [Docker Guide — runtime RAM](docs/guides/DOCKER_GUIDE.md#runtime-r
Standard `bun install` and global installation (`bun install -g omniroute`) are supported via Bun runtime detection:
- **Built-in `bun:sqlite`**: OmniRoute uses Bun's built-in `bun:sqlite` driver when running under Bun, falling back to `better-sqlite3` on Node.js or `sql.js`.
- **Automatic Webpack bundler selection**: Development (`bun run dev`) and production builds (`bun run build`) automatically detect Bun and disable Turbopack in favor of Webpack to prevent native V8 binding incompatibilities.
- **Automatic Webpack bundler selection in dev**: Development (`bun run dev`) automatically detects Bun and disables Turbopack in favor of Webpack to prevent native V8 binding incompatibilities. Production builds (`bun run build`) follow `OMNIROUTE_USE_TURBOPACK` exactly as on Node: Turbopack by default, `OMNIROUTE_USE_TURBOPACK=0` to build with Webpack (`Dockerfile.bun` exposes it as a `--build-arg`).
- **Dedicated Bun Dockerfile**: Multi-stage `Dockerfile.bun` for native Bun production deployments (`docker build -f Dockerfile.bun -t omniroute:bun .`).
```bash

View File

@@ -5,7 +5,11 @@ import { fileURLToPath, pathToFileURL } from "node:url";
import { platform, totalmem } from "node:os";
import { t } from "../i18n.mjs";
import { writePidFile, cleanupPidFile, waitForServer } from "../utils/pid.mjs";
import { ServerSupervisor, detectMitmCrash } from "../runtime/processSupervisor.mjs";
import {
ServerSupervisor,
detectMitmCrash,
BUN_PRELOAD_PATH,
} from "../runtime/processSupervisor.mjs";
import { isTermux } from "../../../scripts/build/postinstallSupport.mjs";
import {
ensureAndroidCacheDir,
@@ -306,7 +310,7 @@ function runDaemon(serverJs, env, memoryLimit, dashboardPort, apiPort) {
process.versions.bun ? process.execPath : "node",
[
...(process.versions.bun
? ["--preload", join(APP_DIR, "open-sse/utils/setupPolyfill.ts")]
? ["--preload", BUN_PRELOAD_PATH]
: buildNodeHeapArgs(process.env, memoryLimit)),
serverJs,
],
@@ -331,7 +335,7 @@ function runWithoutRecovery(serverJs, env, memoryLimit, dashboardPort, apiPort,
process.versions.bun ? process.execPath : "node",
[
...(process.versions.bun
? ["--preload", join(APP_DIR, "open-sse/utils/setupPolyfill.ts")]
? ["--preload", BUN_PRELOAD_PATH]
: buildNodeHeapArgs(process.env, memoryLimit)),
serverJs,
],
@@ -423,7 +427,9 @@ async function runWithSupervisor(
if (detectMitmCrash(crashLog)) {
try {
const PROJECT_ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
const { updateSettings } = await import(pathToFileURL(join(PROJECT_ROOT, "src/lib/db/settings.ts")).href);
const { updateSettings } = await import(
pathToFileURL(join(PROJECT_ROOT, "src/lib/db/settings.ts")).href
);
updateSettings({ mitmEnabled: false });
} catch {}
return "disable-mitm-and-retry";

View File

@@ -1,5 +1,6 @@
import { spawn } from "node:child_process";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { writePidFile, cleanupPidFile, killAllSubprocesses, isPidRunning } from "../utils/pid.mjs";
import {
RESTART_RESET_MS,
@@ -17,6 +18,24 @@ import {
const CRASH_LOG_LINES = 50;
const PACKAGE_ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
// Bun needs the Node-compat polyfill preloaded (#9761). The file ships at the
// package root via package.json "files" (see scripts/build/pack-artifact-policy.ts)
// and is never copied into dist/, so the path must resolve against the package
// root — resolving it next to the server bundle fails with "preload not found" (#11980).
export const BUN_PRELOAD_PATH = join(PACKAGE_ROOT, "open-sse", "utils", "setupPolyfill.ts");
/**
* Argument vector for the server child. Kept pure so tests can assert on it
* directly: the bare `import { spawn }` above cannot be intercepted without
* --experimental-test-module-mocks (same seam as #8131).
*/
export function buildServerSpawnArgs(serverPath, memoryLimit, env = process.env) {
return process.versions.bun
? ["--preload", BUN_PRELOAD_PATH, serverPath]
: buildNodeRuntimeArgs(env, memoryLimit, serverPath);
}
export class ServerSupervisor {
constructor({
serverPath,
@@ -55,21 +74,11 @@ export class ServerSupervisor {
// Node args come from buildNodeRuntimeArgs (#9209 IPv4-first DNS + #5238
// heap flag handling); the Bun branch keeps #9761's polyfill preload —
// Bun does not accept the Node-only flags.
this.child = spawn(
process.execPath,
process.versions.bun
? [
"--preload",
join(dirname(this.serverPath), "open-sse/utils/setupPolyfill.ts"),
this.serverPath,
]
: buildNodeRuntimeArgs(process.env, this.memoryLimit, this.serverPath),
{
cwd: dirname(this.serverPath),
env: this.env,
stdio: showLog ? "inherit" : ["ignore", "pipe", "pipe"],
}
);
this.child = spawn(process.execPath, buildServerSpawnArgs(this.serverPath, this.memoryLimit), {
cwd: dirname(this.serverPath),
env: this.env,
stdio: showLog ? "inherit" : ["ignore", "pipe", "pipe"],
});
writePidFile("server", this.child.pid);

View File

@@ -0,0 +1 @@
- **feat(ui):** enable React Compiler (`reactCompiler: true` + `babel-plugin-react-compiler`) for automatic memoization at build time ([#11783](https://github.com/diegosouzapw/OmniRoute/pull/11783)) — thanks @jonlwheat2-gif

View File

@@ -0,0 +1 @@
- **feat(sse):** treat `max` as a first-class reasoning-effort tier and clamp per model family (GLM 5.1+/DeepSeek V4+/Kimi K3+ keep native `max`; o1/MiniMax/Grok/Muse Spark clamp to their upstream ceiling) ([#11875](https://github.com/diegosouzapw/OmniRoute/pull/11875)) — thanks @Chewji9875

View File

@@ -0,0 +1 @@
- Add a runtime feature flag to disable universal context handoffs globally without changing the default behavior.

View File

@@ -0,0 +1 @@
- **feat(providers):** the provider plugin manifest now also advertises a `usage-supported` capability for the 46 providers whose usage API is accepted by the server and Dashboard routes, so integrators can distinguish "the server will serve quota for this provider" from "a fetcher is wired" without reading TypeScript. Discovery only — no fetcher or quota change. `usage-fetch` resolves on id or alias (the usage dispatcher accepts both); `usage-supported` resolves on id alone, matching the runtime guard `USAGE_SUPPORTED_PROVIDERS.includes(providerId)`. `USAGE_SUPPORTED_PROVIDERS` moved to a zero-dependency leaf (`open-sse/services/usage/supportedProviders.ts`) and is re-exported from `providers.ts`, mirroring the `fetcherProviders` leaf from #11903 and keeping the manifest a light module. ([#12214](https://github.com/diegosouzapw/OmniRoute/pull/12214)) — thanks @maxmad64bis

View File

@@ -0,0 +1 @@
- **feat(usage):** Devin CLI agentic quota (Codeium seat-management GetUserStatus) and OpenRouter key limits plus account credits now surface in Provider Limits ([#12256](https://github.com/diegosouzapw/OmniRoute/pull/12256) — thanks @Neuron-Mr-White)

View File

@@ -0,0 +1 @@
- **feat(radar):** explain Community, single-use, contributor, supporter, recovery, abuse, offers, and privacy rules before either Radar activation action, and remove the superseded fixed-PR grant promise from every UI locale ([#12342](https://github.com/diegosouzapw/OmniRoute/pull/12342))

View File

@@ -0,0 +1 @@
- **feat(gamification):** the dashboard Profile page now shows the real daily streak — `/api/gamification/level` returns `streak: { current, longest }` (per key with `apiKeyId`, operator-wide maximum otherwise) and the streak card reads it instead of a hard-coded 0 (#2403)

View File

@@ -0,0 +1 @@
- **feat(gamification):** the dashboard leaderboard now shows each API key's display name under the Name column instead of a truncated key id; `GET /api/gamification/leaderboard` attaches `name` per entry (name only — no key material), while the shared ranking helper and the federation leaderboard stay id-only — thanks @pacocartones

View File

@@ -0,0 +1 @@
- **feat(gamification):** enforce the documented 1000 XP/min per-API-key anti-cheat rate limit on the XP award path; over-limit awards are logged and skipped instead of persisted, and the sliding window now matches the timestamp format stored in `xp_audit_log` ([#2403](https://github.com/diegosouzapw/OmniRoute/issues/2403))

View File

@@ -0,0 +1 @@
- **feat(admin):** localize the gamification anomalies page — the loading state, the Status column and the Suspicious badge now come from the `common` catalog (new `common.suspicious` key propagated to every locale) — add it to the Gamification sidebar group as `gamification-admin` (`/dashboard/gamification/admin`), and expose the loading and empty states as polite `role="status"` live regions (#12401 — thanks @pacocartones)

View File

@@ -0,0 +1,6 @@
- **feat(providers):** add MaxAI as a signed, OpenAI-compatible provider serving its 13 paid chat models (GPT-5.6 / Luna / Thinking, Claude 5 Sonnet, Claude Haiku 4.5, Gemini 3.1 Pro / Flash-Lite, Grok 4.1-fast / 4.5, DeepSeek V3.2 / R1, Llama 3.3 70B) through OmniRoute's `/v1` endpoint, with per-request HMAC-SHA1→SM3→AES request signing, live model + context-window discovery from `/models/get_config`, and prompted tool-calling translated to OpenAI `tool_calls`
- **feat(providers):** MaxAI vision input — image_url content parts are forwarded inline in `message_content` to the 6 vision-capable models (GPT-5.6 / Luna / Thinking, Claude Haiku 4.5, Gemini 3.1 Pro / Flash-Lite)
- **feat(providers):** MaxAI image generation — 6 image models (gpt-image-1, dall-e-3, flux-1-schnell/dev/pro, sd3-medium) exposed through `POST /v1/images/generations`
- **feat(providers):** MaxAI document RAG — inline base64 file/document attachments are uploaded to MaxAI (content-addressed `doc_id`) and attached to the chat via `doc_list`
- **feat(providers):** browserless MaxAI onboarding — email device-pair login (`/api/providers/[id]/login`) and signed access-token refresh, so a connection can be created and kept fresh without a real browser or Google OAuth
- **feat(providers):** per-provider TLS impersonation profile (MaxAI presents a Windows Firefox-150 client fingerprint) so its bot-sensitive endpoints accept OmniRoute traffic

View File

@@ -0,0 +1,5 @@
- **feat(dashboard):** the `/dashboard/orchestration` snapshot hook now subscribes to the
`agents` WebSocket channel (`agent.task.updated`) instead of `requests` as its refetch
trigger, and relaxes its background poll from 5s to 30s while that WS connection is up —
falling back to the tighter 5s cadence, reprogrammed live on any connect/disconnect
transition, whenever the socket is down.

View File

@@ -0,0 +1,11 @@
- **feat(dashboard):** Orchestration canvas quick wins — search box plus state/source/provider
filter chips with a one-click clear, and per-source collapse/expand, all reflected in the URL
so a filtered/collapsed view is shareable and survives a refresh; the detail drawer gained a
"copy trace JSON" action and hardened error/empty-state and accessibility handling; the
Agents-tab edges now animate traveling particles along active (running) connections; and the
canvas node/edge status colors moved off fixed hex values onto theme-aware `--orch-status-*`
CSS custom properties, so they adapt correctly to light/dark mode.
- **chore(dashboard):** Orchestration UI hardening pass and the missing component/model test
coverage it called for — `OrchestratorNode`/`ActivityNode`/`OverflowNode` rendering, the
`?node=`/overflow-click page routing, the Agents-tab orchestrator-click no-op and
`showCompleted` toggle, and the overview kanban's done-column sort order (#12270, #12271).

View File

@@ -0,0 +1 @@
- **feat(providers): add UC Direct (uncensored.com Developer API), the metered OpenAI-compatible surface.** A standard OpenAI-compatible passthrough (default executor) for uncensored.com's official REST API at `https://api.uncensored.com/api/v1`: `X-api-key` auth (never-expiring `uai_sk_live_` key), `POST /chat/completions` with streaming SSE and native tool-calling, and the full live metered catalog (82 models across 15 providers, discovered from the public `GET /v1/models`). Registered as provider `uc-direct` (alias `ucd`). Complements the un-metered `uc` persona provider — same models, metered credits and a plain API key instead of a subscription session.

View File

@@ -0,0 +1 @@
- **feat(providers): add UC (uncensored.com), the un-metered subscription "persona" chat as an OpenAI-compatible provider.** A WebSocket web-app port: a durable Clerk credential mints a short-lived session token per connect (browserless — no API key), driving UC's persona socket. Ships the browserless email-code login (request → verify → harvest), the 19 verified persona models (Claude Opus, Gemini, Grok, GLM, Kimi, DeepSeek, MiniMax, incl. the uncensored variants), prompted `<tool>` tool-calling with a per-model code-style dialect + auto-cure retry for guardrailed models, live `<think>`/reasoning split, streaming + non-streaming OpenAI responses, and full quota/auth error surfacing (paywall / message-limit / rate-limit → 429, invalid session → 401 re-login). Full multimodal parity via the persona blob-upload layer: **vision** (image input, 15 vision-capable models), **document RAG** (PDF/doc upload, server-side extraction), **image generation** (22 models), **video generation** (14 models, async signed-url → poll), and **TTS** (streaming MP3). Registered as provider `uc` (alias `ucn`). The metered OpenAI-compatible Developer API is a separate `uc-direct` provider.

View File

@@ -0,0 +1,3 @@
- Fixed the v3.8.50 Costs and Analytics dashboards so flat-rate Claude Code usage can be shown as an explicitly requested token-price estimate without changing default billed-cost semantics.
- Fixed archived usage retention so each request is priced individually instead of pricing a day's summed tokens once, which understated archived cost whenever a day mixed cache-heavy and ordinary requests.
- Fixed the Costs dashboard so it discloses when displayed figures include flat-rate token-price estimates instead of labelling them as billed spend, using the flag the analytics API already returns; the month-end projection and the CSV/JSON exports carry the same marker, and billed-cost mode is unchanged.

View File

@@ -0,0 +1 @@
- **perf(compression):** OOM mitigations for large payload hashing, memoization, and token estimation ([#11844](https://github.com/diegosouzapw/OmniRoute/pull/11844) — thanks @AndrianBalanescu)

View File

@@ -0,0 +1,5 @@
- **fix(memory):** self-hosted embedding endpoints now vectorize — the vector width is
measured from the first embedding that comes back instead of being read from a registry
that cannot describe them, so `vec_memories` is created and memories stop piling up
unvectorized behind a green health check
([#12180](https://github.com/diegosouzapw/OmniRoute/pull/12180)) — thanks @kanade-hoshino

View File

@@ -0,0 +1 @@
- **fix(sse):** Keep ZWNJ (U+200C) and ZWJ (U+200D) in assistant text, reasoning and tool-call arguments — Persian/Kurdish half-space (`ارائه‌دهنده`), Arabic/Indic shaping and emoji sequences no longer lose them; the response de-obfuscation now removes joiners only between ASCII word characters, where the request side inserts them ([#12186](https://github.com/diegosouzapw/OmniRoute/issues/12186)) — thanks @rezjalibd

View File

@@ -0,0 +1 @@
- **fix(resilience):** count resolved upstream 5xx results against the provider circuit breaker on the chat path — `CircuitBreaker.execute()` no longer reads a resolved `{ success: false, status: 5xx }` as a success that cancels the call-site failure, so a provider answering 503s now trips its breaker instead of staying `CLOSED` at `failureCount: 1`; single-model and combo dispatches are each accounted exactly once ([#12254](https://github.com/diegosouzapw/OmniRoute/issues/12254))

View File

@@ -0,0 +1 @@
- **fix(providers):** resolve the Codex quota auto-ping model from the live provider catalog and lifecycle registry instead of the retired `gpt-5.1-codex-mini`, and pause the ping with one actionable warning when no selectable Codex model exists rather than retrying a shut-down id every cooldown window ([#11905](https://github.com/diegosouzapw/OmniRoute/issues/11905))

View File

@@ -0,0 +1 @@
- **fix(api):** keep the `{created, data}` wrapper on combo-routed `/v1/images/generations` responses and default Codex image results to `b64_json` on both `/v1/images/generations` and `/v1/images/edits` so Codex CLI's built-in `image_gen` can decode them ([#12268](https://github.com/diegosouzapw/OmniRoute/issues/12268))

View File

@@ -0,0 +1 @@
- **fix(sse):** Name the shadowed custom provider node when a built-in provider id/alias (e.g. `openference``of`) reserves the prefix of an existing OpenAI/Anthropic-compatible node, so the runtime `No active credentials for provider: <built-in>` error explains that the prefix routed to the built-in and never reached the node's healthy connections, instead of contradicting the dashboard ([#11943](https://github.com/diegosouzapw/OmniRoute/issues/11943)) — thanks @morpheus9393

View File

@@ -0,0 +1 @@
- **fix(guardrails):** keep `auto`/`auto/*` virtual combos exempt from the Vision Bridge `fixedModel` credential guard so a combo target is passed through instead of silently falling back to global auto-selection ([#12237](https://github.com/diegosouzapw/OmniRoute/issues/12237))

View File

@@ -0,0 +1 @@
- **fix(combo):** capability-filter exhaustion caused by `max_tokens` above every target's known output limit now reports that reason (requested `max_tokens` vs the pool's highest known ceiling) instead of the unrelated "supports structured output" message ([#12229](https://github.com/diegosouzapw/OmniRoute/issues/12229)) — thanks @DW-MediaLab

View File

@@ -0,0 +1 @@
- **fix(auth):** the `least-used` account strategy now prefers accounts without backoff before falling back to oldest `lastUsedAt`, the same tie-break `round-robin` already applies, so a failover no longer lands on a just-rate-limited account for a single request ([#12279](https://github.com/diegosouzapw/OmniRoute/issues/12279)) — thanks @tenshiak

View File

@@ -0,0 +1 @@
- **fix(docker):** the `chatgpt-web-codex-browser` image now finds the Chrome binary under `chrome-linux64/` (Chrome for Testing layout in `playwright:v1.62.0-noble`) as well as the legacy `chrome-linux/`, so the container no longer crash-loops with `exec: --headless=new: not found` ([#12024](https://github.com/diegosouzapw/OmniRoute/issues/12024))

View File

@@ -0,0 +1 @@
- **fix(providers):** declare `groq/compound` and `allam-2-7b` as non-reasoning models in the curated Groq registry so `reasoning_effort` / `output_config.effort` / `thinking` from Claude Code are stripped instead of forwarded, which Groq rejected with HTTP 400 ([#12134](https://github.com/diegosouzapw/OmniRoute/issues/12134))

View File

@@ -0,0 +1 @@
- **fix(executors):** `OpencodeExecutor` no longer forces a direct connection when the connection has a proxy assigned in Proxy Management but no per-account proxies: the single-account fast path used to wrap the upstream dispatch in the direct-egress sentinel, discarding the ambient proxy context the chat handler had pinned from `proxy_assignments`, so API-key `opencode`/`opencode-go` connections egressed from the host IP (and hit geoblocks) despite the assignment. The direct pin is now applied only when no ambient proxy context exists ([#11894](https://github.com/diegosouzapw/OmniRoute/issues/11894) — thanks @hizzt)

View File

@@ -0,0 +1 @@
- **fix(api):** `GET /v1/models` with `MODELS_CATALOG_PREFIX_MODE=canonical` (or `?prefix=canonical`) now lists providers whose registry alias is undefined or equal to their own id (Antigravity, Antigravity CLI and other self-aliased built-ins) — their single `provider/model` id was dropped by the alias/canonical duplicate guard in the static, synced, custom and alias-backed catalog loops ([#12058](https://github.com/diegosouzapw/OmniRoute/issues/12058)) — thanks @cheynetom

View File

@@ -0,0 +1 @@
- **fix(translator):** Drop replayed `thinking` blocks that carry no signature (the shape produced from cross-provider `reasoning_content`) instead of stamping the default Claude signature on them, which Anthropic rejected with `400 Invalid signature in thinking block` on the next turn served by an Anthropic rung ([#12105](https://github.com/diegosouzapw/OmniRoute/issues/12105)) — thanks @atescivitci-cmd

View File

@@ -0,0 +1 @@
- **fix(cli):** Resolve Bun's `--preload` polyfill path against the package root instead of `dist/`, so `omniroute` installed with `bun install -g` no longer crashes at startup with `error: preload not found …/dist/open-sse/utils/setupPolyfill.ts` ([#11980](https://github.com/diegosouzapw/OmniRoute/issues/11980)) — thanks @joglomedia

View File

@@ -0,0 +1 @@
- **fix(providers):** `gemini-business` now publishes its model catalog — `/v1/models` and `/v1/providers/gemini-business/models` list the 12 enterprise Gemini ids the executor understands instead of returning an empty list (#12107)

View File

@@ -0,0 +1 @@
- **fix(db):** install `busy_timeout` before the SQLite connection's first statement so a process opening the database while another one closes its WAL connection waits out the transient EXCLUSIVE lock instead of dying with `database is locked`, and recognise the drivers' real BUSY/PROTOCOL/IOERR errors as transient in the corruption probe so the same lock no longer renames the database away as corrupt; deflakes `cross-process contenders never both acquire the same connection` (#12394 — thanks @pacocartones)

View File

@@ -0,0 +1 @@
- **fix(chat-admission):** derive the `chat_admission_busy` 503 `Retry-After` from observed heavyweight-lease occupancy — the larger of the exhausted `OMNIROUTE_CHAT_ADMISSION_QUEUE_MS` window and the time since capacity last turned over, capped at 60 s — instead of a fixed 1 s (structural) / 2 s (byte-stage) hint that invited Codex/agent fan-out clients to re-send ~1 MiB `/v1/responses` bodies every second into a gate held for the whole SSE lifetime; an idle gate keeps the historical floors ([#12135](https://github.com/diegosouzapw/OmniRoute/issues/12135)) (#12395 — thanks @pacocartones)

View File

@@ -0,0 +1 @@
- **fix(api-manager):** the API key permissions modal no longer silently drops `allowedCombos` entries its Combo picker cannot render — routing-rule names such as `rt-*`, which the backend already honours — when "All" is clicked and the key is switched back to "Restrict"; those entries now survive the toggle, are listed read-only under the combo list so the count and the list agree, and are saved back verbatim instead of persisting `[]` (deny-all) (#12397 — thanks @pacocartones)

View File

@@ -0,0 +1 @@
- **fix(catalog):** write the NUL separator of the catalog connection memo key, the provider serviceKind memo key, the Video Bridge promotion group key and a JSON-exactness test fixture as the `\u0000` escape instead of a raw byte — same runtime value, but the raw byte made git, GitHub and ripgrep treat those files as binary (hidden PR diffs, silently skipped searches); a guard test now keeps raw NUL bytes out of `src/`, `open-sse/` and `tests/` (#12403 — thanks @pacocartones)

View File

@@ -0,0 +1 @@
- **fix(memory):** Embedding Model Quick select, Embedding Source remote dropdown, and Rerank selector now list every configured provider with embedding/rerank support instead of only chat-catalog text matches plus OpenRouter live discovery; a generic OpenAI-compatible `/embeddings` + Cohere-compatible `/rerank` runtime fallback resolves any configured chat provider's embedding/rerank endpoint, so unlisted providers no longer fail with "Unknown embedding provider"; both memory selectors gained a free-text model override

View File

@@ -0,0 +1 @@
- **docs(env):** align `.env.example`, the README Bun section, and the troubleshooting guide with the code: `OMNIROUTE_USE_TURBOPACK` also governs `npm run build` (not dev-only), `bun run build` follows that flag instead of auto-selecting Webpack, `OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT` is unset by default (no request-count cap), and the structural `503 chat_admission_busy` message matches `chatAdmissionResponses.ts` (#12404 — thanks @pacocartones)

View File

@@ -1,401 +1,400 @@
{
"open-sse/transformer/responsesTransformer.ts": {
"TS2353": 2
"TS2353": 1
},
"open-sse/utils/progressTracker.ts": {
"TS2353": 2
"TS2353": 1
},
"open-sse/utils/sseHeartbeat.ts": {
"TS2353": 2
"TS2353": 1
},
"open-sse/utils/stream.ts": {
"TS2353": 2
"TS2353": 1
},
"src/app/api/assess/route.ts": {
"TS2339": 2
"TS2339": 1
},
"src/app/api/cache/route.ts": {
"TS2339": 2
"TS2339": 1
},
"src/app/api/cli-tools/all-statuses/route.ts": {
"TS2339": 2
"TS2339": 1
},
"src/app/api/cli-tools/claude-settings/route.ts": {
"TS2339": 2
"TS2339": 1
},
"src/app/api/cli-tools/cline-settings/route.ts": {
"TS2339": 6
},
"src/app/api/cli-tools/codex-settings/route.ts": {
"TS2345": 3
},
"src/app/api/cli-tools/grok-build-settings/route.ts": {
"TS2304": 2
},
"src/app/api/cli-tools/hermes-agent-settings/route.ts": {
"TS2345": 2
},
"src/app/api/cli-tools/letta-settings/route.ts": {
"TS2339": 2
},
"src/app/api/cli-tools/omp-settings/route.ts": {
"TS2339": 10
},
"src/app/api/cli-tools/qwen-settings/route.ts": {
"TS2322": 2
},
"src/app/api/combos/auto/route.ts": {
"TS2322": 2
},
"src/app/api/combos/test/route.ts": {
"TS2345": 2,
"TS2339": 2
},
"src/app/api/compression/compare/route.ts": {
"TS2345": 2
},
"src/app/api/compression/preview/route.ts": {
"TS2345": 2
},
"src/app/api/context/combos/[id]/route.ts": {
"TS2345": 2
},
"src/app/api/context/combos/route.ts": {
"TS2345": 2
},
"src/app/api/copilot/chat/route.ts": {
"TS2345": 2
},
"src/app/api/guardrails/test/route.ts": {
"TS2554": 2
},
"src/app/api/internal/codex-responses-ws/route.ts": {
"TS2740": 2,
"TS2339": 9
},
"src/app/api/keys/[id]/route.ts": {
"TS2339": 2
},
"src/app/api/local/redis/start/route.ts": {
"TS2339": 2
},
"src/app/api/local/redis/stop/route.ts": {
"TS2339": 2
},
"src/app/api/logs/[id]/route.ts": {
"TS2322": 2
},
"src/app/api/model-capability-overrides/route.ts": {
"TS2339": 2
},
"src/app/api/model-combo-mappings/route.ts": {
"TS2339": 2
},
"src/app/api/models/alias/route.ts": {
"TS2339": 6
},
"src/app/api/models/route.ts": {
"TS2345": 4,
"TS2538": 2
},
"src/app/api/monitoring/health/route.ts": {
"TS2322": 2
},
"src/app/api/oauth/codex/import-token/route.ts": {
"TS2339": 4
},
"src/app/api/oauth/codex/import/route.ts": {
"TS2554": 2,
"TS2353": 2,
"TS2339": 4
},
"src/app/api/oauth/cursor/login/poll/route.ts": {
"TS2554": 2
},
"src/app/api/oauth/kiro/auto-import/route.ts": {
"TS2345": 2
},
"src/app/api/omniroute/route/preview/route.ts": {
"TS2345": 2
},
"src/app/api/playground/presets/[id]/route.ts": {
"TS2339": 4
},
"src/app/api/provider-nodes/validate/route.ts": {
"TS2339": 3
},
"src/app/api/providers/[id]/login/route.ts": {
"TS2739": 2
},
"src/app/api/providers/[id]/models/route.ts": {
"TS2367": 2,
"TS2339": 3,
"TS2322": 3,
"TS2554": 3,
"TS2345": 4
},
"src/app/api/providers/[id]/refresh-cursor/route.ts": {
"TS2352": 2
},
"src/app/api/providers/[id]/refresh/route.ts": {
"TS2345": 2,
"TS2698": 2,
"TS2339": 8
},
"src/app/api/providers/[id]/sync-models/route.ts": {
"TS2345": 2
},
"src/app/api/providers/[id]/test/route.ts": {
"TS2362": 2,
"TS2698": 2
},
"src/app/api/providers/free-onboarding/route.ts": {
"TS2345": 2
},
"src/app/api/providers/health-autopilot/actions/route.ts": {
"TS2339": 2
},
"src/app/api/providers/route.ts": {
"TS2352": 2,
"TS2322": 3,
"TS2345": 4
},
"src/app/api/providers/test-batch/route.ts": {
"TS2345": 5
},
"src/app/api/providers/validate/route.ts": {
"TS2322": 2
},
"src/app/api/providers/volcengine-plan/connect/[sessionId]/cancel/route.ts": {
"TS2739": 2
},
"src/app/api/providers/volcengine-plan/connect/[sessionId]/code/route.ts": {
"TS2739": 2
},
"src/app/api/providers/volcengine-plan/connect/[sessionId]/identity/route.ts": {
"TS2739": 2
},
"src/app/api/providers/volcengine-plan/connect/[sessionId]/resend/route.ts": {
"TS2739": 2
},
"src/app/api/providers/volcengine-plan/connect/[sessionId]/status/route.ts": {
"TS2739": 2
},
"src/app/api/providers/volcengine-plan/connect/route.ts": {
"TS2739": 2
},
"src/app/api/radar/local-model-state/route.ts": {
"TS2339": 5
},
"src/app/api/resilience/model-cooldowns/route.ts": {
"TS2339": 2
},
"src/app/api/services/_shared/installRoute.ts": {
"TS2339": 2
},
"src/app/api/settings/cache-config/route.ts": {
"TS2339": 2,
"TS2322": 2
},
"src/app/api/settings/database/route.ts": {
"src/app/api/cli-tools/codex-settings/route.ts": {
"TS2345": 2
},
"src/app/api/settings/models-dev/route.ts": {
"TS2339": 2
"src/app/api/cli-tools/grok-build-settings/route.ts": {
"TS2304": 1
},
"src/app/api/settings/obsidian/webdav/route.ts": {
"TS2339": 2
"src/app/api/cli-tools/hermes-agent-settings/route.ts": {
"TS2345": 1
},
"src/app/api/settings/proxies/bulk-import/route.ts": {
"TS2345": 2
"src/app/api/cli-tools/letta-settings/route.ts": {
"TS2339": 1
},
"src/app/api/settings/proxy/cloudflare-deploy/route.ts": {
"TS2769": 2,
"TS2322": 3
"src/app/api/cli-tools/omp-settings/route.ts": {
"TS2339": 8
},
"src/app/api/settings/proxy/deno-deploy/route.ts": {
"TS2322": 5
"src/app/api/cli-tools/qwen-settings/route.ts": {
"TS2322": 1
},
"src/app/api/settings/proxy/vercel-deploy/route.ts": {
"TS2322": 4
"src/app/api/combos/auto/route.ts": {
"TS2322": 1
},
"src/app/api/settings/reasoning-routing-rules/[id]/route.ts": {
"TS2339": 2
"src/app/api/combos/test/route.ts": {
"TS2345": 1,
"TS2339": 1
},
"src/app/api/settings/reasoning-routing-rules/route.ts": {
"TS2339": 2
"src/app/api/compression/compare/route.ts": {
"TS2345": 1
},
"src/app/api/settings/reasoning-routing-rules/simulate/route.ts": {
"TS2322": 2,
"TS2339": 2
"src/app/api/compression/preview/route.ts": {
"TS2345": 1
},
"src/app/api/system/env/repair/route.ts": {
"TS2578": 2,
"TS2353": 4
"src/app/api/context/combos/[id]/route.ts": {
"TS2345": 1
},
"src/app/api/system/version/route.ts": {
"TS2769": 2
"src/app/api/context/combos/route.ts": {
"TS2345": 1
},
"src/app/api/tools/agent-bridge/agents/[id]/detected-models/route.ts": {
"TS2769": 2
"src/app/api/copilot/chat/route.ts": {
"TS2345": 1
},
"src/app/api/tools/traffic-inspector/internal/ingest/route.ts": {
"TS1117": 3,
"TS2345": 2
"src/app/api/guardrails/test/route.ts": {
"TS2554": 1
},
"src/app/api/tools/traffic-inspector/ws/route.ts": {
"TS2578": 2
"src/app/api/internal/codex-responses-ws/route.ts": {
"TS2740": 1,
"TS2339": 7
},
"src/app/api/translator/send/route.ts": {
"TS2345": 2,
"TS2322": 2,
"TS2339": 2
"src/app/api/keys/[id]/route.ts": {
"TS2339": 1
},
"src/app/api/translator/translate/route.ts": {
"TS2345": 2,
"TS2322": 2
"src/app/api/local/redis/start/route.ts": {
"TS2339": 1
},
"src/app/api/usage/analytics/route.ts": {
"TS2352": 18
"src/app/api/local/redis/stop/route.ts": {
"TS2339": 1
},
"src/app/api/usage/combo-health-autopilot/route.ts": {
"TS2769": 3
"src/app/api/logs/[id]/route.ts": {
"TS2322": 1
},
"src/app/api/v1/batches/route.ts": {
"TS2339": 2
"src/app/api/model-capability-overrides/route.ts": {
"TS2339": 1
},
"src/app/api/v1/classify/route.ts": {
"TS2322": 2
"src/app/api/model-combo-mappings/route.ts": {
"TS2339": 1
},
"src/app/api/v1/files/[id]/content/route.ts": {
"TS2345": 2
"src/app/api/models/alias/route.ts": {
"TS2339": 5
},
"src/app/api/v1/files/route.ts": {
"TS2339": 2
"src/app/api/models/route.ts": {
"TS2345": 3,
"TS2538": 1
},
"src/app/api/v1/images/edits/route.ts": {
"TS2339": 22,
"TS2322": 5
"src/app/api/monitoring/health/route.ts": {
"TS2322": 1
},
"src/app/api/v1/messages/count_tokens/route.ts": {
"TS2339": 3,
"TS2322": 2
},
"src/app/api/v1/music/generations/route.ts": {
"TS2322": 2,
"TS2345": 2
},
"src/app/api/v1/ocr/route.ts": {
"TS2345": 2
},
"src/app/api/v1/provider-plugin-manifest/route.ts": {
"TS2345": 2
},
"src/app/api/v1/providers/[provider]/embeddings/route.ts": {
"TS2339": 4,
"TS2322": 2
},
"src/app/api/v1/providers/[provider]/images/generations/route.ts": {
"TS2339": 6
},
"src/app/api/v1/rerank/route.ts": {
"src/app/api/oauth/codex/import-token/route.ts": {
"TS2339": 3
},
"src/app/api/v1/segment/route.ts": {
"TS2322": 2
"src/app/api/oauth/codex/import/route.ts": {
"TS2554": 1,
"TS2353": 1,
"TS2339": 3
},
"src/app/api/v1/session-leases/route.ts": {
"TS2339": 5,
"TS2345": 2
"src/app/api/oauth/cursor/login/poll/route.ts": {
"TS2554": 1
},
"src/app/api/v1/speech-to-text/route.ts": {
"TS2353": 2
"src/app/api/oauth/kiro/auto-import/route.ts": {
"TS2345": 1
},
"src/app/api/v1/text-to-speech/[voiceId]/route.ts": {
"TS2353": 2
"src/app/api/omniroute/route/preview/route.ts": {
"TS2345": 1
},
"src/app/api/v1/web/fetch/route.ts": {
"src/app/api/playground/presets/[id]/route.ts": {
"TS2339": 3
},
"src/app/api/provider-nodes/validate/route.ts": {
"TS2339": 2
},
"src/app/api/v1beta/models/route.ts": {
"TS2345": 2,
"TS2538": 2
"src/app/api/providers/[id]/login/route.ts": {
"TS2739": 1
},
"src/app/api/version-manager/restart/route.ts": {
"TS2339": 2
},
"src/app/api/version-manager/start/route.ts": {
"TS2339": 2
},
"src/app/api/version-manager/stop/route.ts": {
"TS2339": 2
},
"src/app/api/webhooks/[id]/route.ts": {
"TS2554": 2
},
"src/app/api/webhooks/[id]/test/route.ts": {
"TS2352": 3
},
"src/app/api/webhooks/route.ts": {
"src/app/api/providers/[id]/models/route.ts": {
"TS2367": 1,
"TS2339": 2,
"TS2322": 2,
"TS2554": 2,
"TS2345": 2
},
"src/lib/db/tierConfig.ts": {
"TS2345": 3
},
"src/lib/monitoring/comboHealthAutopilot.ts": {
"TS2305": 2,
"TS2345": 2
"src/app/api/providers/[id]/refresh-cursor/route.ts": {
"TS2352": 1
},
"src/lib/monitoring/providerHealthAutopilot.ts": {
"TS2352": 5
"src/app/api/providers/[id]/refresh/route.ts": {
"TS2345": 1,
"TS2698": 1,
"TS2339": 6
},
"src/lib/omnirouteStatus.ts": {
"src/app/api/providers/[id]/sync-models/route.ts": {
"TS2345": 1
},
"src/app/api/providers/[id]/test/route.ts": {
"TS2362": 1,
"TS2698": 1
},
"src/app/api/providers/free-onboarding/route.ts": {
"TS2345": 1
},
"src/app/api/providers/health-autopilot/actions/route.ts": {
"TS2339": 1
},
"src/app/api/providers/route.ts": {
"TS2352": 1,
"TS2322": 2,
"TS2558": 2
"TS2345": 3
},
"src/lib/providerModels/managedModelImport.ts": {
"TS2352": 5
},
"src/lib/proxySubscription/parse.ts": {
"src/app/api/providers/test-batch/route.ts": {
"TS2345": 4
},
"src/lib/quota/quotaAnalytics.ts": {
"src/app/api/providers/validate/route.ts": {
"TS2322": 1
},
"src/app/api/providers/volcengine-plan/connect/[sessionId]/cancel/route.ts": {
"TS2739": 1
},
"src/app/api/providers/volcengine-plan/connect/[sessionId]/code/route.ts": {
"TS2739": 1
},
"src/app/api/providers/volcengine-plan/connect/[sessionId]/identity/route.ts": {
"TS2739": 1
},
"src/app/api/providers/volcengine-plan/connect/[sessionId]/resend/route.ts": {
"TS2739": 1
},
"src/app/api/providers/volcengine-plan/connect/[sessionId]/status/route.ts": {
"TS2739": 1
},
"src/app/api/providers/volcengine-plan/connect/route.ts": {
"TS2739": 1
},
"src/app/api/radar/local-model-state/route.ts": {
"TS2339": 4
},
"src/app/api/resilience/model-cooldowns/route.ts": {
"TS2339": 1
},
"src/app/api/services/_shared/installRoute.ts": {
"TS2339": 1
},
"src/app/api/settings/cache-config/route.ts": {
"TS2339": 1,
"TS2322": 1
},
"src/app/api/settings/database/route.ts": {
"TS2345": 1
},
"src/app/api/settings/models-dev/route.ts": {
"TS2339": 1
},
"src/app/api/settings/obsidian/webdav/route.ts": {
"TS2339": 1
},
"src/app/api/settings/proxies/bulk-import/route.ts": {
"TS2345": 1
},
"src/app/api/settings/proxy/cloudflare-deploy/route.ts": {
"TS2769": 1,
"TS2322": 2
},
"src/app/api/settings/proxy/deno-deploy/route.ts": {
"TS2322": 4
},
"src/app/api/settings/proxy/vercel-deploy/route.ts": {
"TS2322": 3
},
"src/app/api/settings/reasoning-routing-rules/[id]/route.ts": {
"TS2339": 1
},
"src/app/api/settings/reasoning-routing-rules/route.ts": {
"TS2339": 1
},
"src/app/api/settings/reasoning-routing-rules/simulate/route.ts": {
"TS2322": 1,
"TS2339": 1
},
"src/app/api/system/env/repair/route.ts": {
"TS2578": 1,
"TS2353": 3
},
"src/app/api/system/version/route.ts": {
"TS2769": 1
},
"src/app/api/tools/agent-bridge/agents/[id]/detected-models/route.ts": {
"TS2769": 1
},
"src/app/api/tools/traffic-inspector/internal/ingest/route.ts": {
"TS1117": 2,
"TS2345": 1
},
"src/app/api/tools/traffic-inspector/ws/route.ts": {
"TS2578": 1
},
"src/app/api/translator/send/route.ts": {
"TS2345": 1,
"TS2322": 1,
"TS2339": 1
},
"src/app/api/translator/translate/route.ts": {
"TS2345": 1,
"TS2322": 1
},
"src/app/api/usage/analytics/route.ts": {
"TS2352": 15
},
"src/app/api/usage/combo-health-autopilot/route.ts": {
"TS2769": 2
},
"src/lib/quota/quotaResetTimers.ts": {
"TS2769": 3
"src/app/api/v1/batches/route.ts": {
"TS2339": 1
},
"src/lib/usage/comboForecast.ts": {
"TS2345": 2
"src/app/api/v1/classify/route.ts": {
"TS2322": 1
},
"src/lib/usage/comboHealth.ts": {
"TS2345": 2
"src/app/api/v1/files/[id]/content/route.ts": {
"TS2345": 1
},
"src/lib/usage/comboScoringInspector.ts": {
"TS2352": 2,
"TS2741": 2
"src/app/api/v1/files/route.ts": {
"TS2339": 1
},
"src/lib/usage/providerWindowCosts.ts": {
"TS2322": 3,
"TS2558": 6,
"TS2339": 15,
"TS2345": 2
"src/app/api/v1/images/edits/route.ts": {
"TS2339": 18,
"TS2322": 4
},
"src/lib/vscode/modelPresentation.ts": {
"TS2554": 2
"src/app/api/v1/messages/count_tokens/route.ts": {
"TS2339": 2,
"TS2322": 1
},
"src/lib/ws/handshake.ts": {
"src/app/api/v1/music/generations/route.ts": {
"TS2322": 1,
"TS2345": 1
},
"src/app/api/v1/ocr/route.ts": {
"TS2345": 1
},
"src/app/api/v1/provider-plugin-manifest/route.ts": {
"TS2345": 1
},
"src/app/api/v1/providers/[provider]/embeddings/route.ts": {
"TS2339": 3,
"TS2322": 1
},
"src/app/api/v1/providers/[provider]/images/generations/route.ts": {
"TS2339": 5
},
"src/app/api/v1/rerank/route.ts": {
"TS2339": 2
},
"src/mitm/detection/index.ts": {
"TS2741": 2
"src/app/api/v1/segment/route.ts": {
"TS2322": 1
},
"src/mitm/inspector/httpProxyServer.ts": {
"src/app/api/v1/session-leases/route.ts": {
"TS2339": 4,
"TS2345": 1
},
"src/app/api/v1/speech-to-text/route.ts": {
"TS2353": 1
},
"src/app/api/v1/text-to-speech/[voiceId]/route.ts": {
"TS2353": 1
},
"src/app/api/v1/web/fetch/route.ts": {
"TS2339": 1
},
"src/app/api/v1beta/models/route.ts": {
"TS2345": 1,
"TS2538": 1
},
"src/app/api/version-manager/restart/route.ts": {
"TS2339": 1
},
"src/app/api/version-manager/start/route.ts": {
"TS2339": 1
},
"src/app/api/version-manager/stop/route.ts": {
"TS2339": 1
},
"src/app/api/webhooks/[id]/route.ts": {
"TS2554": 1
},
"src/app/api/webhooks/[id]/test/route.ts": {
"TS2352": 2
},
"src/app/api/webhooks/route.ts": {
"TS2554": 1,
"TS2345": 1
},
"src/lib/db/tierConfig.ts": {
"TS2345": 2
},
"src/lib/monitoring/comboHealthAutopilot.ts": {
"TS2305": 1,
"TS2345": 1
},
"src/lib/monitoring/providerHealthAutopilot.ts": {
"TS2352": 4
},
"src/lib/omnirouteStatus.ts": {
"TS2322": 1,
"TS2558": 1
},
"src/lib/providerModels/managedModelImport.ts": {
"TS2352": 4
},
"src/lib/proxySubscription/parse.ts": {
"TS2345": 3
},
"src/lib/quota/quotaAnalytics.ts": {
"TS2769": 1
},
"src/lib/quota/quotaResetTimers.ts": {
"TS2769": 2
},
"src/shared/schemas/cliCatalog.ts": {
"TS2554": 3
"src/lib/usage/comboForecast.ts": {
"TS2345": 1
},
"_relax_velocity_2026_08_30": "per-file TS diagnostic counts raised by 20% (289 → 455); velocity phase, see quality-baseline.json _policy."
"src/lib/usage/comboHealth.ts": {
"TS2345": 1
},
"src/lib/usage/comboScoringInspector.ts": {
"TS2352": 1,
"TS2741": 1
},
"src/lib/usage/providerWindowCosts.ts": {
"TS2322": 2,
"TS2558": 5,
"TS2339": 12,
"TS2345": 1
},
"src/lib/vscode/modelPresentation.ts": {
"TS2554": 1
},
"src/lib/ws/handshake.ts": {
"TS2339": 1
},
"src/mitm/detection/index.ts": {
"TS2741": 1
},
"src/mitm/inspector/httpProxyServer.ts": {
"TS2769": 1
},
"src/shared/schemas/cliCatalog.ts": {
"TS2554": 2
}
}

View File

@@ -3,6 +3,7 @@
"_justifications": {
"@testing-library/dom": "Peer dep obrigatoria de @testing-library/react v16 (adicionada no PR #11224); Refs #9985.",
"@testing-library/user-event": "Utilitario oficial do ecossistema testing-library para testes de UI (adicionada no PR #11224); Refs #9985.",
"babel-plugin-react-compiler": "Official React Compiler Babel plugin (facebook/react, MIT). Required peer of Next.js 16 `reactCompiler: true`; Next declares it optional (`*`) and does not auto-install. Added by PR #11783 / issue #67.",
"eslint-plugin-react-hooks": "React Hooks lint rules (set-state-in-effect, immutability, refs, purity) pinned at 7.0.1 by the release/v3.8.51 cycle; the 224 findings it raised are tracked in #11924. Refs #11924."
},
"allowed": [
@@ -44,6 +45,7 @@
"ajv",
"ajv-formats",
"axios",
"babel-plugin-react-compiler",
"bcryptjs",
"better-sqlite3",
"bottleneck",

View File

@@ -2476,14 +2476,6 @@
"count": 2
}
},
"tests/theoldllm-stress.test.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 10
},
"@typescript-eslint/no-unused-vars": {
"count": 1
}
},
"tests/translator/testFromFile.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 3
@@ -3373,7 +3365,7 @@
},
"tests/unit/combo-routing-engine.test.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 267
"count": 268
}
},
"tests/unit/combo-same-provider-cascade.test.ts": {

View File

@@ -1,4 +1,8 @@
{
"_rebaseline_2026_09_02_v3851_merged_growth_basereds": "Base-red drain: the 2026-09-02 merge waves (#12359-#12404, #11461, #11513, #12423) each grew a frozen file at an existing chokepoint, but the rebaseline was computed in the throwaway combined validation worktree and never reached any PR branch, so the growth landed while the caps did not and check-file-size went red on the release tip. Recorded here against the merged state: src/app/api/providers/[id]/models/route.ts 2429->2432 (#12389 gemini-business listing on top of #11461's 2429); src/app/api/v1/models/catalog.ts 2066->2075 (#12381 self-aliased canonical rows + #12403 NUL escape); src/lib/db/core.ts 1740->1745 (#12394 busy_timeout ordering + probe classification); src/sse/handlers/chat.ts 2375->2384 (#12360 breaker result classification + #12365 shadowed-node error); src/sse/services/auth.ts 3420->3427 (#12375 backoffLevel tie-break); open-sse/handlers/imageGeneration.ts 3255->3259 (#11513 uc-image branch + #12423 uc-image id scoping); open-sse/utils/proxyFetch.ts 1261->1271 (#12380 hasAmbientProxyContext()); tests/unit/image-generation-handler.test.ts 2110->2133 (#12362 regression coverage); tests/unit/sse-auth.test.ts 1697->1729 (#12375 regression coverage). No cap is raised beyond the merged LOC; every other entry is untouched.",
"_rebaseline_2026_09_02_11513_uc_provider": "PR #11513 (arminanton, feat/uc-native-standalone) own growth: open-sse/handlers/imageGeneration.ts 3243->3255 (+12) — the uc-image format branch for the UC persona provider's image surface. Additive at the existing per-format chokepoint, same rationale as _rebaseline_2026_09_02_11461_maxai_tls_profile.",
"_rebaseline_2026_09_02_11461_maxai_tls_profile": "PR #11461 (arminanton, feat/maxai-provider) own growth, three files at existing per-provider chokepoints: open-sse/utils/proxyFetch.ts 1241->1261 (+20, the TLS_PROVIDER_PROFILE map giving MaxAI a Windows/firefox_150 impersonation profile instead of the tlsClient chrome_124/macos default); open-sse/handlers/imageGeneration.ts 3231->3243 (+12, the maxai-image format branch); src/app/api/providers/[id]/models/route.ts 2381->2429 (+48, live model listing via maxaiModels). Additive data, same no-split rationale as _rebaseline_2026_08_20_10531_freebuff_provider.",
"_rebaseline_2026_09_02_11460_flat_rate_estimates": "PR #11460 (xiaoyaner0201, fix/11459-cc-cost-estimates) own growth: src/app/(dashboard)/dashboard/costs/CostOverviewTab.tsx 1283->1319 (+36) — the flat-rate estimate labelling and the includeFlatRateEstimates opt-in on the Costs dashboard. #11460 merged first so this ratchet re-tightening measures the real post-merge LOC; the cap still drops 2002->1319 (-683) versus the 2026-08-10 +30% loosening this PR reverses. Same own-growth rationale as _rebaseline_2026_08_20_10531_freebuff_provider.",
"_rebaseline_2026_08_31_chatgpt_web_v4_vendor": "Pinned MIT vendor refresh from codex-chatgpt-web 0.1.16 to v4.0.6 (commit 09877fa21ffdbf20979623ef501046fc02a750d7). browser-worker.ts is preserved as the reviewed upstream browser protocol implementation; splitting the vendored file would destroy source parity and make future security/liveness updates unauditable. OmniRoute-specific DATA_DIR, Docker CDP, credential-marker, and XML decoding adaptations are covered by the ChatGPT Web Codex focused suite.",
"_rebaseline_2026_08_20_10531_freebuff_provider": "PR #10531 (adrianaryaputra, feat/freebuff-provider-support, closes #6793) own growth: src/shared/constants/providers/apikey/gateways.ts 1283->1298 (+15, the freebuff APIKEY_PROVIDERS_GATEWAYS catalog entry, additive data at the existing registry chokepoint, same god-file no-split rationale as prior gateways.ts rebaselines) and src/app/(dashboard)/dashboard/providers/[id]/components/modals/AddApiKeyModal.tsx 1062->1067 (+5, freebuff credential placeholder/hint at the existing per-provider switch chokepoint). Covered by tests/unit/freebuff-provider.test.ts (9/9 passing).",
"_rebaseline_2026_08_31_12212_openapi_generated": "PR #12212 (docs audit follow-up nº 3): src/app/docs/lib/openapi.generated.ts 171->1347 — the module is emitted by scripts/docs/gen-openapi-module.mjs from docs/openapi.yaml, and the spec now documents all 692 implemented routes (was 276), so the generated output grew with the spec. Frozen at the generator output size; shrink by slimming the spec, never by hand-editing the generated module. Covered by tests/unit/openapi-security-tiers.test.ts (6/6) and the check:api-docs-refs gate (692/692 paths with a real route).",
@@ -86,7 +90,7 @@
"_rebaseline_2026_06_20_reviewprs_mine_r2_filesize": "Reconciliacao file-size pos-lote /review-prs 'apenas minhas' r2: dois frozen cresceram cumulativamente sem bump (cada PR media OK na sua base, mas o crescimento empilhou acima do frozen no tip de merge; o fast-path do release nao roda check:file-size, so release->main). (1) src/shared/constants/pricing.ts 1620->1623 (+3 = linhas de pricing Claude Code (cc) do #4440, sobre o 1620 que o #4447 ja setara para gpt-4.1-mini/nano + o3/o4-mini). (2) open-sse/executors/base.ts 1399->1407 (+8 = handling granular de reasoning_effort para Claude no Copilot do #4443). Ambos dados/wiring coesos nos chokepoints existentes; nao extraiveis. Cobertos por tests/unit (claude-code pricing / base-executor-sanitize-effort + github-claude-reasoning-effort-granular).",
"_rebaseline_2026_06_22_4647_opencode_go_deepseek": "PR #4647 (DevEstacion/opencode-go DeepSeek V4 Pro effort variants) review feedback: open-sse/executors/base.ts 1407->1414 (+7 = supportsMaxEffortForProvider now opt-ins opencode-go+deepseek so the literal 'max' effort survives the post-transformReasoningEffortForProvider pass — without this, max was silently rewritten to xhigh (OmniRoute's internal top tier) and the opencode-go upstream rejected it. The check is scoped to opencode-go deliberately to preserve the OpenRouter-DeepSeek inverse invariant (pi#4055, asserted by base-executor-sanitize-effort test:OpenRouter DeepSeek normalizes max -> xhigh). The +5 explanatory comment is required: a naive maintainer could otherwise broaden the check to all deepseek models and break the OpenRouter contract. Cohesive at the existing supportsMaxEffortForProvider chokepoint, next to the Claude/CC-compatible check; not extractable. Covered by tests/unit/base-executor-sanitize-effort.test.ts (3 new opencode-go deepseek cases).",
"_rebaseline_2026_06_30_v3842_release_basetsl_5480": "v3.8.42 cycle-close file-size reconciliation: open-sse/executors/base.ts 1497->1500 (+3 net = #5480 'gate claude adaptive thinking defaults' — the adaptive-thinking injection is now gated behind the operator's thinking-budget config at the existing transform chokepoint, so default/passthrough no longer force-injects). Cohesive at the existing reasoning/thinking transform site; not extractable. The fast-path release gate (PR->release/**) does not run check:file-size, so this surfaced only on the release PR (PR->main). Covered by tests/unit/base-thinking-budget-config-5312.test.ts + the #5480 gate test.",
"_rebaseline_2026_06_20_4023_web_cookie_noauth_validation": "PR #4023 (oyi77) own growth: src/lib/providers/validation.ts 4450->4518 (+68 = a new validateWebCookieProvider that probes the provider's /models endpoint — 401/403 => AUTH_007 SESSION_EXPIRED, any other status => valid session, empty cookie => invalid, provider-not-in-registry => unsupported — plus a local STANDARD_USER_AGENT const for the probe). Cohesive validator at the validateProviderApiKey dispatch; not extractable. Covered by tests/unit/provider-validation-web-cookie-auth007.test.ts. Heavily curated on merge — the PR's branch was badly stale-based (squash-base-stale), so its tree was DESTRUCTIVE: providers/index.ts deleted live providers openadapter/dit/tokenrouter (added by #4313) and the executor/base.ts edits reverted release fixes (#4037 duckduckgo host, theoldllm gpt5 models, base.ts fetch-start-timeout). Only the purely-additive validation feature was kept (validation.ts validateWebCookieProvider + errorCodes AUTH_007 + the test). Dropped: 5 malformed new registry entries (used non-RegistryEntry fields defaultModel/auth + referenced non-existent executors -> tsc TS2353), the destructive providers/index.ts + executor reverts, the unrelated pr-*.sh automation scripts, and evals/types.ts (belongs to the deferred evals modularization #4422). Also removed the PR's fragile 'Phase 2' executor probe (ran a live upstream chat during validation + classified any 'auth'-containing error as SESSION_EXPIRED) and rewrote the test to install its fetch mock before module load (the original mocked too late and silently hit live chatgpt.com).",
"_rebaseline_2026_06_20_4023_web_cookie_noauth_validation": "PR #4023 (oyi77) own growth: src/lib/providers/validation.ts 4450->4518 (+68 = a new validateWebCookieProvider that probes the provider's /models endpoint — 401/403 => AUTH_007 SESSION_EXPIRED, any other status => valid session, empty cookie => invalid, provider-not-in-registry => unsupported — plus a local STANDARD_USER_AGENT const for the probe). Cohesive validator at the validateProviderApiKey dispatch; not extractable. Covered by tests/unit/provider-validation-web-cookie-auth007.test.ts. Heavily curated on merge — the PR's branch was badly stale-based (squash-base-stale), so its tree was DESTRUCTIVE: providers/index.ts deleted live providers openadapter/dit/tokenrouter (added by #4313) and the executor/base.ts edits reverted release fixes (#4037 duckduckgo host, no-auth gpt5 model aliases, base.ts fetch-start-timeout). Only the purely-additive validation feature was kept (validation.ts validateWebCookieProvider + errorCodes AUTH_007 + the test). Dropped: 5 malformed new registry entries (used non-RegistryEntry fields defaultModel/auth + referenced non-existent executors -> tsc TS2353), the destructive providers/index.ts + executor reverts, the unrelated pr-*.sh automation scripts, and evals/types.ts (belongs to the deferred evals modularization #4422). Also removed the PR's fragile 'Phase 2' executor probe (ran a live upstream chat during validation + classified any 'auth'-containing error as SESSION_EXPIRED) and rewrote the test to install its fetch mock before module load (the original mocked too late and silently hit live chatgpt.com).",
"_rebaseline_2026_06_20_1308_model_lockout_honors_reset": "port from 9router#1308 own growth: open-sse/services/accountFallback.ts 1731->1752 (+21 = the new exported pure helper selectLockoutCooldownMs + its doc comment — picks the parsed upstream reset as the model-lockout exactCooldownMs when it exceeds the base cooldown, e.g. Antigravity \"Resets in 160h\", else preserves the existing 0/base behavior) and open-sse/executors/antigravity.ts 1680->1686 (this PR +1 = parseRetryFromErrorMessage regex `reset` -> `resets?` so plural \"Resets in 160h27m24s\" matches, plus a comment line; frozen set to the SUM 1686 with the concurrent #1944 which adds +5 at the disjoint passthroughFields region of the same file, so either merge order passes — pair-file rule). The combo lockout call sites in combo.ts now pass selectLockoutCooldownMs(cooldownMs, mlSettings) instead of always base/exponential, so an exhausted model honors the real upstream reset instead of being retried within minutes. Both edits are cohesive at the existing lockout/parse chokepoints; the helper is its own pure function (not extractable further). Covered by tests/unit/combo-model-lockout-honors-reset-1308.test.ts.",
"_rebaseline_2026_06_20_1944_antigravity_strip_output_config": "port from 9router#1944: open-sse/executors/antigravity.ts frozen set to the measured cumulative 1687 of two concurrent PRs that touch disjoint regions of this file, so either merge order passes (pair-file rule). #1944 adds +6 at the envelope passthroughFields destructuring (~line 759: drop output_config/output_format — Anthropic/Claude-Code-only fields that Google's Cloud Code envelope rejects with `400 Unknown name \"output_config\"`, which broke every Claude model on Antigravity); #1308 adds +1 at parseRetryFromErrorMessage (~line 889: regex reset->resets?). Base 1680 + 6 + 1 = 1687 (re-measured on the real merge tip — the earlier 1686 estimate was off by one). Both edits are cohesive at their chokepoints; not extractable. Covered by tests/unit/antigravity-strip-output-config-1944.test.ts.",
"_rebaseline_2026_06_22_779_copilot_agent_antigravity_parity": "port from 9router#779 (@lukmanfauzie): open-sse/executors/antigravity.ts 1696->1721 (+25 = MAX_ANTIGRAVITY_OUTPUT_TOKENS constant + doc + final cap branch inside applyAntigravityGenerationDefaults + test-only export). Hard-caps generationConfig.maxOutputTokens at 16384 so VS Code GitHub Copilot Chat in Agent mode (which routinely requests 32K65K tokens) stops triggering Antigravity upstream HTTP 400 'Invalid Argument'. The remaining items in upstream #779 (recursive JSON-schema sanitization, sanitizeFunctionName, $comment/enumDescriptions, functionResponse name resolution, VALIDATED mode) are already covered by OmniRoute's existing geminiHelper/geminiToolsSanitizer/openai-to-gemini pipeline — the cap is the only delta missing here. Cohesive guard at the existing generation-defaults chokepoint; not extractable. Covered by tests/unit/copilot-agent-antigravity-parity.test.ts.",
@@ -196,43 +200,33 @@
"_rebaseline_2026_08_24_video_bridge_fu01_fu03_fu04_result_cache_tests": "PRs #11362 (FU-01 cache hardening) + #11382 (FU-03 visual dedup policy identity) + #11383 (FU-04 focused analysis mode) own test growth: videoBridgeResultCache.test.ts <1000->1040, +40 (sum of three stacked PRs boarded together in the same merge-batch, each adding its own cache-identity assertions on the shared result-cache seam). Owner pre-authorized rebaseline for legitimate PR growth (2026-08-19 directive).",
"_rebaseline_basered_codebuddy_cn": "Base-red fix (#4664 CodeBuddy CN): oauth-providers-config.test.ts 867->870 (+3) to align the EXPECTED provider list/config with the codebuddy-cn provider that #4664 added to the registry without updating this test (it asserts 'exactly once').",
"_rebaseline_pr4613_compatible_provider_groups": "Reconcile #4613 already-merged growth: providers-page-utils.test.ts 1004->1052 (+48, buildCompatibleProviderGroups partition unit test). Fast-gate PR->release does not run check:file-size, so this surfaced post-merge.",
"tests/integration/chat-pipeline.test.ts": 2493,
"tests/integration/chatcore-compression-integration.test.ts": 1738,
"tests/integration/skills-pipeline.test.ts": 1211,
"tests/unit/account-fallback-service.test.ts": 2439,
"tests/unit/adobe-firefly.test.ts": 1773,
"tests/unit/batch_api.test.ts": 2066,
"tests/unit/cc-compatible-provider.test.ts": 1899,
"tests/unit/chatcore-translation-paths.test.ts": 4487,
"tests/unit/combo-routing-engine.test.ts": 5393,
"tests/unit/db-migration-runner.test.ts": 2339,
"tests/unit/deepseek-web.test.ts": 1704,
"tests/unit/executor-antigravity.test.ts": 1713,
"tests/unit/executor-codex.test.ts": 2090,
"tests/unit/executor-default-base.test.ts": 2370,
"tests/unit/grok-web.test.ts": 3802,
"tests/unit/image-generation-handler.test.ts": 3166,
"tests/unit/model-sync-route.test.ts": 1586,
"tests/unit/models-catalog-route.test.ts": 2553,
"tests/unit/perplexity-web.test.ts": 2115,
"tests/unit/provider-models-route.test.ts": 2788,
"tests/unit/provider-validation-specialty.test.ts": 4656,
"tests/unit/providers-page-utils.test.ts": 1726,
"tests/unit/response-sanitizer.test.ts": 1659,
"tests/unit/route-edge-coverage.test.ts": 1936,
"tests/unit/search-handler-extended.test.ts": 1671,
"tests/unit/sse-auth.test.ts": 2512,
"tests/unit/stream-utils.test.ts": 3814,
"tests/unit/token-refresh-service.test.ts": 2150,
"tests/unit/translator-openai-responses-req.test.ts": 1863,
"tests/unit/translator-openai-to-gemini.test.ts": 2531,
"tests/unit/translator-openai-to-kiro.test.ts": 1990,
"tests/unit/translator-resp-gemini-to-openai.test.ts": 1925,
"tests/unit/usage-service-hardening.test.ts": 2314,
"tests/unit/vscode-token-routes.test.ts": 1960,
"tests/unit/guardrails/videoBridgeResultCache.test.ts": 1248,
"tests/unit/reasoning-cache.test.ts": 1616,
"tests/unit/chatgpt-web.test.ts": 4911
"tests/integration/chat-pipeline.test.ts": 1644,
"tests/unit/account-fallback-service.test.ts": 2008,
"tests/unit/batch_api.test.ts": 1345,
"tests/unit/cc-compatible-provider.test.ts": 1225,
"tests/unit/chatcore-translation-paths.test.ts": 3447,
"tests/unit/chatgpt-web.test.ts": 4911,
"tests/unit/combo-routing-engine.test.ts": 3625,
"tests/unit/db-migration-runner.test.ts": 1509,
"tests/unit/executor-codex.test.ts": 1465,
"tests/unit/executor-default-base.test.ts": 1632,
"tests/unit/grok-web.test.ts": 2437,
"tests/unit/image-generation-handler.test.ts": 2133,
"tests/unit/models-catalog-route.test.ts": 1652,
"tests/unit/perplexity-web.test.ts": 1384,
"tests/unit/provider-models-route.test.ts": 1783,
"tests/unit/provider-validation-specialty.test.ts": 2912,
"tests/unit/reasoning-cache.test.ts": 1291,
"tests/unit/route-edge-coverage.test.ts": 1244,
"tests/unit/sse-auth.test.ts": 1729,
"tests/unit/stream-utils.test.ts": 2517,
"tests/unit/token-refresh-service.test.ts": 1407,
"tests/unit/translator-openai-responses-req.test.ts": 1470,
"tests/unit/translator-openai-to-gemini.test.ts": 1625,
"tests/unit/translator-openai-to-kiro.test.ts": 1275,
"tests/unit/translator-resp-gemini-to-openai.test.ts": 1234,
"tests/unit/usage-service-hardening.test.ts": 1487,
"tests/unit/vscode-token-routes.test.ts": 1267
},
"_rebaseline_2026_06_09": "Re-baseline consciente pre-release v3.8.19: 9 arquivos cresceram durante o ciclo (features mergeadas: RequestLoggerV2 +281 request-logger rework, stream +101, combo +73, chatCore +45, catalog +32 fable-5/catalog-flag, callLogs +4, accountFallback +2, usageHistory novo 840) + core.ts +7 (fix resetAllDbModuleState, PR 3536). A catraca segue valendo destes valores — proximo crescimento falha. Decisao: encolher (esp. RequestLoggerV2/chatCore) e a issue #3501 ficam para o ciclo seguinte.",
"_rebaseline_2026_06_11_phase1f": "Phase 1f (#3501): ProviderDetailPageClient.tsx 4948→4062 (-886 LOC); 3 novos hooks extraídos. useProviderConnections.ts=954 acima do cap=800 — justificado: extração direta do god-component (zero lógica nova), própria redução do cliente supera o custo. useProviderSettings.ts=263 e useProviderModels.ts=154 já abaixo do cap.",
@@ -367,139 +361,96 @@
"_rebaseline_2026_07_24_responses_toolcalls_log_summary": "hartmark, fix/responses-tool-calls-log-summary own growth: open-sse/translator/response/openai-responses.ts 1163->1174 (+11). closeToolCall() now also writes the completed tool call into the shared state.toolCalls Map (already populated by the openai-to-claude / claude-to-openai / gemini-to-openai response translators) so stream.ts's completion-log summary builder (which reads state.toolCalls, not this translator's own funcCallIds/funcNames/funcArgsBuf bookkeeping) reports finish_reason \"tool_calls\" and message.tool_calls for openai->openai-responses translated streams instead of always logging \"stop\" with no tool_calls — the actual client-facing SSE events were already correct; only the persisted call-log summary was wrong. Irreducible call-site addition at the existing tool-call-close chokepoint. Covered by the new regression test in tests/unit/translator-resp-openai-responses.test.ts.",
"_rebaseline_2026_07_25_8476_combo_input_bound_homogeneous_scope": "PR #8476 (herjarsa, fix/8375-8459-combo-image-fixes, #8375) own growth: open-sse/services/combo.ts 3642->3679 (+37 net: +29 the PR's own isInputBoundFailure short-circuit for deterministic context_length_exceeded/context_window_exceeded failures, +8 a /green-prs pre-merge fix scoping that short-circuit to homogeneous remainders only — the shipped code fired unconditionally on ANY target, regressing the intentional heterogeneous-combo fallback #6637/isContextOverflow400 protects, exactly as flagged by this PR's own review evidence but never actually implemented in the branch). The fix compares orderedTargets[i+1..] modelStr against the failing target's modelStr at the existing executeTarget dispatch chokepoint (mirrors the sameProviderNext precedent a few lines below) — irreducible call-site wiring, not extractable without hiding the dispatch boundary. Covered by tests/unit/combo-input-bound-failure-8375.test.ts (homogeneous pool still short-circuits) and the new tests/unit/combo-input-bound-heterogeneous-8375.test.ts (heterogeneous combo now correctly falls through to the larger-context target).",
"_rebaseline_2026_07_25_adobe_firefly_reference_images": "Follow-up to #8006: storage upload + referenceBlobs for image/video and /v1/images/edits dispatch. adobeFireflyClient.ts 1958->2317 (+upload helpers, extract sources, resolve blob ids). Note: 2317 not 2316 — check-file-size.mjs counts LOC via split(\"\\n\").length (counts the trailing-newline empty element), which is 1 higher than `wc -l` on a file ending in \\n; the PR's original entry (2316) was measured with wc -l and undercounted by 1 against the actual gate.",
"_rebaseline_pr1043_minimax_tts": "Upstream port decolua/9router#1043 (toanalien) own growth: audioSpeech.ts 965->1061 (+96). Adds MiniMax T2A v2 TTS dispatch (handleMinimaxSpeech + hexToBytes helper) — provider entry was already in audioRegistry (format: minimax-tts) but no handler existed, falling through to the OpenAI-compatible default that fails (T2A has custom shape + hex-encoded audio + base_resp envelope). New branch sits next to the other inline provider branches (xiaomi-mimo, coqui, tortoise, aws-polly) — extracting would just create indirection. Covered by tests/unit/minimax-tts-1043.test.ts (3 tests, GREEN: success, base_resp error, invalid-hex).",
"_rebaseline_pr4592_exclude_exhausted_auto": "Reconcile #4592 already-merged growth: combo.ts 2991->3036 (+45, terminal-status quota-cutoff exclusion in buildAutoCandidates + opt-in gate). Fast-gate PR->release does not run check:file-size.",
"open-sse/executors/antigravity.ts": 2384,
"open-sse/executors/base.ts": 2559,
"open-sse/executors/codex.ts": 2438,
"open-sse/executors/cursor.ts": 2439,
"open-sse/executors/deepseek-web.ts": 1791,
"open-sse/executors/grok-web.ts": 1629,
"open-sse/executors/muse-spark-web.ts": 2192,
"open-sse/handlers/chatCore.ts": 7895,
"open-sse/handlers/imageGeneration.ts": 4838,
"open-sse/handlers/responseSanitizer.ts": 1760,
"open-sse/handlers/search.ts": 2397,
"open-sse/handlers/videoGeneration.ts": 1659,
"open-sse/mcp-server/schemas/tools.ts": 2423,
"open-sse/mcp-server/server.ts": 2259,
"open-sse/mcp-server/tools/advancedTools.ts": 1748,
"open-sse/services/accountFallback.ts": 3086,
"open-sse/services/adobeFireflyBrowserLogin.ts": 2126,
"open-sse/services/adobeFireflyClient.ts": 4679,
"open-sse/services/adobeFireflySession.ts": 1565,
"open-sse/services/claudeCodeCompatible.ts": 1876,
"open-sse/services/combo.ts": 5691,
"open-sse/services/compression/strategySelector.ts": 1655,
"open-sse/services/compression/engines/ccr/index.ts": 1229,
"_rebaseline_2026_08_22_11084_ccr_caller_gate": "PR #11084 (HouMinXi) own growth: open-sse/services/compression/engines/ccr/index.ts 1000->1024 (first listing — the engine was unlisted and drifted just over the 1000 cap; +24 are the callerSupportsCcrRetrieve gate that skips replacement entirely for callers without the retrieve tool, closing the stranded-prompt incident measured in production). Covered by tests/unit/compression/ccr-non-mcp-full-prompt-loss-7746.test.ts. Owner pre-authorized baseline bumps 2026-08-22.",
"open-sse/services/contextManager.ts": 1202,
"_rebaseline_2026_08_22_11113_purify_system_first": "PR #11113 (ggdayup) own growth: open-sse/services/contextManager.ts 1000->1001 (+1, purifyHistory merges the compression notice into the leading system message instead of splicing a second one mid-array — live-confirmed TokenRouter 400s; the +1 is the merge-into-leading branch, not extractable). Covered by tests/unit/context-manager-purify-system-first.test.ts. Owner pre-authorized baseline bumps 2026-08-22.",
"open-sse/services/rateLimitManager.ts": 1821,
"open-sse/translator/response/openai-responses.ts": 1983,
"open-sse/utils/cursorAgentProtobuf.ts": 2348,
"open-sse/utils/stream.ts": 4508,
"src/app/(dashboard)/dashboard/HomePageClient.tsx": 2165,
"src/app/(dashboard)/dashboard/analytics/ComboHealthTab.tsx": 1608,
"src/app/(dashboard)/dashboard/api-manager/ApiManagerPageClient.tsx": 4863,
"src/app/(dashboard)/dashboard/cache/media/MediaPageClient.tsx": 1665,
"src/app/(dashboard)/dashboard/combos/page.tsx": 7337,
"src/app/(dashboard)/dashboard/costs/CostOverviewTab.tsx": 2002,
"src/app/(dashboard)/dashboard/costs/quota-share/components/PoolWizard.tsx": 1595,
"src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.tsx": 4080,
"src/app/(dashboard)/dashboard/health/page.tsx": 1817,
"src/app/(dashboard)/dashboard/providers/[id]/components/modals/EditConnectionModal.tsx": 2066,
"src/app/(dashboard)/dashboard/providers/page.tsx": 3033,
"src/app/(dashboard)/dashboard/runtime/RuntimePageClient.tsx": 1874,
"src/app/(dashboard)/dashboard/settings/components/PricingTab.tsx": 1590,
"src/app/(dashboard)/dashboard/settings/components/ProxyRegistryManager.tsx": 2294,
"src/app/(dashboard)/dashboard/settings/components/ResilienceTab.tsx": 1752,
"src/app/(dashboard)/dashboard/settings/components/RoutingTab.tsx": 2542,
"src/app/(dashboard)/dashboard/settings/components/SystemStorageTab.tsx": 2454,
"src/app/(dashboard)/dashboard/usage/components/BudgetTab.tsx": 1604,
"src/app/(dashboard)/dashboard/usage/components/EvalsTab.tsx": 3351,
"src/app/(dashboard)/dashboard/usage/components/ProviderLimits/index.tsx": 1746,
"src/app/api/providers/[id]/models/route.ts": 3683,
"src/app/api/v1/models/catalog.ts": 2492,
"src/lib/db/apiKeys.ts": 2386,
"src/lib/db/core.ts": 2558,
"src/lib/db/migrationRunner.ts": 1718,
"src/lib/db/models.ts": 1712,
"src/lib/db/providers.ts": 1613,
"src/lib/memory/retrieval.ts": 1674,
"src/lib/tailscaleTunnel.ts": 1876,
"src/lib/usage/providerLimits.ts": 1581,
"src/shared/components/OAuthModal.tsx": 1769,
"src/shared/components/RequestLoggerV2.tsx": 2542,
"src/shared/components/analytics/charts.tsx": 1616,
"src/shared/services/cliRuntime.ts": 1751,
"src/sse/handlers/chat.ts": 2992,
"src/sse/services/auth.ts": 4132,
"_rebaseline_2026_08_28_mergebatch_v3851_provenance_sweep_batch6": "/merge-batch 2026-08-27/28 (v3.8.51) provider/asset provenance & legal compliance sweep — combining the Designer Web + Felo Web + Runtime + GPL-derived (Raycast/Hailuo Web, #11691) retirement guards at their shared chokepoints: src/sse/services/auth.ts 3432->3443 (+11, getProviderCredentials()'s two sequential retirement-check if-blocks plus getModelInfoOrRetirementResponse() catch-branch wiring), src/sse/handlers/chatHelpers.ts 1019->1037 (+18, the combined retirement-error catch branches in the executor dispatch path), src/shared/constants/providers/apikey/gateways.ts 1330->1347 (+17, catalog drift from the same PR chain since the prior 2026-08-11 rebaseline), open-sse/services/autoCombo/virtualFactory.ts 1130->1132 (+2, retirement guard import wiring at the virtual-instance factory chokepoint). Each guard call is irreducible per-mechanism wiring at pre-existing chokepoints (getExecutor, resolveExecutorWithProxy, chat.ts/chatHelpers.ts catch branches, providers.ts write paths) — combining them is additive, not a new branch. Covered by the focused test suites of each boarded PR (chatcore-executor-proxy.test.ts, provider-node-reserved-prefix.test.ts, gpl-derived-provider-removals.test.ts, migration-166-retire-gpl-derived-providers.test.ts, among others).",
"_rebaseline_2026_08_24_lasterror_provider_error_detail": "PR (ntdat812) own growth: src/sse/services/auth.ts 3344->3346 (+2). One line is the import of describeUpstreamFailure from @/shared/utils/upstreamError, which replaces the string-only collapse `typeof errorText === \"string\" ? errorText.slice(0, 100) : \"Provider error\"` at the single markAccountUnavailable chokepoint (net 0 lines there) — the logic itself lives in upstreamError.ts, next to the extractErrorMessage it reuses, so nothing else moved into this file. The second line is the repo's own lint-staged prettier pass splitting a pre-existing two-statements-on-one-line at getProviderCredentials (`invalidateManagedLease(...); log.warn(...)`); it re-applies on any commit that touches this file, so it is not separable from the change. Covered by tests/unit/provider-error-detail-lastError.test.ts.",
"_rebaseline_2026_08_23_11186_synced_inventory_routing": "PR #11186 (pacocartones) own growth: src/sse/services/auth.ts 3260->3337 (+77, loadAdvertisedModelsForSelfHostedConnections + the modelNotAdvertised candidate-filter predicate — pins chat routing to the connection whose synced inventory actually advertises the model, fixing spurious model-not-found on multi-host self-hosted setups; at the existing credential-selection chokepoint, not extractable without splitting the selection flow). Covered by tests/unit/chat-routing-synced-inventory-11089.test.ts. Owner pre-authorized baseline bumps 2026-08-22.",
"tests/unit/account-fallback-service.test.ts": 2453,
"tests/unit/provider-validation-specialty.test.ts": 4656,
"open-sse/executors/hyperagent.ts": 1601,
"src/lib/tokenHealthCheck.ts": 1643,
"open-sse/executors/default.ts": 1626,
"open-sse/executors/kiro.ts": 1668,
"open-sse/translator/request/openai-to-kiro.ts": 1649,
"open-sse/utils/sseHeartbeat.ts": 233,
"open-sse/utils/proxyFetch.ts": 1493,
"_rebaseline_2026_08_23_11177_dns_retry_classification": "PR #11177 (rqzbeh) own growth: proxyFetch.ts 1239->1244 (+5, EAI_AGAIN/ENOTFOUND/ETIMEDOUT join the retryable dispatcher classification alongside ECONNREFUSED — bounded socket retries for transient DNS failures, part of the #10443 Hermes→Antigravity stream-drop fixes). Covered by tests/unit/proxy-fetch-dns-retry-10443.test.ts. Owner pre-authorized baseline bumps 2026-08-22.",
"_rebaseline_2026_08_11_v3850_merge_storm_provider_registry": "DRIFT do merge-storm 2026-08-11 (99 PRs mergeados no release/v3.8.50). AddApiKeyModal.tsx (PR #8949 ChatGPT Web (Codex) provider) e useProviderConnections.ts/ModelSelectModal.tsx (PRs #9011 combo test-all, #9499 image combos) = UI nova legitima acima do cap; gateways.ts = god-file de catalogo de providers que cresceu com PRs #9009/#9421/#9468/#9594 (qualquer split arriscaria corromper o merge de novo — o proprio PR #9421 quebrou o arquivo); bridge.ts (PR #8949) = ponte Chromium vendored; proxyFetch.ts 1207->1220 = drift herdado de merges. Owner autorizou rebaseline com anotacao (2026-08-11).",
"_rebaseline_2026_08_11_v3850_merge_storm_provider_registry: DRIFT do merge-storm 2026-08-11 (99 PRs mergeados no release/v3.8.50). AddApiKeyModal.tsx (PR #8949 ChatGPT Web (Codex) provider) e useProviderConnections.ts/ModelSelectModal.tsx (PRs #9011 combo test-all, #9499 image combos) = UI nova legítima acima do cap; gateways.ts = god-file de catálogo de providers que cresceu com os PRs #9009/#9421/#9468/#9594 (qualquer split arriscaria corromper o merge de novo — o próprio PR #9421 foi o que quebrou o arquivo; sem split até o release, congelado no tamanho atual). Owner autorizou rebaseline com anotação (2026-08-11).": {
"src/app/(dashboard)/dashboard/providers/[id]/components/modals/AddApiKeyModal.tsx": 1062,
"src/app/(dashboard)/dashboard/providers/[id]/hooks/useProviderConnections.ts": 1051,
"src/shared/components/ModelSelectModal.tsx": 1138,
"src/shared/constants/providers/apikey/gateways.ts": 1250
},
"src/app/(dashboard)/dashboard/providers/[id]/components/modals/AddApiKeyModal.tsx": 1408,
"_rebaseline_2026_08_23_11207_aws_polly_fields": "PR #11207 (rafacpti23, draft) own growth: AddApiKeyModal.tsx 1082->1173 (+91, AWS SigV4 credential fields for aws-polly — Access Key ID / Region / optional Session Token blocks with providerText i18n labels, at the existing per-provider form-section chokepoint; the file is the known god-modal with repeated dated rebaselines). Covered by tests/unit/dashboard/aws-polly-connection-modal-fields.test.ts. Owner pre-authorized baseline bumps 2026-08-22.",
"_rebaseline_2026_08_22_11156_enter_check_disabled": "PR #11156 (rqzbeh) own growth: AddApiKeyModal.tsx 1080->1082 (+2, Enter keydown handler now mirrors the isCheckDisabled condition — owner-requested post-merge polish from #11056; the rest of the diff is Prettier reflow). Covered by tests/unit/ui/add-api-key-modal-enter-key.test.tsx (jsdom render test, Enter dispatch assertions).",
"src/app/(dashboard)/dashboard/providers/[id]/hooks/useProviderConnections.ts": 1262,
"src/shared/components/ModelSelectModal.tsx": 1366,
"src/shared/constants/providers/apikey/gateways.ts": 1618,
"open-sse/vendor/codex-chatgpt-web/bridge.ts": 1665,
"open-sse/vendor/codex-chatgpt-web/adapters/chatgpt-web/browser-worker.ts": 4410,
"_rebaseline_2026_08_11_v3850_merge_storm_provider_registry": "DRIFT do merge-storm 2026-08-11 (99 PRs mergeados no release/v3.8.50). AddApiKeyModal.tsx (PR #8949 ChatGPT Web (Codex) provider) e useProviderConnections.ts/ModelSelectModal.tsx (PRs #9011 combo test-all, #9499 image combos) = UI nova legitima acima do cap; gateways.ts = god-file de catalogo de providers que cresceu com PRs #9009/#9421/#9468/#9594 (qualquer split arriscaria corromper o merge de novo — o proprio PR #9421 quebrou o arquivo); bridge.ts (PR #8949) = ponte Chromium vendored; proxyFetch.ts 1207->1220 = drift herdado de merges. Owner autorizou rebaseline com anotacao (2026-08-11).",
"src/lib/modelCapabilities.ts": 1287,
"_rebaseline_2026_08_21_11034_effort_variants": "DRIFT do tip (base-red #9985): modelCapabilities.ts 1016->1072 (+56) acumulado por PRs ja mergeadas no release/v3.8.50 — principalmente #11034 (resolve effort-variant capabilities a partir do modelo base), alem de #10963/#11040/#10987 growth dos catalogos. Tip puro ficou vermelho neste gate; rebaseline no tip por push direto (owner pre-autorizou crescimento legitimo). Nao tocou no arquivo da #11038.",
"src/app/(dashboard)/dashboard/providers/[id]/providerPageHelpers.ts": 1217,
"open-sse/config/imageRegistry.ts": 1241,
"src/sse/handlers/chatHelpers.ts": 1245,
"src/shared/middleware/chatBodyAdmission.ts": 1342,
"_rebaseline_2026_08_22_11020_sigterm_drain": "PR #11020 (RaviTharuma) own growth: chatBodyAdmission.ts 1005->1009 (+4, heavyweight admission leases now increment the SIGTERM drain counter and releaseChatAdmissionWhenDone holds it for the SSE lifetime — closes #11015; +4 are the lease/drain wiring lines at the existing admission chokepoint). Covered by tests/unit/chat-body-admission.test.ts heavyweight-lease cases. Owner pre-authorized baseline bumps 2026-08-22.",
"_rebaseline_2026_08_20_10668_tabitoken_gateway": "#10668 (yawar-aquil) own catalog growth: src/shared/constants/providers/apikey/gateways.ts 1268->1283 (+15, entirely this PR diff -- one new tabitoken gateway entry, data lines only; base moved from 1255 to 1268 via other merges since the PR forked). Not combination drift: reproducible on the PR branch alone, so the WS5.5 release-captain rule does not apply. Extraction is not available -- the file is pure data (own header: \"Pure data; merged by apikey/index.ts via spread\") and already split into 6 family files under apikey/. Same precedent as _rebaseline_2026_08_14_imagetotext_servicekinds (#10275/#10291, gateways.ts 1250->1255, data lines only) and _rebaseline_2026_08_11_v3850_merge_storm_provider_registry (owner-authorized for this same file).",
"_rebaseline_2026_08_20_10878_10799_provider_health_probes": "PRs #10878 (unsupported OpenAI-like validation probes stay neutral) + #10799 (preserve credential health on inconclusive NVIDIA-timeout/Antigravity-400 probes) own growth: src/app/api/providers/[id]/test/route.ts 946->1025 (+79, sum of both boarded together). Both add narrowly-scoped classification branches at the existing test-route dispatch chokepoint (unsupported-capability skip, credential-inconclusive detection) rather than new files, mirroring the prior 2026_06_27_5193 rebaseline of the same file. Covered by tests/unit/provider-validation-unsupported-neutral.test.ts + tests/unit/provider-health-inconclusive-probes.test.ts.",
"_rebaseline_2026_08_21_10859_vision_bridge_catalog": "#10859 own growth (Vision Bridge fixes #10808/#10809): src/lib/modelCapabilities.ts 1006->1016 (+10, cmd/gpt-5.3-codex* text-only capability resolution) and open-sse/executors/commandCode.ts 988->1023 (+35, Command Code wire-model normalization for bare ids + reasoning field fallback for opencode-routed gateways). Cohesive bug fixes at the existing capability-resolution / executor chokepoints; not extractable mid-fix. Covered by tests/unit/model-capabilities-command-code-codex-textonly-10703.test.ts, tests/unit/command-code-vision.test.ts, tests/unit/opencode-mimo-reasoning-details-nonstream.test.ts. Pushed directly to release (own-session miss: the original rebaseline was made in a throwaway validation worktree and never landed on the PR branch or the release before merge).",
"_rebaseline_2026_08_21_10907_sticky_pin_clear": "#10907 own growth: open-sse/executors/commandCode.ts 1023->1038 (+15, effort-suffix sanitization threading for the sticky-pin-clear fix). Cohesive change at the existing executor chokepoint. Covered by tests/unit/command-code-executor.test.ts.",
"_rebaseline_2026_08_21_10986_reasoning_only_content": "#10986 own growth: open-sse/executors/commandCode.ts 1038->1059 (+21, reasoning-only content fallback — when upstream emits only reasoning-delta events and never a text-delta, surface the reasoning text as message.content in createJsonResponse and emit a synthetic content delta in createStreamResponse). Cohesive bug fix at the existing executor chokepoint (mirrors precedent style of #10907/#10859). Covered by tests/unit/command-code-executor.test.ts (2 new cases: non-stream + streaming).",
"_rebaseline_2026_08_21_11069_m365_har_import": "#11069 own growth: AddApiKeyModal.tsx 1073->1080 (+7 = Import .har file button for the copilot-m365-web credential modal — M365 is the only provider whose credential (access_token+chathubPath) must be extracted from a DevTools HAR WebSocket URL, added as a new modal affordance). Cohesive UI at the existing modal chokepoint; not extractable. Covered by tests/unit/m365-har-import*.test.ts.",
"_rebaseline_2026_08_23_11141_oauth_400_recovery": "PR #11141 (HouMinXi) own growth: test/route.ts 1025->1215 (+190, the reactive-400 recovery path — a fully rebuilt probe for refresh+retry on refreshable non-rotating connections, with inconclusive-status preservation and rotating-provider exclusion; all growth is the new probe builder + guards at the existing test-route dispatch, extraction would split the retry flow mid-logic). Covered by tests/unit/oauth-400-recovery.test.ts (8, bug-injection proof). Owner pre-authorized baseline bumps 2026-08-22.",
"_rebaseline_2026_08_23_tip_drift_post_batch0823": "Tip drift after the 2026-08-23 merge wave: chatBodyAdmission.ts 1009->1118 (+109, gate count incl. +1) and auth.ts 3337->3344 (+7), both grown by merges already on origin/release/v3.8.50 (verified identical on the pristine tip) — not by the codex-appserver-hardening PR that carries this bump. Owner pre-authorized baseline bumps 2026-08-22.",
"_rebaseline_2026_08_24_11355_cooldown_recovery_guards": "PR #11355 own growth: test/route.ts 1215->1237, +22 (startup crash-recovery guard: clearStaleCrashCooldowns() now parses the persisted rate_limited_until deadline and skips clearing rows still genuinely in the future, instead of clearing every non-terminal cooldown unconditionally). Cohesive fix at the existing test-route dispatch chokepoint alongside the #11141 probe builder. Covered by tests/unit/startup-stale-cooldown-recovery.test.ts + tests/unit/repro-zai-cooldown-cleared-by-connection-test.test.ts.",
"_rebaseline_2026_08_24_video_bridge_fu02_fu07_sampler": "PRs #11344 (FU-02 one-frame scene-aware determinism) + #11381 (FU-07 opt-in segment_aware structural sampling) own growth: videoBridgeRuntime.ts <1000->1009, +9 (sum of both boarded together in the same merge-batch). #11344 adds the deterministic one-frame midpoint fallback + policyEffective=uniform report at the existing scene_aware seam; #11381 adds the bounded local-only FFmpeg structural pre-analysis pass (scene/freeze/blur/exposure/SI-TI) and its budget-reallocation logic. Covered by tests/unit/guardrails/videoBridgeSampler.test.ts, tests/unit/guardrails/videoBridgeFu07StructuralSampling.test.ts, tests/integration/video-bridge-sampler-ffmpeg.test.ts. Owner pre-authorized rebaseline for legitimate PR growth (2026-08-19 directive).",
"open-sse/services/autoCombo/virtualFactory.ts": 1374,
"_rebaseline_2026_08_29_9133_candidates_inspector_skip_flag": "#9133 own growth: open-sse/services/autoCombo/virtualFactory.ts 1138->1139 (+1, net of extraction). Fix: prepareVirtualAutoComboInputs gained an opt-in `skip` parameter so the read-only #7819 candidate inspector (open-sse/handlers/autoComboCandidates.ts) can build the FULL, unfiltered pool and decorate a resilience-blocked candidate as reachable:false instead of filterResilienceBlockedCandidates silently dropping the row before the inspector ever sees it (routing is unaffected — it never passes `skip`). The connectionsById map-building loop was extracted to buildConnectionResilienceMap() in resilienceCandidateFilter.ts (net 0 there since Prettier still breaks the call over multiple lines) and the now-unused ConnectionResilienceView import was dropped; the sole remaining growth is the new `skip` default parameter itself, which Prettier always places on its own line once the preceding options object parameter already breaks across lines — not further reducible without splitting prepareVirtualAutoComboInputs's signature away from its own body. Covered by tests/unit/auto-combo-candidates-locked-model-visible.test.ts (TDD repro: red before the fix, green after) plus the existing tests/unit/noauth-autocombo-lockout-7623.test.ts and tests/unit/auto-combo-credentialed-model-pool.test.ts (unaffected routing-path behavior).",
"_rebaseline_2026_08_29_11481_model_exposure_list": "Feature #11481 (explicit model exposure allow/deny list for /v1/models, mirrored into auto/* combo pools) own growth on top of #9133's +1: open-sse/services/autoCombo/virtualFactory.ts 1139->1145 (measured real line count after both #9133 and #11481 merged together = one import line for filterModelExposureCandidates plus the filter-and-reassign block at the existing buildPreparedPool chokepoint, immediately after the filterPaidOnlyCandidates call it mirrors — the exact pattern #6512 already established for hidePaidModels). The actual predicate (isModelExposureAllowed, glob support via the shared globToRegex matcher) lives in the new src/shared/utils/modelExposureList.ts leaf, and the pool-filter wrapper lives in the new open-sse/services/autoCombo/modelExposureFilter.ts leaf (both well under cap) — this file only carries the minimal call-site wiring plus import, not extractable further without hiding the buildPreparedPool filter chain. Covered by tests/unit/autoCombo/model-exposure-filter-11481.test.ts (pure filter, all branches) and tests/unit/model-exposure-list.test.ts (predicate).",
"_rebaseline_2026_08_28_mergebatch_v3851_qwen_retirement": "/merge-batch 2026-08-28 (v3.8.51): #11713 (Qwen Web retirement) own growth: open-sse/services/autoCombo/virtualFactory.ts 1132->1135 (+3, combining the Designer + Runtime retirement-guard filter into the single runtimeConnections predicate at the existing candidate-pool chokepoint, now excluding Qwen Web alongside Felo Web). Irreducible per-mechanism wiring, additive not a new branch. Covered by tests/unit/virtual-auto-combo.test.ts.",
"_rebaseline_2026_08_28_mergebatch_v3851_chatgptweb_retirement": "/merge-batch 2026-08-28 (v3.8.51): #11754 (common ChatGPT Web retirement) own growth: open-sse/services/autoCombo/virtualFactory.ts 1135->1138 (+3, an early `available` connection filter for the retired chatgpt-web/cgpt-web ids applied to both the active and disabled-noauth connection lists, ahead of the existing Designer+Runtime runtimeConnections filter). Irreducible per-mechanism wiring, additive not a new branch. Covered by tests/unit/virtual-auto-combo.test.ts.",
"src/lib/cloudflaredTunnel.ts": 1294,
"src/shared/components/RequestLoggerDetail.tsx": 1334,
"_rebaseline_2026_08_30_11703_json_tree_viewer": "/merge-batch 2026-08-30 (v3.8.51): #11703 (hartmark) own growth: src/shared/components/RequestLoggerDetail.tsx 1018->1111 (+93). The 2026-07-22 annotation on this same file said 'no further growth without split rationale' — this PR does split: the collapsible-JSON-tree rendering logic itself lives in the sibling RequestLoggerDetail.sections.tsx (PayloadSection/StreamSection extraction, +82 lines there) plus two new leaves (JsonTreeExpandControls.tsx, useTimestampTitles.ts) and a new store (jsonTreeExpandStore.ts) — all well under cap. The +93 remaining here is the irreducible call-site wiring: import + mount JsonTreeExpandControls, wire the per-section expand-level state and timestamp-tooltip hook into the existing detail panel layout. Covered by the PR's own tests/unit/dashboard/payload-section-collapsible-json.test.tsx, timestamp-titles.test.tsx, tests/unit/shared/json-tree-expand-store.test.ts, short-call-id.test.ts (43/43 vitest + 11/11 native pass).",
"src/app/api/providers/[id]/test/route.ts": 1506,
"src/lib/guardrails/videoBridgeRuntime.ts": 1211,
"_rebaseline_2026_08_28_mergebatch_v3851_ratchet_bank_reconcile": "/merge-batch 2026-08-28 (v3.8.51): boarding #11702 (fix/verify-ratchet-bank object-note comparator) surfaced a large stale `frozen`/`testFrozen` snapshot on PR #11702's own branch (forked before the 08-11 banking outage — see the object-valued `_rebaseline_2026_08_11_v3850_merge_storm_provider_registry` note above, the exact bug #11702 fixes in the verifier) — its conflicting block duplicated ~85 already-tracked files with sizes smaller than the current release tip, and still listed open-sse/executors/chatgpt-web.ts (deleted by the #11754 retirement). Resolved by re-measuring every file in the union of both sides directly on the boarded tree (split(\"\\n\").length, matching check-file-size.mjs) rather than trusting either stale snapshot; dropped the dead chatgpt-web.ts entry; kept the two genuinely-new entries PR #11702's branch had that this tip did not yet track (src/app/api/providers/[id]/test/route.ts, src/lib/guardrails/videoBridgeRuntime.ts, both re-measured). Same reconciliation applied to the testFrozen block above.",
"open-sse/executors/chatgpt-web.ts": 5056,
"_rebaseline_2026_08_11_v3850_merge_storm_provider_registry: DRIFT do merge-storm 2026-08-11 (99 PRs mergeados no release/v3.8.50). AddApiKeyModal.tsx (PR #8949 ChatGPT Web provider) e useProviderConnections.ts/ModelSelectModal.tsx (PRs #9011 combo test-all, #9499 image combos) = UI nova legítima acima do cap; gateways.ts = god-file de catálogo de providers que cresceu com os PRs #9009/#9421/#9468/#9594 (qualquer split arriscaria corromper o merge de novo — o próprio PR #9421 foi o que quebrou o arquivo; sem split até o release, congelado no tamanho atual). Owner autorizou rebaseline com anotação (2026-08-11).": {
"src/app/(dashboard)/dashboard/providers/[id]/components/modals/AddApiKeyModal.tsx": 1062,
"src/app/(dashboard)/dashboard/providers/[id]/hooks/useProviderConnections.ts": 1051,
"src/shared/components/ModelSelectModal.tsx": 1138,
"src/shared/constants/providers/apikey/gateways.ts": 1250
},
"open-sse/executors/commandCode.ts": 1271,
"src/app/docs/lib/openapi.generated.ts": 1347
"_rebaseline_2026_08_20_10668_tabitoken_gateway": "#10668 (yawar-aquil) own catalog growth: src/shared/constants/providers/apikey/gateways.ts 1268->1283 (+15, entirely this PR diff -- one new tabitoken gateway entry, data lines only; base moved from 1255 to 1268 via other merges since the PR forked). Not combination drift: reproducible on the PR branch alone, so the WS5.5 release-captain rule does not apply. Extraction is not available -- the file is pure data (own header: \"Pure data; merged by apikey/index.ts via spread\") and already split into 6 family files under apikey/. Same precedent as _rebaseline_2026_08_14_imagetotext_servicekinds (#10275/#10291, gateways.ts 1250->1255, data lines only) and _rebaseline_2026_08_11_v3850_merge_storm_provider_registry (owner-authorized for this same file).",
"_rebaseline_2026_08_20_10878_10799_provider_health_probes": "PRs #10878 (unsupported OpenAI-like validation probes stay neutral) + #10799 (preserve credential health on inconclusive NVIDIA-timeout/Antigravity-400 probes) own growth: src/app/api/providers/[id]/test/route.ts 946->1025 (+79, sum of both boarded together). Both add narrowly-scoped classification branches at the existing test-route dispatch chokepoint (unsupported-capability skip, credential-inconclusive detection) rather than new files, mirroring the prior 2026_06_27_5193 rebaseline of the same file. Covered by tests/unit/provider-validation-unsupported-neutral.test.ts + tests/unit/provider-health-inconclusive-probes.test.ts.",
"_rebaseline_2026_08_21_10859_vision_bridge_catalog": "#10859 own growth (Vision Bridge fixes #10808/#10809): src/lib/modelCapabilities.ts 1006->1016 (+10, cmd/gpt-5.3-codex* text-only capability resolution) and open-sse/executors/commandCode.ts 988->1023 (+35, Command Code wire-model normalization for bare ids + reasoning field fallback for opencode-routed gateways). Cohesive bug fixes at the existing capability-resolution / executor chokepoints; not extractable mid-fix. Covered by tests/unit/model-capabilities-command-code-codex-textonly-10703.test.ts, tests/unit/command-code-vision.test.ts, tests/unit/opencode-mimo-reasoning-details-nonstream.test.ts. Pushed directly to release (own-session miss: the original rebaseline was made in a throwaway validation worktree and never landed on the PR branch or the release before merge).",
"_rebaseline_2026_08_21_10907_sticky_pin_clear": "#10907 own growth: open-sse/executors/commandCode.ts 1023->1038 (+15, effort-suffix sanitization threading for the sticky-pin-clear fix). Cohesive change at the existing executor chokepoint. Covered by tests/unit/command-code-executor.test.ts.",
"_rebaseline_2026_08_21_10986_reasoning_only_content": "#10986 own growth: open-sse/executors/commandCode.ts 1038->1059 (+21, reasoning-only content fallback — when upstream emits only reasoning-delta events and never a text-delta, surface the reasoning text as message.content in createJsonResponse and emit a synthetic content delta in createStreamResponse). Cohesive bug fix at the existing executor chokepoint (mirrors precedent style of #10907/#10859). Covered by tests/unit/command-code-executor.test.ts (2 new cases: non-stream + streaming).",
"_rebaseline_2026_08_21_11034_effort_variants": "DRIFT do tip (base-red #9985): modelCapabilities.ts 1016->1072 (+56) acumulado por PRs ja mergeadas no release/v3.8.50 — principalmente #11034 (resolve effort-variant capabilities a partir do modelo base), alem de #10963/#11040/#10987 growth dos catalogos. Tip puro ficou vermelho neste gate; rebaseline no tip por push direto (owner pre-autorizou crescimento legitimo). Nao tocou no arquivo da #11038.",
"_rebaseline_2026_08_21_11069_m365_har_import": "#11069 own growth: AddApiKeyModal.tsx 1073->1080 (+7 = Import .har file button for the copilot-m365-web credential modal — M365 is the only provider whose credential (access_token+chathubPath) must be extracted from a DevTools HAR WebSocket URL, added as a new modal affordance). Cohesive UI at the existing modal chokepoint; not extractable. Covered by tests/unit/m365-har-import*.test.ts.",
"_rebaseline_2026_08_22_11020_sigterm_drain": "PR #11020 (RaviTharuma) own growth: chatBodyAdmission.ts 1005->1009 (+4, heavyweight admission leases now increment the SIGTERM drain counter and releaseChatAdmissionWhenDone holds it for the SSE lifetime — closes #11015; +4 are the lease/drain wiring lines at the existing admission chokepoint). Covered by tests/unit/chat-body-admission.test.ts heavyweight-lease cases. Owner pre-authorized baseline bumps 2026-08-22.",
"_rebaseline_2026_08_22_11084_ccr_caller_gate": "PR #11084 (HouMinXi) own growth: open-sse/services/compression/engines/ccr/index.ts 1000->1024 (first listing — the engine was unlisted and drifted just over the 1000 cap; +24 are the callerSupportsCcrRetrieve gate that skips replacement entirely for callers without the retrieve tool, closing the stranded-prompt incident measured in production). Covered by tests/unit/compression/ccr-non-mcp-full-prompt-loss-7746.test.ts. Owner pre-authorized baseline bumps 2026-08-22.",
"_rebaseline_2026_08_22_11113_purify_system_first": "PR #11113 (ggdayup) own growth: open-sse/services/contextManager.ts 1000->1001 (+1, purifyHistory merges the compression notice into the leading system message instead of splicing a second one mid-array — live-confirmed TokenRouter 400s; the +1 is the merge-into-leading branch, not extractable). Covered by tests/unit/context-manager-purify-system-first.test.ts. Owner pre-authorized baseline bumps 2026-08-22.",
"_rebaseline_2026_08_22_11156_enter_check_disabled": "PR #11156 (rqzbeh) own growth: AddApiKeyModal.tsx 1080->1082 (+2, Enter keydown handler now mirrors the isCheckDisabled condition — owner-requested post-merge polish from #11056; the rest of the diff is Prettier reflow). Covered by tests/unit/ui/add-api-key-modal-enter-key.test.tsx (jsdom render test, Enter dispatch assertions).",
"_rebaseline_2026_08_23_11141_oauth_400_recovery": "PR #11141 (HouMinXi) own growth: test/route.ts 1025->1215 (+190, the reactive-400 recovery path — a fully rebuilt probe for refresh+retry on refreshable non-rotating connections, with inconclusive-status preservation and rotating-provider exclusion; all growth is the new probe builder + guards at the existing test-route dispatch, extraction would split the retry flow mid-logic). Covered by tests/unit/oauth-400-recovery.test.ts (8, bug-injection proof). Owner pre-authorized baseline bumps 2026-08-22.",
"_rebaseline_2026_08_23_11177_dns_retry_classification": "PR #11177 (rqzbeh) own growth: proxyFetch.ts 1239->1244 (+5, EAI_AGAIN/ENOTFOUND/ETIMEDOUT join the retryable dispatcher classification alongside ECONNREFUSED — bounded socket retries for transient DNS failures, part of the #10443 Hermes→Antigravity stream-drop fixes). Covered by tests/unit/proxy-fetch-dns-retry-10443.test.ts. Owner pre-authorized baseline bumps 2026-08-22.",
"_rebaseline_2026_08_23_11186_synced_inventory_routing": "PR #11186 (pacocartones) own growth: src/sse/services/auth.ts 3260->3337 (+77, loadAdvertisedModelsForSelfHostedConnections + the modelNotAdvertised candidate-filter predicate — pins chat routing to the connection whose synced inventory actually advertises the model, fixing spurious model-not-found on multi-host self-hosted setups; at the existing credential-selection chokepoint, not extractable without splitting the selection flow). Covered by tests/unit/chat-routing-synced-inventory-11089.test.ts. Owner pre-authorized baseline bumps 2026-08-22.",
"_rebaseline_2026_08_23_11207_aws_polly_fields": "PR #11207 (rafacpti23, draft) own growth: AddApiKeyModal.tsx 1082->1173 (+91, AWS SigV4 credential fields for aws-polly — Access Key ID / Region / optional Session Token blocks with providerText i18n labels, at the existing per-provider form-section chokepoint; the file is the known god-modal with repeated dated rebaselines). Covered by tests/unit/dashboard/aws-polly-connection-modal-fields.test.ts. Owner pre-authorized baseline bumps 2026-08-22.",
"_rebaseline_2026_08_23_tip_drift_post_batch0823": "Tip drift after the 2026-08-23 merge wave: chatBodyAdmission.ts 1009->1118 (+109, gate count incl. +1) and auth.ts 3337->3344 (+7), both grown by merges already on origin/release/v3.8.50 (verified identical on the pristine tip) — not by the codex-appserver-hardening PR that carries this bump. Owner pre-authorized baseline bumps 2026-08-22.",
"_rebaseline_2026_08_24_11355_cooldown_recovery_guards": "PR #11355 own growth: test/route.ts 1215->1237, +22 (startup crash-recovery guard: clearStaleCrashCooldowns() now parses the persisted rate_limited_until deadline and skips clearing rows still genuinely in the future, instead of clearing every non-terminal cooldown unconditionally). Cohesive fix at the existing test-route dispatch chokepoint alongside the #11141 probe builder. Covered by tests/unit/startup-stale-cooldown-recovery.test.ts + tests/unit/repro-zai-cooldown-cleared-by-connection-test.test.ts.",
"_rebaseline_2026_08_24_lasterror_provider_error_detail": "PR (ntdat812) own growth: src/sse/services/auth.ts 3344->3346 (+2). One line is the import of describeUpstreamFailure from @/shared/utils/upstreamError, which replaces the string-only collapse `typeof errorText === \"string\" ? errorText.slice(0, 100) : \"Provider error\"` at the single markAccountUnavailable chokepoint (net 0 lines there) — the logic itself lives in upstreamError.ts, next to the extractErrorMessage it reuses, so nothing else moved into this file. The second line is the repo's own lint-staged prettier pass splitting a pre-existing two-statements-on-one-line at getProviderCredentials (`invalidateManagedLease(...); log.warn(...)`); it re-applies on any commit that touches this file, so it is not separable from the change. Covered by tests/unit/provider-error-detail-lastError.test.ts.",
"_rebaseline_2026_08_24_video_bridge_fu02_fu07_sampler": "PRs #11344 (FU-02 one-frame scene-aware determinism) + #11381 (FU-07 opt-in segment_aware structural sampling) own growth: videoBridgeRuntime.ts <1000->1009, +9 (sum of both boarded together in the same merge-batch). #11344 adds the deterministic one-frame midpoint fallback + policyEffective=uniform report at the existing scene_aware seam; #11381 adds the bounded local-only FFmpeg structural pre-analysis pass (scene/freeze/blur/exposure/SI-TI) and its budget-reallocation logic. Covered by tests/unit/guardrails/videoBridgeSampler.test.ts, tests/unit/guardrails/videoBridgeFu07StructuralSampling.test.ts, tests/integration/video-bridge-sampler-ffmpeg.test.ts. Owner pre-authorized rebaseline for legitimate PR growth (2026-08-19 directive).",
"_rebaseline_2026_08_28_mergebatch_v3851_chatgptweb_retirement": "/merge-batch 2026-08-28 (v3.8.51): #11754 (common ChatGPT Web retirement) own growth: open-sse/services/autoCombo/virtualFactory.ts 1135->1138 (+3, an early `available` connection filter for the retired chatgpt-web/cgpt-web ids applied to both the active and disabled-noauth connection lists, ahead of the existing Designer+Runtime runtimeConnections filter). Irreducible per-mechanism wiring, additive not a new branch. Covered by tests/unit/virtual-auto-combo.test.ts.",
"_rebaseline_2026_08_28_mergebatch_v3851_provenance_sweep_batch6": "/merge-batch 2026-08-27/28 (v3.8.51) provider/asset provenance & legal compliance sweep — combining the Designer Web + Felo Web + Runtime + GPL-derived (Raycast/Hailuo Web, #11691) retirement guards at their shared chokepoints: src/sse/services/auth.ts 3432->3443 (+11, getProviderCredentials()'s two sequential retirement-check if-blocks plus getModelInfoOrRetirementResponse() catch-branch wiring), src/sse/handlers/chatHelpers.ts 1019->1037 (+18, the combined retirement-error catch branches in the executor dispatch path), src/shared/constants/providers/apikey/gateways.ts 1330->1347 (+17, catalog drift from the same PR chain since the prior 2026-08-11 rebaseline), open-sse/services/autoCombo/virtualFactory.ts 1130->1132 (+2, retirement guard import wiring at the virtual-instance factory chokepoint). Each guard call is irreducible per-mechanism wiring at pre-existing chokepoints (getExecutor, resolveExecutorWithProxy, chat.ts/chatHelpers.ts catch branches, providers.ts write paths) — combining them is additive, not a new branch. Covered by the focused test suites of each boarded PR (chatcore-executor-proxy.test.ts, provider-node-reserved-prefix.test.ts, gpl-derived-provider-removals.test.ts, migration-166-retire-gpl-derived-providers.test.ts, among others).",
"_rebaseline_2026_08_28_mergebatch_v3851_qwen_retirement": "/merge-batch 2026-08-28 (v3.8.51): #11713 (Qwen Web retirement) own growth: open-sse/services/autoCombo/virtualFactory.ts 1132->1135 (+3, combining the Designer + Runtime retirement-guard filter into the single runtimeConnections predicate at the existing candidate-pool chokepoint, now excluding Qwen Web alongside Felo Web). Irreducible per-mechanism wiring, additive not a new branch. Covered by tests/unit/virtual-auto-combo.test.ts.",
"_rebaseline_2026_08_28_mergebatch_v3851_ratchet_bank_reconcile": "/merge-batch 2026-08-28 (v3.8.51): boarding #11702 (fix/verify-ratchet-bank object-note comparator) surfaced a large stale `frozen`/`testFrozen` snapshot on PR #11702's own branch (forked before the 08-11 banking outage — see the object-valued `_rebaseline_2026_08_11_v3850_merge_storm_provider_registry` note above, the exact bug #11702 fixes in the verifier) — its conflicting block duplicated ~85 already-tracked files with sizes smaller than the current release tip, and still listed open-sse/executors/chatgpt-web.ts (deleted by the #11754 retirement). Resolved by re-measuring every file in the union of both sides directly on the boarded tree (split(\"\\n\").length, matching check-file-size.mjs) rather than trusting either stale snapshot; dropped the dead chatgpt-web.ts entry; kept the two genuinely-new entries PR #11702's branch had that this tip did not yet track (src/app/api/providers/[id]/test/route.ts, src/lib/guardrails/videoBridgeRuntime.ts, both re-measured). Same reconciliation applied to the testFrozen block above.",
"_rebaseline_2026_08_29_11481_model_exposure_list": "Feature #11481 (explicit model exposure allow/deny list for /v1/models, mirrored into auto/* combo pools) own growth on top of #9133's +1: open-sse/services/autoCombo/virtualFactory.ts 1139->1145 (measured real line count after both #9133 and #11481 merged together = one import line for filterModelExposureCandidates plus the filter-and-reassign block at the existing buildPreparedPool chokepoint, immediately after the filterPaidOnlyCandidates call it mirrors — the exact pattern #6512 already established for hidePaidModels). The actual predicate (isModelExposureAllowed, glob support via the shared globToRegex matcher) lives in the new src/shared/utils/modelExposureList.ts leaf, and the pool-filter wrapper lives in the new open-sse/services/autoCombo/modelExposureFilter.ts leaf (both well under cap) — this file only carries the minimal call-site wiring plus import, not extractable further without hiding the buildPreparedPool filter chain. Covered by tests/unit/autoCombo/model-exposure-filter-11481.test.ts (pure filter, all branches) and tests/unit/model-exposure-list.test.ts (predicate).",
"_rebaseline_2026_08_29_9133_candidates_inspector_skip_flag": "#9133 own growth: open-sse/services/autoCombo/virtualFactory.ts 1138->1139 (+1, net of extraction). Fix: prepareVirtualAutoComboInputs gained an opt-in `skip` parameter so the read-only #7819 candidate inspector (open-sse/handlers/autoComboCandidates.ts) can build the FULL, unfiltered pool and decorate a resilience-blocked candidate as reachable:false instead of filterResilienceBlockedCandidates silently dropping the row before the inspector ever sees it (routing is unaffected — it never passes `skip`). The connectionsById map-building loop was extracted to buildConnectionResilienceMap() in resilienceCandidateFilter.ts (net 0 there since Prettier still breaks the call over multiple lines) and the now-unused ConnectionResilienceView import was dropped; the sole remaining growth is the new `skip` default parameter itself, which Prettier always places on its own line once the preceding options object parameter already breaks across lines — not further reducible without splitting prepareVirtualAutoComboInputs's signature away from its own body. Covered by tests/unit/auto-combo-candidates-locked-model-visible.test.ts (TDD repro: red before the fix, green after) plus the existing tests/unit/noauth-autocombo-lockout-7623.test.ts and tests/unit/auto-combo-credentialed-model-pool.test.ts (unaffected routing-path behavior).",
"_rebaseline_2026_08_30_11703_json_tree_viewer": "/merge-batch 2026-08-30 (v3.8.51): #11703 (hartmark) own growth: src/shared/components/RequestLoggerDetail.tsx 1018->1111 (+93). The 2026-07-22 annotation on this same file said 'no further growth without split rationale' — this PR does split: the collapsible-JSON-tree rendering logic itself lives in the sibling RequestLoggerDetail.sections.tsx (PayloadSection/StreamSection extraction, +82 lines there) plus two new leaves (JsonTreeExpandControls.tsx, useTimestampTitles.ts) and a new store (jsonTreeExpandStore.ts) — all well under cap. The +93 remaining here is the irreducible call-site wiring: import + mount JsonTreeExpandControls, wire the per-section expand-level state and timestamp-tooltip hook into the existing detail panel layout. Covered by the PR's own tests/unit/dashboard/payload-section-collapsible-json.test.tsx, timestamp-titles.test.tsx, tests/unit/shared/json-tree-expand-store.test.ts, short-call-id.test.ts (43/43 vitest + 11/11 native pass).",
"_rebaseline_pr1043_minimax_tts": "Upstream port decolua/9router#1043 (toanalien) own growth: audioSpeech.ts 965->1061 (+96). Adds MiniMax T2A v2 TTS dispatch (handleMinimaxSpeech + hexToBytes helper) — provider entry was already in audioRegistry (format: minimax-tts) but no handler existed, falling through to the OpenAI-compatible default that fails (T2A has custom shape + hex-encoded audio + base_resp envelope). New branch sits next to the other inline provider branches (xiaomi-mimo, coqui, tortoise, aws-polly) — extracting would just create indirection. Covered by tests/unit/minimax-tts-1043.test.ts (3 tests, GREEN: success, base_resp error, invalid-hex).",
"_rebaseline_pr4592_exclude_exhausted_auto": "Reconcile #4592 already-merged growth: combo.ts 2991->3036 (+45, terminal-status quota-cutoff exclusion in buildAutoCandidates + opt-in gate). Fast-gate PR->release does not run check:file-size.",
"open-sse/executors/antigravity.ts": 1665,
"open-sse/executors/base.ts": 1751,
"open-sse/executors/chatgpt-web.ts": 5056,
"open-sse/executors/codex.ts": 1499,
"open-sse/executors/cursor.ts": 1759,
"open-sse/executors/muse-spark-web.ts": 1405,
"open-sse/handlers/chatCore.ts": 5946,
"open-sse/handlers/imageGeneration.ts": 3259,
"open-sse/handlers/search.ts": 1789,
"open-sse/mcp-server/schemas/tools.ts": 1621,
"open-sse/mcp-server/server.ts": 1572,
"open-sse/services/accountFallback.ts": 2422,
"open-sse/services/adobeFireflyBrowserLogin.ts": 1401,
"open-sse/services/combo.ts": 4023,
"open-sse/translator/response/openai-responses.ts": 1466,
"open-sse/utils/cursorAgentProtobuf.ts": 1547,
"open-sse/utils/proxyFetch.ts": 1271,
"open-sse/utils/stream.ts": 3072,
"open-sse/vendor/codex-chatgpt-web/adapters/chatgpt-web/browser-worker.ts": 4398,
"open-sse/vendor/codex-chatgpt-web/bridge.ts": 1322,
"src/app/(dashboard)/dashboard/HomePageClient.tsx": 1344,
"src/app/(dashboard)/dashboard/api-manager/ApiManagerPageClient.tsx": 3186,
"src/app/(dashboard)/dashboard/combos/page.tsx": 5012,
"src/app/(dashboard)/dashboard/costs/CostOverviewTab.tsx": 1319,
"src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.tsx": 2491,
"src/app/(dashboard)/dashboard/providers/[id]/components/modals/EditConnectionModal.tsx": 1631,
"src/app/(dashboard)/dashboard/providers/page.tsx": 2007,
"src/app/(dashboard)/dashboard/runtime/RuntimePageClient.tsx": 1201,
"src/app/(dashboard)/dashboard/settings/components/ProxyRegistryManager.tsx": 1475,
"src/app/(dashboard)/dashboard/settings/components/ResilienceTab.tsx": 1271,
"src/app/(dashboard)/dashboard/settings/components/RoutingTab.tsx": 1606,
"src/app/(dashboard)/dashboard/settings/components/SystemStorageTab.tsx": 1597,
"src/app/(dashboard)/dashboard/usage/components/EvalsTab.tsx": 2152,
"src/app/api/providers/[id]/models/route.ts": 2432,
"src/app/api/providers/[id]/test/route.ts": 1252,
"src/app/api/v1/models/catalog.ts": 2075,
"src/app/docs/lib/openapi.generated.ts": 1347,
"src/lib/db/apiKeys.ts": 1610,
"src/lib/db/core.ts": 1745,
"src/lib/db/migrationRunner.ts": 1201,
"src/lib/tailscaleTunnel.ts": 1208,
"src/lib/tokenHealthCheck.ts": 1218,
"src/shared/components/RequestLoggerV2.tsx": 1718,
"src/shared/constants/providers/apikey/gateways.ts": 1439,
"src/shared/services/cliRuntime.ts": 1296,
"src/sse/handlers/chat.ts": 2384,
"src/sse/services/auth.ts": 3427,
"tests/unit/account-fallback-service.test.ts": 2453,
"tests/unit/provider-validation-specialty.test.ts": 4656
},
"_rebaseline_base_2026_08_10_proxyfetch": "Base-red fix (green-prs sweep, issue #9985): open-sse/utils/proxyFetch.ts 1207 > cap 1000 — new proxied-TLS fetch helper introduced by the Fal reference-image work. Owner-authorized quick rebaseline to green; structural slim tracked for v3.9.0.",
"_rebaseline_2026_07_27_v3849_train2": "Merge-train 2 (7 PRs) — owner-approved 2026-07-27. Single entry: chatCore.ts 4955->5006 (#8595, Responses multi-turn image compaction before the context hard-reject). Genuine irreducible growth at the existing compaction chokepoint in handleChatCore — the PR adds a last-resort retry against the concrete budget plus the estimateFinalInputTokens helper, both wired at the pre-existing call site rather than a new branch. Covered by tests/unit/8560-responses-image-compaction.test.ts (4 tests).",

View File

@@ -14,6 +14,7 @@
"claude-3-7-sonnet-20250219",
"google/gemini-2.0-flash",
"gpt-4-0125-preview",
"gpt-5.2-codex",
"openai/gpt-5.2-codex"
],
"allowedRetiredInCatalog_note": "TODO(#11503): ratchet to burn down. Each id is retired by its vendor but still routable from the provider catalog. Removing a catalog row or adding a BUILT_IN_ALIASES forward is a maintainer call (some aggregators still serve these ids), so they are allowlisted here rather than silently dropped. Delete an entry as soon as it is forwarded or removed; never add one without a tracking issue.",

View File

@@ -10,7 +10,6 @@
"tests/integration/services/cliproxy-coexistence.test.ts",
"tests/integration/services/full-lifecycle.int.test.ts",
"tests/integration/services/route-guard-services.int.test.ts",
"tests/live/deepseek-web-live.test.ts",
"tests/theoldllm-stress.test.ts"
"tests/live/deepseek-web-live.test.ts"
]
}

View File

@@ -1,4 +1,30 @@
{
"schemaVersion": 1,
"reconciliations": []
"reconciliations": [
{
"id": "provider-takedown-2026-08-30",
"reason": "Operator of a third-party keyless service asked in writing (2026-08-30) that every reference to it be removed from OmniRoute, including release documentation. Bullets whose sole subject was that provider are dropped; bullets that mentioned it in passing are reworded without the name.",
"baseChangelogSha256": "dba84d68ba25f539575ec8679b62f084d88b302c7b596c55a28017b481265ad7",
"resultChangelogSha256": "6b3d4fe192d3694bbef4cb5ba0f4985a81e269a159041b5dd9f11fefb91c04d7",
"removedBullets": [
"- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun",
"- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{\"effort\":\"max\"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White",
"- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn",
"- **fix(resilience):** a bare, unrecognized `403` from a no-credential (`authType:\"none\"`) provider like mimocode or theoldllm no longer permanently bans the connection ([#6315](https://github.com/diegosouzapw/OmniRoute/issues/6315), [#6345](https://github.com/diegosouzapw/OmniRoute/issues/6345)) — `classifyProviderError()`'s 403 branch only exempted `apikey` providers from the terminal `FORBIDDEN` classification, so these free/stateless proxies (no real account/credential to revoke) fell through to `FORBIDDEN` on the first unmatched 403 and got `isActive:false, testStatus:\"banned\"` with no cooldown or retry. The exemption now also covers `authType:\"none\"` providers, returning `null` (recoverable) so the existing connection-cooldown/retry layer handles it. Regression guard: `tests/unit/errorClassifier-noauth-403-6315.test.ts`.",
"- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)",
"- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)",
"- **fix(theoldllm):** `X-Request-Token` generated server-side, dropping the Playwright dependency — replicates the site's client `rie()` token (djb2 hash + `oldllm-client-2026` seed + UA prefix + 8-hex `crypto.randomUUID` suffix) directly, so The Old LLM no longer needs a headless browser to mint tokens. ([#3491](https://github.com/diegosouzapw/OmniRoute/pull/3491) — thanks @borodulin / @diegosouzapw)",
"- **fix(catalog):** imported/custom models on no-auth providers (e.g. The Old LLM) now appear in `GET /api/v1/models` and the Playground model selector — the eligibility gate required a DB connection row which no-auth providers never have, silently dropping every imported model for them. ([#3463](https://github.com/diegosouzapw/OmniRoute/pull/3463) — thanks @tjengbudi / @diegosouzapw)",
"- **fix(theoldllm):** stop the `[502]: Body is unusable: Body has already been read` error on the cached-token path — the executor read the same upstream `Response` body with `.text()` twice; it now reads it once and only re-reads after a token-rejection refetch. (#3296 — thanks @onizukashonan14-png)",
"- **fix(dashboard):** keep no-auth providers (opencode, duckduckgo-web, theoldllm, veoaifree-web) visible under the \"Show configured only\" filter — they never create a connection row (`stats.total === 0`) but are always usable and already appear in `/v1/models`, so the filter now treats `displayAuthType === \"no-auth\"` as configured. (#3290 — thanks @uniQta)",
"- **theoldllm:** add The Old LLM — a free, Playwright-backed provider with dual-mode operation (cached browser token + direct fetch) bridged through a Vercel relay (#3217 — thanks @oyi77)"
],
"addedBullets": [
"- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{\"effort\":\"max\"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White",
"- **fix(resilience):** a bare, unrecognized `403` from a no-credential (`authType:\"none\"`) provider like mimocode no longer permanently bans the connection ([#6315](https://github.com/diegosouzapw/OmniRoute/issues/6315), [#6345](https://github.com/diegosouzapw/OmniRoute/issues/6345)) — `classifyProviderError()`'s 403 branch only exempted `apikey` providers from the terminal `FORBIDDEN` classification, so these free/stateless proxies (no real account/credential to revoke) fell through to `FORBIDDEN` on the first unmatched 403 and got `isActive:false, testStatus:\"banned\"` with no cooldown or retry. The exemption now also covers `authType:\"none\"` providers, returning `null` (recoverable) so the existing connection-cooldown/retry layer handles it. Regression guard: `tests/unit/errorClassifier-noauth-403-6315.test.ts`.",
"- **fix(catalog):** imported/custom models on no-auth providers now appear in `GET /api/v1/models` and the Playground model selector — the eligibility gate required a DB connection row which no-auth providers never have, silently dropping every imported model for them. ([#3463](https://github.com/diegosouzapw/OmniRoute/pull/3463) — thanks @tjengbudi / @diegosouzapw)",
"- **fix(dashboard):** keep no-auth providers (opencode, duckduckgo-web, veoaifree-web) visible under the \"Show configured only\" filter — they never create a connection row (`stats.total === 0`) but are always usable and already appear in `/v1/models`, so the filter now treats `displayAuthType === \"no-auth\"` as configured. (#3290 — thanks @uniQta)"
]
}
]
}

View File

@@ -7,4 +7,4 @@ USER pwuser
EXPOSE 9223
CMD ["/bin/sh", "-lc", "node /opt/cdp-proxy.mjs & chrome_path=$(find /ms-playwright -path '*/chrome-linux/chrome' -type f | head -n 1); test -n \"$chrome_path\"; exec xvfb-run -a --server-args='-screen 0 1920x1080x24 -nolisten tcp' \"$chrome_path\" --no-sandbox --disable-dev-shm-usage --remote-debugging-port=9222 --user-data-dir=/browser-profile about:blank"]
CMD ["/bin/sh", "-lc", "node /opt/cdp-proxy.mjs & chrome_path=$(find /ms-playwright -path '*/chrome-linux*/chrome' -type f | head -n 1); test -n \"$chrome_path\"; exec xvfb-run -a --server-args='-screen 0 1920x1080x24 -nolisten tcp' \"$chrome_path\" --no-sandbox --disable-dev-shm-usage --remote-debugging-port=9222 --user-data-dir=/browser-profile about:blank"]

View File

@@ -1,4 +1,4 @@
<svg viewBox="0 0 1200 350" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Animated terminal demoing the OmniRoute CLI: omniroute providers list (352 providers registered, anthropic, codex, glm, kimi shown active), omniroute combo list (always-on priority, cost-saver, fusion-panel, context-relay) and omniroute health (healthy, 18412 requests in 24h, p95 412ms, circuit breakers 24 closed, 1 half-open, 0 open), cycling over 86 top-level commands: providers, oauth, keys, combo, nodes, models, cache, compression, cost, usage, quota, health, resilience, telemetry, logs, audit, mcp, a2a, cloud, memory, skills, eval, doctor, repl, tunnel, backup, sync, webhooks, policy, pricing, translator, simulate and more.">
<svg viewBox="0 0 1200 350" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Animated terminal demoing the OmniRoute CLI: omniroute providers list (354 providers registered, anthropic, codex, glm, kimi shown active), omniroute combo list (always-on priority, cost-saver, fusion-panel, context-relay) and omniroute health (healthy, 18412 requests in 24h, p95 412ms, circuit breakers 24 closed, 1 half-open, 0 open), cycling over 86 top-level commands: providers, oauth, keys, combo, nodes, models, cache, compression, cost, usage, quota, health, resilience, telemetry, logs, audit, mcp, a2a, cloud, memory, skills, eval, doctor, repl, tunnel, backup, sync, webhooks, policy, pricing, translator, simulate and more.">
<desc>Compact animated terminal cycling three real OmniRoute CLI commands with a typewriter effect and a scrolling subcommand ticker; the first frame shows the completed providers-list screen.</desc>
<defs><clipPath id="tickerClip"><rect x="12" y="304" width="1176" height="40"/></clipPath><clipPath id="tw0"><rect x="64" y="46" height="26" width="0"><animate attributeName="width" calcMode="discrete" values="0;31;61;92;122;153;184;214;245;245" keyTimes="0;0.012;0.018;0.024;0.030;0.036;0.042;0.048;0.054;1" dur="18s" repeatCount="indefinite"/></rect></clipPath><clipPath id="tw1"><rect x="64" y="46" height="26" width="0"><animate attributeName="width" calcMode="discrete" values="0;26;51;76;102;128;153;178;204;204" keyTimes="0;0.348;0.351;0.357;0.363;0.369;0.375;0.381;0.387;1" dur="18s" repeatCount="indefinite"/></rect></clipPath><clipPath id="tw2"><rect x="64" y="46" height="26" width="0"><animate attributeName="width" calcMode="discrete" values="0;20;41;61;82;102;122;143;163;163" keyTimes="0;0.678;0.684;0.690;0.696;0.702;0.708;0.714;0.720;1" dur="18s" repeatCount="indefinite"/></rect></clipPath></defs>
<rect width="1200" height="350" fill="#0d1117"/>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,4 +1,4 @@
<svg viewBox="0 0 1200 780" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Comparison table: OmniRoute versus 9router, OpenRouter, CLIProxyAPI and LiteLLM across 13 capabilities. OmniRoute is the only one with the full set: 352 providers, 150+ free providers built-in, 19 routing strategies, 12-engine token compression, a built-in MCP server with 110 tools, A2A protocol, persistent memory, guardrails, cloud agents, TLS fingerprint stealth, desktop/Termux/PWA, 43 UI locales and 100% MIT self-hosted. 9router has free providers, RTK compression and translation but no MCP, A2A, memory, guardrails, cloud agents or stealth. OpenRouter is a hosted SaaS with 400+ models, guardrails and a hosted MCP but is not self-hosted and lacks A2A, memory, cloud agents and stealth. CLIProxyAPI is a light OAuth proxy with two routing strategies. LiteLLM has 100+ providers, A2A and extensive guardrails but no memory, compression, free tier, stealth or cloud agents.">
<svg viewBox="0 0 1200 780" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Comparison table: OmniRoute versus 9router, OpenRouter, CLIProxyAPI and LiteLLM across 13 capabilities. OmniRoute is the only one with the full set: 354 providers, 150+ free providers built-in, 19 routing strategies, 12-engine token compression, a built-in MCP server with 110 tools, A2A protocol, persistent memory, guardrails, cloud agents, TLS fingerprint stealth, desktop/Termux/PWA, 43 UI locales and 100% MIT self-hosted. 9router has free providers, RTK compression and translation but no MCP, A2A, memory, guardrails, cloud agents or stealth. OpenRouter is a hosted SaaS with 400+ models, guardrails and a hosted MCP but is not self-hosted and lacks A2A, memory, cloud agents and stealth. CLIProxyAPI is a light OAuth proxy with two routing strategies. LiteLLM has 100+ providers, A2A and extensive guardrails but no memory, compression, free tier, stealth or cloud agents.">
<desc>Static-header comparison table where each capability row fades in top to bottom; the OmniRoute column is highlighted and shows a check or a leading value in every row, while competitors show a mix of checks, partials and crosses.</desc>
<defs>
<pattern id="gC" width="32" height="32" patternUnits="userSpaceOnUse"><path d="M 32 0 L 0 0 0 32" fill="none" stroke="#ffffff" stroke-opacity="0.05" stroke-width="1"/></pattern>

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,4 +1,4 @@
<svg viewBox="0 0 1200 540" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="The OmniRoute promise: one endpoint and 352 providers. Six pillars. Resilient fallback: automatic routing continues while another healthy target is available. Save up to 95 percent of eligible tokens: RTK plus Caveman stacked compression averages about 89 percent on tool-heavy sessions. Zero dollars to start: 150+ providers with a free tier and 53 recurring or keyless free-forever providers. Every tool works: 36 CLI and agent integration records, including Claude Code, Codex, Cursor, Cline, Copilot and Antigravity, through one config. One endpoint: OpenAI, Claude, Gemini and Responses API translation at /v1. Production controls: circuit breakers, TLS stealth, MCP with 110 tools, A2A, memory, guardrails, evals, and 39,000+ static test declarations across 5,100+ tracked test files.">
<svg viewBox="0 0 1200 540" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="The OmniRoute promise: one endpoint and 354 providers. Six pillars. Resilient fallback: automatic routing continues while another healthy target is available. Save up to 95 percent of eligible tokens: RTK plus Caveman stacked compression averages about 89 percent on tool-heavy sessions. Zero dollars to start: 150+ providers with a free tier and 53 recurring or keyless free-forever providers. Every tool works: 36 CLI and agent integration records, including Claude Code, Codex, Cursor, Cline, Copilot and Antigravity, through one config. One endpoint: OpenAI, Claude, Gemini and Responses API translation at /v1. Production controls: circuit breakers, TLS stealth, MCP with 110 tools, A2A, memory, guardrails, evals, and 39,000+ static test declarations across 5,100+ tracked test files.">
<desc>Animated promise card: six pillar tiles fade in in reading order, then a soft colored border highlight sweeps from tile to tile in a continuous cycle.</desc>
<defs>
<pattern id="gridPaperP" width="32" height="32" patternUnits="userSpaceOnUse">
@@ -21,7 +21,7 @@
<line x1="150" y1="53" x2="1160" y2="53" stroke="#232b38" stroke-width="1.5"/>
</g>
<g>
<text x="40" y="100" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="23" font-weight="600" fill="#c9d1d9">One endpoint. <tspan fill="#a78bfa" font-weight="800">352 providers.</tspan> Never stop building — OmniRoute picks <tspan fill="#7ee787" font-weight="700">the cheapest one that works</tspan>.</text>
<text x="40" y="100" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="23" font-weight="600" fill="#c9d1d9">One endpoint. <tspan fill="#a78bfa" font-weight="800">354 providers.</tspan> Never stop building — OmniRoute picks <tspan fill="#7ee787" font-weight="700">the cheapest one that works</tspan>.</text>
</g>
<g font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif">
@@ -38,7 +38,7 @@
<line x1="3.9" y1="3.9" x2="18.1" y2="18.1"/>
</g>
<text x="102" y="170" font-size="18" font-weight="800" fill="#74b9ff">Never hit limits</text>
<text x="66" y="204" font-size="13.5" fill="#a1a1aa">Auto-fallback across 352 providers in</text>
<text x="66" y="204" font-size="13.5" fill="#a1a1aa">Auto-fallback across 354 providers in</text>
<text x="66" y="226" font-size="13.5" fill="#a1a1aa">milliseconds. Quota out? The next provider</text>
<text x="66" y="248" font-size="13.5" fill="#a1a1aa">takes over while a healthy target remains.</text>
</g>

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1,4 +1,4 @@
<svg viewBox="0 0 1200 548" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="OmniRoute hero: Never stop coding. Every AI tool to 352 providers — 150+ free — through one endpoint. Claude Code, Codex, Cursor, Cline, Copilot and Antigravity into free Claude, GPT and Gemini with auto-fallback. RTK + Caveman stacked compression saves 15 to 95 percent of tokens — about 89 percent average on tool-heavy sessions — so you never hit limits. Stats: 352 AI providers, 150+ free tiers, about 1.51B free tokens per month, 15 to 95 percent token savings, 19 routing strategies, zero dollars to start.">
<svg viewBox="0 0 1200 548" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="OmniRoute hero: Never stop coding. Every AI tool to 354 providers — 150+ free — through one endpoint. Claude Code, Codex, Cursor, Cline, Copilot and Antigravity into free Claude, GPT and Gemini with auto-fallback. RTK + Caveman stacked compression saves 15 to 95 percent of tokens — about 89 percent average on tool-heavy sessions — so you never hit limits. Stats: 354 AI providers, 150+ free tiers, about 1.51B free tokens per month, 15 to 95 percent token savings, 19 routing strategies, zero dollars to start.">
<desc>Animated hero card: a pulse travels the divider line and a compression bar demo repeatedly shrinks a prompt by up to 95 percent; all headline content is static and readable on the first frame.</desc>
<defs>
<pattern id="gridPaperH" width="32" height="32" patternUnits="userSpaceOnUse">
@@ -28,7 +28,7 @@
<text x="48" y="138" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="60" font-weight="800" fill="#e9edf3">Never stop coding<tspan fill="#a855f7">.</tspan></text>
<!-- subheadline -->
<text x="48" y="184" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="25" font-weight="600" fill="#c9d1d9">Every AI tool → <tspan fill="#a78bfa" font-weight="800">352 providers</tspan><tspan fill="#7ee787" font-weight="800">150+ free</tspan> — through one endpoint.</text>
<text x="48" y="184" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="25" font-weight="600" fill="#c9d1d9">Every AI tool → <tspan fill="#a78bfa" font-weight="800">354 providers</tspan><tspan fill="#7ee787" font-weight="800">150+ free</tspan> — through one endpoint.</text>
<!-- plug line -->
<text x="48" y="222" font-family="Inter, 'Segoe UI', Arial, Helvetica, system-ui, sans-serif" font-size="16.5" fill="#a1a1aa">Claude Code · Codex · Cursor · Cline · Copilot · Antigravity&#160;&#160;&#160;&#160;<tspan fill="#7ee787" font-weight="700">FREE</tspan> Claude / GPT / Gemini · auto-fallback</text>

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@@ -1,13 +1,17 @@
---
title: "Radar Free-Model Catalog"
version: 3.8.50
lastUpdated: 2026-08-13
version: 3.8.51
lastUpdated: 2026-09-01
---
# Radar Free-Model Catalog
> **Source of truth:** `src/lib/radar/`, `src/lib/db/radar.ts`, `src/app/api/radar/`
> **Last updated:** 2026-08-13 — v3.8.50
> **Last updated:** 2026-09-01 — v3.8.51
> **Hosted-service evidence boundary:** server-side rules described here were verified on
> 2026-09-01 against the intentionally private Radar server at exact revision
> `main@dce70f004364912f3f144cdb69f4cbcde16093ed`. That implementation is not distributed in
> this OSS repository; hosted availability remains a separate operational state.
Radar is an **optional add-on** that overlays a signed, freshly-curated free-model
catalog on top of the release baseline (`FREE_MODEL_BUDGETS` in
@@ -24,7 +28,7 @@ is never mutated on disk — see
---
## Delivery status in v3.8.50
## Delivery status in v3.8.51
The following status distinguishes what this OSS release implements from later Radar
workstreams. It is a code-level status, not a promise that a particular hosted deployment
@@ -109,10 +113,17 @@ When both are on, the sync path is:
`Authorization: Bearer <supporter key>` header (see below). Servers default to the separately
signed v1 transition artifact when the schema header is absent, so older installed clients keep
receiving updates.
2. Nothing about the request, the operator, or their traffic is uploaded — it is a
plain, unauthenticated-by-default GET. OmniRoute never posts usage data, provider
configuration, or model traffic to the feed service.
3. The response is verified, validated, and cached locally (see
2. This is a download-only application flow, but it is still an HTTPS request. The hosted
infrastructure receives ordinary connection metadata such as the source IP. When a supporter
key is configured, sync also sends that key in the Bearer header so the service can resolve the
entitlement. At the exact private-server revision identified in the evidence boundary above,
feed-request accounting uses key hashes, aggregate usage, and a daily rotating truncated HMAC
of the IP for manual abuse review; those tables persist neither the key nor the IP in raw form.
Infrastructure access logs and the encrypted delivery outbox are separate operational
boundaries.
3. OmniRoute never sends prompts, responses, conversations, provider credentials, model traffic,
uptime, latency, or the local provider configuration to the Radar service.
4. The response is verified, validated, and cached locally (see
[Security model](#security-model)). Radar has exactly four server-side network paths:
`syncRadar()` for the catalog, `syncRadarReferrals()` for referrals, and
`syncRadarOffers()` / `syncRadarIntel()` for supporter-only offers and Intel.
@@ -133,6 +144,42 @@ that lets the feed service decide which tier to serve (see
---
## Access and safety rules shown before opt-in
The inactive dashboard renders these rules from
`src/app/(dashboard)/dashboard/radar/RadarAccessExplainer.tsx` **before** either activation action.
The canonical access scale is:
| Level | Eligibility | Access | Repeat/expiration rule |
| --------------------- | --------------------------------------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------- |
| Community | Anyone; no key | Complete catalog delayed by about 30 days | Always available; no issuance |
| Star + follow | GitHub OAuth verifies both a star on the repository and a follow of the owner | One live catalog read, then Community | One issuance per login; never reissued |
| Contributor Top 10 | Positions 110 in the latest complete weekly ranking | 365 live days | Claimed on demand; leaving the ranking does not shorten an awarded period |
| Contributor Top 100 | Positions 11100 in that ranking | 90 live days | Same on-demand/idempotent claim rule |
| Supporter purchase | One-time 6-month, 1-year, or lifetime purchase | Live catalog, signed live offers, and Intel | No automatic renewal |
| Donation/manual grant | Owner-reviewed donation or an owner grant for an explicit number of days/lifetime | Same live entitlement for the granted period | Audited, idempotent grant |
Merged PRs, commits, and changed lines are **ranking inputs only**. A login outside the Top 100 gets
no contributor grant regardless of PR count. Finite purchases, donations, contributor periods, and
manual grants accumulate from the current expiration; lifetime dominates. A rank change never
retroactively revokes or shortens time already awarded.
The hosted license is personal and the user-facing rule is one active installation at a time. This
release does **not** claim a hardware lock: the OSS sync does not fingerprint hardware or maintain a
cryptographic device lease. At the verified private-server revision above, implemented enforcement
is entitlement validation plus a manual-review signal when the same live key is seen from a fourth
distinct IP within 24 hours. That signal never blocks or revokes a key automatically. Recovery
revokes and replaces the lost key while preserving the existing expiration; it does not restart the
purchased or granted period.
Live offers are manually curated and can change or expire. The opt-in screen also names the exact
privacy boundary: signed catalog/referral metadata is downloaded; a valid key additionally unlocks
signed offers and Intel; the Bearer key and normal connection metadata reach the hosted service;
prompts, responses, conversations, provider credentials, model traffic, uptime, latency, and local
provider configuration do not.
---
## Getting a supporter key
The activation screen (`/dashboard/radar`) links out to two flows for **obtaining** a
@@ -142,11 +189,12 @@ destination pages, not in this repo (spec decision D14).
- **"I'm a contributor"** — opens `RADAR_CONTRIBUTOR_CLAIM_URL` (default
`https://radar.omniroute.online/auth/github`), a GitHub OAuth claim flow hosted on
the private radar server. It verifies the visitor's GitHub account and grants a
supporter key to anyone with 5+ merged pull requests or a top-100 contributor spot
on the repo.
the private Radar server. It checks the latest complete weekly ranking: Top 10 receives 365 days
and positions 11100 receive 90 days. Outside the Top 100, PR count never grants access; the flow
instead checks the separate star + follow single-use level.
- **"Support the project"** — opens `RADAR_SUPPORTER_PLANS_URL` (default
`https://radar.omniroute.online/planos`), the payment/plans page.
`https://radar.omniroute.online/planos`), the hosted page for the one-time 6-month, 1-year, and
lifetime options. The OSS page still displays no monetary value.
Both URLs are resolved server-side (`src/lib/radar/links.ts`, same env-override
pattern as `RADAR_FEED_URL`) and relayed to the dashboard through the existing

View File

@@ -52,7 +52,7 @@ Common problems and solutions for OmniRoute.
```bash
export OMNIROUTE_ROTATE_ON_400=true # hop to another model/provider on 400/401 (skips broken passthrough models)
export OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT=4 # raise the heavyweight admission ceiling (default 1) so long-context bursts are not rejected
export OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT=4 # explicit heavyweight admission ceiling (unset by default: no request-count cap, see note below)
export OMNIROUTE_CHAT_ADMISSION_QUEUE_MS=5000 # longer bounded wait for heavyweight capacity instead of an immediate retryable 503
```
@@ -538,8 +538,12 @@ When many concurrent requests hit a rate-limited provider, OmniRoute uses mutex
- The chat completions endpoint returns a retryable `503` response whose error code is
`chat_admission_busy`.
- The response includes `Retry-After`; the byte-based path uses 2 seconds, while the
structure-based path uses 1 second and includes `reason: "structure_limit"`.
- The response includes `Retry-After`. Since #12135 the value is derived from observed
occupancy — the larger of the `OMNIROUTE_CHAT_ADMISSION_QUEUE_MS` window the request already
waited and the time the current heavyweight leases have been held — rounded up to whole
seconds and capped at 60. On an idle gate it keeps the historical floors: 2 seconds on the
byte-based path, 1 second on the structure-based path (which also includes
`reason: "structure_limit"`).
- This can happen while another heavyweight chat or long-running streaming response is still
in flight.
@@ -556,8 +560,8 @@ The byte-based response body is:
```
The structure-based response uses the same type and code, with the message
`Structurally heavy chat request capacity is busy; retry shortly.` and
`reason: "structure_limit"`.
`Local chat admission capacity is busy for this structurally heavy request; upstream provider routing was not attempted. Retry shortly.`
and `reason: "structure_limit"`.
At the default thresholds, a request is structurally heavy when it has at least `200` messages,
at least `64` tools, or at least `32,000` estimated tokens, or when bounded structure estimation
exhausts its bounds of `10,000` visited nodes or depth `12`.

View File

@@ -63,7 +63,7 @@ changing the server-wide setting for your other clients. On a reference instance
If you would rather fix it server-wide for _every_ client, set the
`MODELS_CATALOG_PREFIX_MODE` feature flag to `alias` in the dashboard. See
[API_REFERENCE → prefix](../reference/API_REFERENCE.md#model-id-prefixes-prefix) for the
query parameter and the warning about `canonical`.
query parameter and the per-mode table.
### It hides models that cannot chat

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

View File

@@ -633,7 +633,6 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **[TS7] fix(types): normalize DuckDuckGo request messages** ([#9847](https://github.com/diegosouzapw/OmniRoute/pull/9847), original [#9797](https://github.com/diegosouzapw/OmniRoute/pull/9797)) — thanks @backryun
- **[TS7] fix(types): expose SQLite transaction state** ([#9848](https://github.com/diegosouzapw/OmniRoute/pull/9848), original [#9796](https://github.com/diegosouzapw/OmniRoute/pull/9796)) — thanks @backryun
- **[TS7] fix(types): validate default executor pool config** ([#9849](https://github.com/diegosouzapw/OmniRoute/pull/9849), original [#9795](https://github.com/diegosouzapw/OmniRoute/pull/9795)) — thanks @backryun
- **[TS7] fix(types): preserve The Old LLM proxy contracts** ([#9850](https://github.com/diegosouzapw/OmniRoute/pull/9850), original [#9793](https://github.com/diegosouzapw/OmniRoute/pull/9793)) — thanks @backryun
- **[TS7] fix(types): normalize Gemini Business credentials** ([#9851](https://github.com/diegosouzapw/OmniRoute/pull/9851), original [#9792](https://github.com/diegosouzapw/OmniRoute/pull/9792)) — thanks @backryun
- **[TS7] fix(types): preserve Claude thinking body contracts** ([#9852](https://github.com/diegosouzapw/OmniRoute/pull/9852), original [#9791](https://github.com/diegosouzapw/OmniRoute/pull/9791)) — thanks @backryun
- **fix(response): strip internal reasoning placeholder from all reasoning fields** ([#9853](https://github.com/diegosouzapw/OmniRoute/pull/9853), original [#9790](https://github.com/diegosouzapw/OmniRoute/pull/9790)) — thanks @adevwithpurpose
@@ -805,7 +804,7 @@ _By commits in `ed2db6cb19..v3.8.50`, author identities consolidated via `.mailm
- **fix(combo):** defer the known-context-overflow hard rejection for compressible requests so compression runs before the final context gate, instead of a raw-body estimate 400'ing generic Responses clients targeting a large model before OmniRoute can shrink it ([#10225](https://github.com/diegosouzapw/OmniRoute/issues/10225))
- **fix(api):** deleting a manually-added custom model no longer tombstones a provider-synced model that shares its id. `DELETE /api/provider-models` is addressed by `provider` + `model` alone, so when both a custom row and a synced row existed for one id it removed both and wrote `isDeleted:true`. `replaceSyncedAvailableModelsForConnection` then filtered that id out of every subsequent re-import, so the provider could never resync — model sync kept reporting `added: N` while the catalog stayed empty and `/v1/models` never listed the model again, even though routing to it still worked. The custom row is now removed first and its presence is treated as the operator's intent, leaving the synced sibling importable; a synced-only delete still tombstones as before (#3199, #3782 unaffected) ([#10228](https://github.com/diegosouzapw/OmniRoute/pull/10228)) — thanks @Neuron-Mr-White
- **Audio Bridge:** fix production transcription self-loop uploads so real audio reaches the configured STT provider instead of falling back to an unavailable-provider stub ([#10229](https://github.com/diegosouzapw/OmniRoute/pull/10229)).
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `tllm/deepseek_v4`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(api):** DeepSeek V4's native `max` reasoning tier is now reachable. DeepSeek accepts `reasoning_effort` `low`/`high`/`max` and maps `medium`/`xhigh` down to `high`, while OmniRoute's canonical vocabulary collapses `max` onto `xhigh` — so `{"effort":"max"}` silently resolved to `high` and the catalog never advertised a `max` tier (or its `<model>-max` variant). Following the existing `extendCodexGpt56EffortValues` precedent, the native tier is now preserved for `deepseek`/`ds` V4 models only; the global effort vocabulary is unchanged, routed namespaces (`openrouter/deepseek/…`, `oc/deepseek-v4-flash-free`) keep the canonical behavior, and an explicit client `reasoning_effort` still wins ([#10230](https://github.com/diegosouzapw/OmniRoute/pull/10230)) — thanks @Neuron-Mr-White
- **fix(providers):** FreeAIAPIKey now targets `api.freeaiapikey.com`, the host upstream names in its `410 endpoint_moved` response — every request through the provider was failing — and its catalog is resynced to the 10 models the live `/v1/models` actually serves ([#10233](https://github.com/diegosouzapw/OmniRoute/pull/10233))
- **fix(providers):** MonsterAPI's deprecation now actually applies — the flag was written as `isDeprecated`, a key no consumer or schema reads, so the provider kept rendering as healthy in the dashboard, the onboarding wizard and the generated provider reference ([#10234](https://github.com/diegosouzapw/OmniRoute/pull/10234))
- **fix(cliproxy):** read platform/arch at runtime via `os.platform()`/`os.arch()` in `binaryManager` so the embedded installer selects the Windows/ARM assets even when the release bundle is built on a Linux runner (fixes #10244)
@@ -2916,7 +2915,6 @@ _Living section — regenerated 2026-07-19 from all 306 cycle commits (bump 2c62
- Stream model health probes for slow providers ([#7377](https://github.com/diegosouzapw/OmniRoute/pull/7377)) — thanks @JxnLexn
- Refresh NVIDIA free metadata and detect catalog drift ([#7378](https://github.com/diegosouzapw/OmniRoute/pull/7378)) — thanks @JxnLexn
- Reject invalid output token budgets ([#7379](https://github.com/diegosouzapw/OmniRoute/pull/7379)) — thanks @JxnLexn
- Honor provider proxies for The Old LLM Vercel blocks ([#7380](https://github.com/diegosouzapw/OmniRoute/pull/7380)) — thanks @JxnLexn
- Restore proxy navigation and sidebar accordion state ([#7381](https://github.com/diegosouzapw/OmniRoute/pull/7381)) — thanks @JxnLexn
- Expose proxy controls for no-auth providers ([#7419](https://github.com/diegosouzapw/OmniRoute/pull/7419)) — thanks @JxnLexn
- Add reasoning-based model and effort routing ([#7607](https://github.com/diegosouzapw/OmniRoute/pull/7607)) — thanks @JxnLexn
@@ -3608,7 +3606,6 @@ Thanks to everyone whose work landed in v3.8.45:
- **feat(api):** expose a read-only provider plugin manifest at `GET /api/v1/provider-plugin-manifest` for sidecar/relay discovery. ([#6001](https://github.com/diegosouzapw/OmniRoute/pull/6001)) (thanks @KooshaPari)
- **feat(sidecar):** advertise the provider manifest URL to Bifrost/CLIProxyAPI via the `X-OmniRoute-Provider-Manifest-Url` header (`OMNIROUTE_PROVIDER_MANIFEST_URL`). ([#6007](https://github.com/diegosouzapw/OmniRoute/pull/6007)) (thanks @KooshaPari)
- **feat(autoCombo):** add a latency/speed-optimized routing mode (shared `rankBySpeed` scoring core) plus the `omniroute_pick_fastest_model` MCP tool. ([#6011](https://github.com/diegosouzapw/OmniRoute/pull/6011)) (thanks @KooshaPari)
- **feat(providers):** refresh The Old LLM (Free) model catalog ([#5181](https://github.com/diegosouzapw/OmniRoute/issues/5181)) — seed the current free `/api/chatgpt` tier (GPT-5/5.1/5.2/5.3/5.4, o3/o4-mini, Gemini 3 Pro / 2.5 Pro / 2.0 Flash / 1.5 Flash, Claude 4.6 Opus/Sonnet & 4.5 Haiku, GPT-4o, Grok 4, DeepSeek V3/R1, Sonar Pro) while keeping the legacy alias IDs for saved-preference compatibility. Also fixes a latent routing bug: `mapModel()` now passes known upstream IDs through unchanged, so Gemini/o-series/Grok/DeepSeek/Sonar models no longer silently collapse onto `GPT_5_4`. Regression guard: `tests/unit/theoldllm-model-refresh-5181.test.ts`. (thanks @WslzGmzs)
- **feat(resilience):** surface Codex **banked reset credits** per connected account ([#5199](https://github.com/diegosouzapw/OmniRoute/issues/5199)) — the Codex quota parsers (`buildCodexUsageQuotas`, `parseCodexUsageResponse`) now additively read `rate_limit_reset_credits.available_count` (+ optional `rate_limit_reached_type`) from the `/wham/usage` payload OmniRoute already fetches, and the provider-limits dashboard renders a **"Banked Reset Credits"** row when a positive count is present. Display-only and **fail-open** — the field is eligibility-gated, so accounts without it are unaffected (parsers never throw on absent/garbage shapes); redemption (an unofficial mutating endpoint) is intentionally out of scope. Regression guard: `tests/unit/codex-banked-reset-credits-5199.test.ts` (8). (thanks @ofekbetzalel)
- **feat(providers):** add sign-up geo-restriction notices for **SenseNova** and **StepFun** ([#5462](https://github.com/diegosouzapw/OmniRoute/issues/5462)) — the provider add-form now warns that SenseNova's console appears to require a Chinese (+86) phone number with no documented international path, and that StepFun's default endpoint is its China platform while a global StepFun Open Platform (`platform.stepfun.ai`, operated by Sparkling AI Pte. Ltd., Singapore) with email/Google/Discord login exists for international users. Informational `notice` only — neither provider is disabled. Regression guard: `tests/unit/regional-provider-cn-notices-5462.test.ts`. (thanks @chirag127)
- **feat(usage):** add on-demand period-scoped usage-data reset (Settings → System Storage) with a purge API and time-window selector. ([#5831](https://github.com/diegosouzapw/OmniRoute/pull/5831))
@@ -5030,7 +5027,6 @@ _See English CHANGELOG for v3.8.32 details._
- **fix(sse): map `reasoning_effort` to DeepSeek V4's native `{high, max}` vocabulary** — DeepSeek V4 only understands `high`/`max` reasoning levels, so other `reasoning_effort` values are mapped onto its native vocabulary instead of being rejected. ([#4219](https://github.com/diegosouzapw/OmniRoute/pull/4219))
- **fix(glm): default `max_tokens` and an extended timeout for GLM-5.2+ thinking** — GLM-5.2+ thinking responses are slow and need headroom, so OmniRoute now sets a sensible default `max_tokens` and a longer timeout for them. ([#4255](https://github.com/diegosouzapw/OmniRoute/pull/4255) — thanks @dhaern)
- **fix(antigravity): default `includeThoughts` for modern Gemini models** — modern Gemini models on the Antigravity path now default to including thoughts so reasoning isn't silently dropped. ([#4180](https://github.com/diegosouzapw/OmniRoute/pull/4180) — thanks @dhaern)
- **fix(provider-registry): add correct `contextLength` to theoldllm models** — fills in accurate context-window sizes for theoldllm's models. ([#4184](https://github.com/diegosouzapw/OmniRoute/pull/4184) — thanks @herjarsa)
- **fix(models): expose combo model token limits**`/v1/models` now reports token limits for combo models. ([#4189](https://github.com/diegosouzapw/OmniRoute/pull/4189) — thanks @megamen32)
- **fix(combo): keep the passthrough quota fallback scoped** — prevents the passthrough quota fallback from leaking across unrelated targets. ([#4194](https://github.com/diegosouzapw/OmniRoute/pull/4194) — thanks @Svetznaniy33)
- **fix(combo): opt proactive-fallback compression into the TV1 bail-out (no silent target drop)** — proactive-fallback compression now participates in the TV1 bail-out so a target is never silently dropped. ([#4228](https://github.com/diegosouzapw/OmniRoute/pull/4228))

View File

@@ -4,7 +4,7 @@
---
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 352 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
> OmniRoute is a free, open-source AI Gateway that acts as a universal API proxy for multi-provider LLMs. It provides smart routing, automatic fallback, load balancing, and format translation across 354 AI providers — all through a single OpenAI-compatible endpoint. Includes a built-in MCP Server (110 tools), A2A v0.3 protocol, Memory/Skills systems, Cloud Agents (codex, cursor, devin, jules), Guardrails framework, and an Electron desktop app.
## Overview
@@ -281,7 +281,7 @@ OmniRoute solves the problem of managing multiple AI provider subscriptions, quo
## Key Features (v3.8.50)
### Core Proxy
- **352 AI providers** with automatic format translation
- **354 AI providers** with automatic format translation
- **Provider categories**: Free (90+ free tiers), OAuth, API Key, Self-Hosted, Custom (OpenAI/Anthropic-compatible)
- **19 routing strategies**: priority, weighted, round-robin, fill-first, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline
- **4-tier fallback**: Subscription → API Key → Cheap → Free

Some files were not shown because too many files have changed in this diff Show More