Skip to content

Release v3.8.26 - #3875

Merged
diegosouzapw merged 48 commits into
mainfrom
release/v3.8.26
Jun 16, 2026
Merged

diegosouzapw merged 48 commits into
mainfrom
release/v3.8.26

Conversation

@diegosouzapw

@diegosouzapw diegosouzapw commented Jun 15, 2026 •

Copy link
Copy Markdown
Collaborator

Release v3.8.26 — release/v3.8.26 → main. Final release notes (reconciled at release time).

[3.8.26] — 2026-06-15

✨ New Features

  • feat(media): Vertex AI (Google) speech, transcription, music & video generation — Vertex AI's Google media models are now routable through dynamic discovery: speech synthesis, audio transcription, music generation, and video generation. (#3929 — thanks @artickc)
  • feat(glm): add GLM-5.2 with effort-tier routing (high/max) — GLM-5.2 is registered with high/max effort-tier routing. (#3885 — thanks @dhaern)
  • feat(combo): add a sticky round-robin target limit — round-robin combos can cap how many targets stay "sticky" within a session (stickyRoundRobinLimit), balancing stickiness against spread. (#3846 — thanks @adivekar-utexas)
  • feat(openrouter): connection presets — OpenRouter connections support reusable presets (provider routing / sort / quantization preferences), selectable when adding a connection. (#3878 — thanks @rdself)

🐛 Fixed

  • fix(compression/memory): stop memory + compression from poisoning the upstream prompt cache — with compression and/or memory enabled, requests to caching providers (Anthropic-family) missed the prompt cache on every turn, multiplying cost. Two root causes: (1) memory injection prepended the retrieved memories — which vary per user query — at index 0 of the message array, shifting the entire cacheable prefix every turn; memory is now inserted just before the last user message when the request carries cache_control breakpoints, keeping the cacheable prefix (system prompt + prior turns) byte-stable. (2) the cache-aware skipSystemPrompt flag computed by getCacheAwareStrategy() was dropped by selectCompressionStrategy() (which can only return a mode), so the system prompt could still be compressed under caching; a new resolveCacheAwareConfig() now forces preserveSystemPrompt on for caching requests. (#3936, closes #3890 — thanks @xenstar / @diegosouzapw)
  • fix(providers): register BytePlus ModelArk so its API key can be added — adding a BytePlus (ark-…) key reported "invalid". byteplus was present in the provider catalog (APIKEY_PROVIDERS) but never registered in the routing registry, so key validation fell through to { unsupported: true } → HTTP 400 → the UI rendered every key as invalid (and the provider was unusable for inference). Added a registry entry modeled on the existing Volcengine Ark provider: OpenAI-compatible format, base https://ark.ap-southeast.bytepluses.com/api/v3 (region ap-southeast-1), Authorization: Bearer auth, seeded with the catalog's advertised models (Seed 2.0, Kimi K2 Thinking, GLM 4.7, GPT-OSS-120B). (#3935, closes #3877 — thanks @nikohd12 / @diegosouzapw)
  • fix(providers): Nous Research key validation no longer fails on a stale probe model — adding a valid Nous Research API key reported "invalid" even though the same key worked via the portal's copy-shell curl. The validation probe sent model: "nousresearch/hermes-4-70b", which Nous does not serve, so the API returned 400 and the validator (which only treated 200/429 as success) reported the key invalid. The probe now uses the real Hermes-4-70B slug, and any non-auth 4xx (400/404/422) is treated as a valid key (the request shape was wrong, not the credentials) — mirroring the longcat/nvidia validators so a future model rename can't re-break key validation. (#3934, closes #3881 — thanks @FerLuisxd / @diegosouzapw)
  • fix(stream): persist mid-stream upstream failures — when an upstream stream fails partway through, the partial response and incremental usage are now finalized and persisted instead of lost; extracts a shared streamFailureFinalization path and merges incremental Claude usage (follow-up to fix: stabilize reasoning streams and request logs #3879). (#3937 — thanks @rdself)
  • fix(perplexity-web): update the request payload to schema v2.18 (HTTP 400) — Perplexity web requests started returning HTTP 400; the request payload was updated to Perplexity's v2.18 schema. (#3938 — thanks @artickc)
  • fix(stream): keep the in-flight request payload in sync — the pending-by-id request record is now updated in place (Object.assign) so the in-flight payload stays consistent with what was dispatched (coexists with fix(stream): persist mid-stream failures #3937). (#3940 — thanks @rdself)
  • fix: stabilize reasoning streams and request logs — reasoning-token streaming and the request-log capture path were stabilized to avoid dropped/duplicated reasoning frames and inconsistent log entries. (#3879 — thanks @rdself)
  • fix(opencode-plugin): include nested combo-refs in the LCD context window — the OpenCode plugin now follows nested combo references when computing the least-common-denominator context window, so a combo nested inside another no longer reports an inflated window. (#3910 — thanks @herjarsa)
  • fix(models): correct the failed-model auto-hide defaults — the defaults governing when a failed model is auto-hidden were corrected, and auto-hide is now opt-in so models are no longer dropped unexpectedly. (#3930 — thanks @rdself)
  • fix(openrouter): show the preset field when editing a connection — the connection-preset field appeared only when creating a connection, not when editing one; it now appears in both (follow-up to feat(openrouter): add connection preset support #3878). (#3921 — thanks @rdself)
  • fix(sse): announce the assistant role on the first delta (Responses→Chat) — the first SSE delta of a Responses-API→Chat-Completions stream now carries role: "assistant", which strict OpenAI-compatible clients expect before content deltas. (#3911 — thanks @diego-anselmo)
  • fix(vertex): add the generative-language scope so SA-JSON model discovery works — Vertex service-account (SA-JSON) model discovery failed without the generative-language OAuth scope; the scope is now requested. (#3922 — thanks @artickc)
  • fix(proxy): direct-connection fallback for control-plane ops when a pinned proxy is unreachable — control-plane operations (validation, discovery) now fall back to a direct connection when a connection's pinned proxy is unreachable, instead of failing outright. (#3906 — thanks @zhiru)
  • fix(providers): prevent zombie-socket hangs for zai/glm and tighten the default keepAlive — zai/glm could hang on dead keep-alive sockets; the default keepAlive was tightened to evict zombie sockets. (#3907 — thanks @insoln)
  • fix(setup): remove the stale CJS bundle check from setup-open-code — the OpenCode setup helper no longer checks for a CJS bundle that the now ESM-only plugin no longer ships. (#3908 — thanks @herjarsa)
  • fix(opencode-plugin): drop the CJS bundle to fix the OpenCode plugin loader — the plugin is now ESM-only, fixing the OpenCode loader which failed on the dual CJS/ESM build. (#3883 — thanks @herjarsa)
  • fix(mcp): fall back to node:sqlite when the better-sqlite3 binding is missing — the MCP server now falls back to Node's built-in node:sqlite when the native better-sqlite3 binding is unavailable, instead of crashing. (#3887 — thanks @megamen32)
  • fix(models): correct the generate-models alias lookup — alias resolution during model generation was corrected so aliased model ids resolve to their canonical entry. (#3870 — thanks @YunyunZhai)
  • fix(combo): guard the candidate pool against an empty array — combo candidate-pool selection no longer throws when the pool resolves to an empty array. (#3871 — thanks @YunyunZhai)

🔒 Security & Hardening

  • fix(security): bump form-data + vite (2 HIGH), harden workflow template-injection & allowlist guarded workflow_run — two HIGH Dependabot advisories (form-data, vite) were upgraded; GitHub Actions workflows were hardened against ${{ }} template-injection (untrusted values now passed via env:); and the guarded workflow_run trigger was allowlisted. (#3949 — thanks @diegosouzapw)

🧹 Internal / Quality / Docs

  • fix(ci): grant contents: write to the npm publish job for SBOM attach — the v3.8.25 TokenPermissions hardening set the npm-publish publish job to contents: read, but its "Attach SBOM to GitHub Release" step (gh release upload) needs contents: write and failed with HTTP 403 on the v3.8.25 release (npm / GitHub Packages / opencode-plugin / Docker / Electron all published fine; only the SBOM attach broke — the v3.8.25 SBOM was attached manually). (#3874 — thanks @diegosouzapw)
  • fix(providers): keep the /v1/models catalog alias-only (release-time follow-up to Fix/generate models alias lookup #3870) — Fix/generate models alias lookup #3870 made generateModels() also key the registry by each provider's raw id, which surfaced phantom opencode/* entries in /v1/models that collide with the opencode/ → opencode-zen route (a regression vs v3.8.25, caught by the [BUG] Models from "OpenCode Free" provider are active in UI but return an empty list in /v1/models #2798 catalog regression test). getProviderModels() now resolves a raw provider id to its alias at lookup time instead of mirroring raw-id keys into the model namespace, preserving Fix/generate models alias lookup #3870's intent (getProviderModels("github") returns the same models as the gh alias) without polluting the public catalog. (#3870 — thanks @diegosouzapw / @YunyunZhai)
  • ci(quality): make zizmor / gitleaks / osv scanners functional + freeze advisory baselines — the supply-chain scanners are now actually executed (correct install + invocation) with frozen advisory baselines so new findings surface as diffs. (#3947 — thanks @diegosouzapw)
  • ci(quality): fix scanner install + size-limit preset, promote codeqlAlerts to blocking — corrected the scanner install and the size-limit preset, and promoted the codeqlAlerts ratchet from advisory to blocking. (#3945 — thanks @diegosouzapw)
  • ci(quality): add an OpenAPI breaking-change gate (oasdiff, advisory) + fix dangling $refs — a CI gate diffs the OpenAPI spec against the base branch (BASE_REF) with oasdiff to surface breaking API changes, and the spec's dangling $refs were repaired. (#3951 — thanks @diegosouzapw)
  • ci(quality): add a schemathesis API-fuzz nightly (advisory) — a nightly schemathesis property/fuzz pass against the OpenAPI spec (Quality Gates Fase 8 · Bloco B.4, advisory). (#3956 — thanks @diegosouzapw)
  • ci(quality): wire Stryker mutation testing as an advisory nightly — Stryker mutation testing runs nightly (advisory) — Quality Gates Fase 7 · Task 11. (#3898 — thanks @diegosouzapw)
  • ci(quality): freeze per-module coverage floors + wire require-tighten (advisory) — per-module coverage floors are frozen with an advisory "require-tighten" check that flags modules drifting below their floor. (#3901 — thanks @diegosouzapw)
  • ci(quality): enforce the stale-allowlist check on check-known-symbols — stale allowlist entries (suppressing a symbol that no longer exists) now fail the gate — Fase 6A.3 follow-up. (#3899 — thanks @diegosouzapw)
  • test(ci): de-flake pipeline-payloads via per-test re-seed + honest reset — the pipeline-payloads suite now re-seeds per test and performs an honest cache reset, eliminating a cross-test ordering flake. (#3893 — thanks @diegosouzapw)
  • fix(ci): drop the secrets-in-job-if from nightly-llm-security — referencing secrets in a job-level if caused a startup_failure on push; the gating was moved so the workflow starts cleanly. (#3892 — thanks @diegosouzapw)
  • test: reconcile the runtime-timeouts keepAlive baseline to 4000 after the fix(providers): prevent zombie-socket hangs for zai/glm and tighten default keepAlive #3907 source revert — the keepAlive assertion was realigned to the source value (4000) after fix(providers): prevent zombie-socket hangs for zai/glm and tighten default keepAlive #3907's source-side revert. (#3933 — thanks @diegosouzapw)
  • chore(repo): nest quality-gate state under config/quality, declutter the repo root — baselines / allowlists / metrics moved under config/quality/, trimming the tracked root file count. (#3896 — thanks @diegosouzapw)
  • docs: refresh the provider count to 226 + regenerate PROVIDER_REFERENCE.md — the README advertised a stale 177 providers; the canonical generator (scripts/docs/gen-provider-reference.ts) now reports 226 unique provider IDs, so the README badges/anchors and the generated provider reference were brought in sync. Also adds a documentation audit/sync report. (thanks @diegosouzapw)
  • docs: sync all documentation to v3.8.24 + count-guard & wiki/prose CI — a full documentation sync with a strict provider/locale count-guard plus Vale / markdownlint prose CI. (#3804 — thanks @diegosouzapw)
  • docs: regenerate stale counts to canonical values — 226 providers / 87 MCP tools / 15 strategies / 42 locales. (#3904 — thanks @diegosouzapw)
  • docs(quality): correct the stale gate count + add an opt-in agent-lsp scaffold — (#3902 — thanks @diegosouzapw)
  • docs(mcp): correct the MCP tool-inventory diagram source + text to 87 tools — (#3909 — thanks @diegosouzapw)
  • docs: update the compression section to the 9-engine multi-layer stack — (#3894 — thanks @diegosouzapw)
  • ci(docs): automate GitHub wiki sync (add missing pages + cover counts) — (#3900 — thanks @diegosouzapw)
  • docs: require a dedicated git worktree + branch per development task (Hard Rule docs: add npm badge, CLI options, and release workflow to README #19) — codifies the worktree-isolation rule after the shared-checkout incidents. (#3939 — thanks @diegosouzapw)
  • fix(docs): add MDX frontmatter to DOCUMENTATION_AUDIT_REPORT so the fumadocs build passes — the audit report lacked the title: frontmatter MDX pages require. (thanks @diegosouzapw)

[3.8.25] — 2026-06-14

✨ New Features

  • feat(compression): pluggable compression engines + async pipeline + Compression Studios — a new prompt-compression subsystem with selectable engines (Lite / Aggressive / Ultra), an asynchronous compression pipeline wired into the chat core, and "Compression Studios" tooling for inspecting and tuning compression. (#3848)
  • feat(compression-ui): unified compression configuration UI — a Compression Hub with per-engine pages (Lite / Aggressive / Ultra), a combos editor, a dedicated sidebar entry, and live-WS default-on. (#3860)
  • feat(security): prompt-injection guard across every LLM route + red-team suite — the prompt-injection guard now runs on all LLM routes (chat, responses, embeddings, images, audio, rerank, search, moderations, videos, music) with a shared input sanitizer and a promptfoo-based red-team suite (Quality Gates Fase 8 · Bloco D). (#3857)
  • feat(kiro): live per-account model discovery — Kiro now discovers each account/tier's entitled models via CodeWhisperer ListAvailableModels (region-matched, with a static-catalog fallback). (#3836 — thanks @artickc)
  • feat(gemini/vertex): surface Veo video models in dynamic discovery — Veo video models (predictLongRunning) now appear in Gemini/Vertex dynamic model discovery. (#3839 — thanks @artickc)
  • feat(mimocode): per-account proxy for multi-account round-robin — each mimocode account can route through its own proxy (resolved per account by fingerprint via runWithProxyContext), with a "Distribute proxies" UI helper. (#3837 — thanks @pizzav-xyz)
  • feat(intelligence): expose Arena ELO sync as a feature flag — the LM Arena ELO leaderboard sync is now toggleable (ARENA_ELO_SYNC_ENABLED, DB-override + env fallback). (#3821 — thanks @rdself)

🐛 Fixed

  • test(oauth): prove refresh_token preservation for the real gemini-cli / antigravity dispatch — the [BUG] [BUG] Google OAuth refresh_token not persisted — connections die after 2–3 refresh cycles #3679/fix(oauth): preserve non-rotating providers' refresh_token on unrecoverable refresh (#3679) #3766 regression test used a synthetic provider that routes through the generic tokenUrl path, so the fix was never proven for the actual Google-family providers, which dispatch through refreshGoogleToken() against the hardcoded OAUTH_ENDPOINTS.google.token. Added a test that drives checkConnection through the real gemini-cli/antigravity path (redirecting the Google token endpoint to a local server returning invalid_grant) and asserts the refresh_token is preserved (not nulled) — confirming these connections are not spuriously destroyed on a failed refresh. (#3850 — thanks @3xa228148)
  • fix(oauth): clear setup message for GitLab Duo instead of "Internal server error" — adding a GitLab Duo connection without a registered OAuth client returned an opaque Internal server error at the Add Connection step. buildAuthUrl threw when GITLAB_DUO_OAUTH_CLIENT_ID was missing, and the route swallowed it into a generic 500. It now returns null (mirroring the Qoder provider) and the authorize route surfaces an actionable message: register an OAuth app at https://gitlab.com/-/profile/applications with redirect URI http://localhost:20128/callback and scopes ai_features read_user, then set GITLAB_DUO_OAUTH_CLIENT_ID. (#3861 — thanks @sidinsearch)
  • fix(db): persist the "Keep latest backups" retention setting — changing the backup-retention count in Settings → Database backup retention had no effect: it always snapped back to 20 on refresh (and editing .env post-start was ignored too, since process.env isn't reloaded). getDbBackupMaxFiles() only read the DB_BACKUP_MAX_FILES env var — there was no setter and no persisted value. The value now round-trips through a dedicated key_value store (getDbBackupMaxFiles precedence: env override → persisted UI value → default 20), and the "Clean old backups" action persists the chosen count. Existing installs keep the historical default of 20 until explicitly changed. (#3834 — thanks @netstratego)
  • fix(sse): clamp Gemini thinking budget to the model's real cap (reasoning_effort/effort=high 400) — translating OpenAI reasoning_effort=high (and Claude-Code output_config.effort=high) to a Gemini target sent a hardcoded thinkingBudget: 32768, which exceeds Flash-tier Gemini's real max of 24576 → upstream HTTP 400 (the thinkingLevel=high path already used 24576 and worked on the same model). gemini-2.5-flash now declares its real thinkingBudgetCap (24576) so the existing capThinkingBudget() chokepoint actually clamps, and the Claude→Gemini output_config.effort path — which previously sent the raw value with no cap at all — now routes through the same clamp (pro-tier, real cap 32768, is left untouched). (#3842 — thanks @andrea-kingautomation)
  • fix(intelligence): run pricing + models.dev sync from the live startup path — like the Arena ELO sync (v3.8.24), the external pricing sync (PRICING_SYNC_ENABLED) and the models.dev capability sync (Settings → AI toggle) were only initialized from server-init.ts, which the Next standalone runtime never executes — and models.dev had no caller at all. Their toggles were inert in production. Both are now initialized from instrumentation-node.ts (self-gated, opt-in preserved, non-blocking, never fatal). (thanks @diegosouzapw)
  • test(proxy): guard the per-connection 'direct' bypass over a global proxy + clearer label — the per-connection "Proxy Off" toggle (proxyEnabled: false) already overrides a configured global proxy (resolveProxyForConnection short-circuits to level: "direct" before the global step). Added an explicit regression test proving the bypass beats a global assignment (and round-trips on re-enable), and relabeled the UI to "Direct (bypass proxy)" so operators recognize it. Closes the verification gap in #2996. (thanks @diegosouzapw)
  • feat(connections): per-connection "disable cooldown" opt-out — a connection can now opt out of the transient cooldown (providerSpecificData.disableCooling, with a toggle in the Edit Connection modal). When set, a recoverable failure still records the error/backoff but does not take the connection out of rotation, so it stays eligible for selection — useful for a primary key you never want parked on a blip. Terminal states (banned / expired / credits_exhausted) still apply. (#2997 — thanks @diegosouzapw)
  • fix(combo): restore sessionless combo stickiness + reasoning-aware readiness (504 / TPS regression after v3.8.14) — fix: server-side context cache pinning, stop proxy message leaks, persist context_cache_protection toggle #3399 (v3.8.16) replaced the <omniModel>-tag combo pinning with a server-side context-cache pin gated on a client sessionId. Clients that send no session id (most OpenAI-compatible tools) lost combo stickiness, so combos re-ran strategy selection every turn → upstream prompt-cache misses → cold high-reasoning starts (~78s) → intermittent [504] Upstream request did not return response headers + TPS collapse (only on combos). The pin now falls back to a stable per-conversation fingerprint (extractSessionAffinityKey(body)) when no session id is present — only when context_cache_protection is on, so fix: server-side context cache pinning, stop proxy message leaks, persist context_cache_protection toggle #3399's anti-leak behaviour is preserved. Separately, the stream-readiness window now grants the +30s reasoning budget unconditionally for high-reasoning Codex GPT-5.x (small high-reasoning prompts were 504-ing at the 80s base regardless of stickiness). (#3825 — thanks @bypanghu)
  • test(combo): cover the skipProviderBreaker consumer gate — the producer was tested but the consumer (whether a failed combo target trips the whole-provider circuit breaker) was not; the breaker decision is now an exported pure predicate (shouldRecordProviderBreakerFailure, behaviour-identical) with direct tests asserting a connection_cooldown 503 does not trip the breaker while a plain 503 does. Closes another deferred test gap from #2743. (thanks @diegosouzapw)
  • fix(providers): surface the real Devin error + correct the Windsurf auth instructions — Devin chat returned a generic 502 "Invalid SSE response for non-streaming request" that swallowed the real cause (e.g. "Devin CLI not found"): an error-only SSE chunk (no choices) is now propagated with its sanitized message. The Windsurf "Visit windsurf.com/show-auth-token" instruction (the bare URL shows no token without an IDE-supplied ?state=) now directs users to the Windsurf: Provide Auth Token command-palette flow. (#3324 — thanks @mikmaneggahommie)
  • fix(grok-web): clearer 403 message for anti-bot / IP-reputation blocks — a Grok Web subscription validating from a flagged datacenter/VPS IP got a 403 that read like an invalid cookie, sending users to chase a cookie that was actually fine. A non-auth 403 (Cloudflare challenge / anti-bot body) now returns a message stating the cookie is likely OK and the block is IP-reputation-based — retry from a residential IP or configure a proxy (auth-shaped 403s keep the re-paste guidance). (#3474 — thanks @friedtofu1608)
  • fix(db): make the mass-pending-migrations safety threshold env-overridable — restoring a backup DB from an older version could trip "Detected N pending migrations … threshold is 50" with no way to override the hardcoded 50. The threshold is now configurable via OMNIROUTE_MAX_PENDING_MIGRATIONS (resolved at startup; 0 disables the check). (#3416 — thanks @samuraiIT)
  • test(proxy): cover the Vercel-relay proxyFetch path — net-new tests for buildVercelRelayHeaders and the vercel-type relay short-circuit (x-relay-target/-path/-auth, TCP-skip, missing-auth fail-closed), closing one of the deferred test gaps tracked in #2743. (thanks @diegosouzapw)
  • fix(cli): surface omniroute runtime repair in the native-module error messages — after a Node major upgrade, better-sqlite3's prebuilt binary mismatches the ABI and the service can crash-loop; the error only mentioned npm rebuild better-sqlite3 (which fails for global / no-toolchain installs). The startup + SQLite error hints now also point to the existing self-heal command omniroute runtime repair (rebuilds into a user-writable runtime), and a top-level omniroute repair alias was added. (#3476 — thanks @Rahulsharma0810)
  • fix(antigravity): per-request Pro-family upstream-id fallback chain (gemini-3.1-pro-high 400) — Antigravity silently renamed the Gemini 3.1 Pro-high upstream id, so gemini-3.1-pro-high started returning HTTP 400 (while -low still worked) and the live id can't be determined statically (competitor proxies disagree). The executor now retries alternative ids on a 400 (gemini-3.1-pro-high → gemini-pro-agent → gemini-3-pro-high, analogous for pro-low), bounded and only on a 400, with zero extra cost on the happy path; the 1:1 tier-passthrough invariant is preserved (the chain is request-time, not a static alias remap). (#3786 — thanks @aliaksandrsen)
  • fix(sse): retry once on an early stream close (STREAM_EARLY_EOF) for single-model requests — flaky OpenAI-compatible upstreams (e.g. NVIDIA NIM with minimax-m3 / qwen3.5 / glm-5.1) intermittently send HTTP 200 then close the SSE with zero useful frames, surfacing as a 502 "Stream ended before producing useful content". Only Antigravity got an early-close retry; every other provider returned the 502 immediately on the non-combo single-model path. A bounded one-retry (early-close only — not readiness-timeout — and without marking the account unavailable) now generalizes it. (The separate qwen-web validation SSRF part of the same report was already fixed in v3.8.24, #3767.) (#3758 — thanks @Svatosalav)
  • fix(models): preserve eye-hidden models across auto-sync / import — hiding models via the visibility (eye) toggle to keep only a combo's models was undone on every model import or auto-sync, which re-showed all of them. The sync re-import treated "hidden" identically to "deleted" and dropped both; a distinct isDeleted marker now separates the trash/delete path (still dropped on re-import, [BUG] model cannot delete in llamacpp #3199) from the eye toggle (preserved as listed-but-hidden), and eye-hidden models are no longer re-aliased into the routable catalog on sync. (#3782 — thanks @xenstar)
  • fix(providers): correct the lmarena cookie hint (session → arena-auth-prod-v1) — the lmarena credential hint asked for a cookie named session, but lmarena.ai's real auth cookie is arena-auth-prod-v1, so users who pasted only session=… hit validation failures. The credential name, placeholder and storage keys now use the correct name (the legacy session key is retained for back-compat with already-saved credentials). (#3810 — thanks @xspylol)
  • fix(reasoning): normalize OpenAI-compatible max effort to xhigh by default — OpenAI-compatible providers do not accept literal max, but some upstreams (for example DeepSeek through OpenRouter) support xhigh; max now maps to xhigh unless the target model explicitly opts out of xhigh, with Claude alias variants still honoring the canonical Claude opt-out list. (#3826 — thanks @rdself)
  • fix(combo): return the replay response on the round-robin streaming path — a round-robin combo with a streaming target returned a body already locked by the readiness peek, surfacing as a 500 "ReadableStream is locked"; the round-robin path now returns the replay clone like the priority path does. (#3811 — thanks @0xtbug)
  • fix(claude): strip the reasoning-effort suffix from Claude model ids — Claude ids carrying an effort suffix (…-low … …-max) 404'd upstream and tripped the circuit breaker into a misleading "rate-limited" state; the suffix is now stripped before dispatch. (#3807 — thanks @zhiru)
  • fix(sse): flush routed SSE chunks promptly (ping/zombie readiness filter) — combo stream-readiness now filters ping/zombie frames so routed SSE chunks stream out without waiting on the readiness window. (#3759 — thanks @rdself)
  • fix(models): don't auto-hide transient (rate-limited / timeout) failures on Test All — a parallel Test All across many models could rate-limit an account and auto-hide every model that 429'd / timed out (dropping them from /v1/models); transient failures now surface an error state but stay visible. (#3849 — thanks @lukmanc405)
  • fix(quota): surface OpenCode Go's missing quota-API as a latched diagnostic — OpenCode Go keys whose quota endpoints return 404/401 no longer hammer the dead endpoints; the gap is latched with a clear message and an OMNIROUTE_OPENCODE_GO_QUOTA_URL override hint. (#3838 — thanks @adivekar-utexas)
  • fix(pricing): add the missing Kiro model pricing rows — Kiro models the registry serves (e.g. claude-sonnet-4.6) had no pricing row and reported $0.00; the rows were added. (#3835 — thanks @artickc)
  • fix(ui): render country flags via flagcdn SVGs for Windows compatibility — Windows doesn't render regional-indicator flag emoji; flags now use flagcdn SVGs with an emoji fallback. (#3814 — thanks @rafacpti23)
  • fix(ui): expand the request log table with a vertical resize handle — the request log table now shows ~10 rows and can be resized vertically. (#3820 — thanks @rafacpti23)
  • fix(i18n): translate the missing embeddedServices keys across 37 locales — the embeddedServices strings showed __MISSING__ in 37 locales; they are now translated. (#3819 — thanks @rafacpti23)

🔒 Security & Hardening

  • fix(security): CCR cross-tenant IDOR — per-principal scope store + bounded memory — the compression CCR scope store was shared across principals, allowing cross-tenant reads; it is now scoped per-principal with bounded memory. (#3859)
  • feat(supply-chain): build provenance, SBOM, Trivy scan & OpenSSF Scorecard (advisory) — added npm build provenance, a CycloneDX SBOM, Trivy image scanning, and an OpenSSF Scorecard workflow (Quality Gates Fase 8 · Bloco A, advisory). (#3824)

🧹 Internal / Quality / Docs

  • Consolidate the email-privacy control into Settings → Appearance — the per-page email-privacy toggles were replaced by a single global switch. (#3822 — thanks @rdself)
  • docs(ui): clarify the routing-settings copy (strategy sync + sticky limit) — (#3843 — thanks @adivekar-utexas)
  • Quality Gates — Fase 7 & 8 — promoted the dead-code / cognitive-complexity / type-coverage ratchets to blocking, installed advisory CI scanners (gitleaks / osv / actionlint / zizmor), and added property + golden + SSE-correctness tests and a runtime-resilience (chaos / heap-growth / k6 soak) suite. (#3809, #3858, #3808, #3854)
  • fix(docs): add MDX frontmatter to SUPPLY_CHAIN.md — the new security doc lacked the title: frontmatter that MDX pages require, which broke the production Build + Docker Hub publish; the frontmatter was added. (#3864)
  • chore(deps): bump aquasecurity/trivy-action 0.28.0 → 0.36.0 (#3862)
  • chore(quality): reconcile the file-size ratchet baseline for Prettier-inflated v3.8.25 fixes + chat.ts growth — the per-file size baseline was re-frozen to absorb the formatting/line-count growth from this cycle's chat-core and combo fixes (manual edits, never an automatic upward ratchet). (#3823, #3833 — thanks @diegosouzapw)
  • test(suite): green the unit suite at release time — align stale tests to this cycle's intended behavior + de-flake two new suites — release-gate housekeeping: updated tests that lagged behind intended behavior changes (OpenCode Go latched quota message fix(quota): surface OpenCode Go missing-quota-API as a latched warning #3838, the email-privacy control consolidated into Settings Consolidate email privacy control #3822, SOCKS5 default-on proxy-type message, the [id] provider-detail strangler-fig decomposition [refactor] Decompose providers/[id]/page.tsx god-component (12,882 LOC → ≤800, phased/strangler) #3501, Vertex Express-mode keys, Antigravity discovery using a current user-callable model id) and the same-provider 503 fall-through resilience test; de-flaked the compression benchmark reproducibility test (sequential passes) and the ServiceSupervisor crash test (poll instead of fixed sleep). No production code changed. Also documented OMNIROUTE_MAX_PENDING_MIGRATIONS ([BUG] v3.8.15 — Server exits immediately under systemd (Linux, production) #3416) in .env.example + ENVIRONMENT.md. (thanks @diegosouzapw)

🙌 Contributors

Huge thanks to everyone whose work shipped in v3.8.26:

Contributor PRs / Issues
@artickc #3929, #3922, #3938
@rdself #3878, #3879, #3921, #3930, #3937, #3940
@herjarsa #3883, #3908, #3910
@YunyunZhai #3870, #3871
@dhaern #3885
@adivekar-utexas #3846
@megamen32 #3887
@zhiru #3906
@insoln #3907
@diego-anselmo #3911
@xenstar reported #3890 (compression cache)
@nikohd12 reported #3877 (BytePlus)
@FerLuisxd reported #3881 (Nous Research)
@diegosouzapw maintainer — release engineering, quality gates, security hardening, docs

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request bumps the project version from 3.8.25 to 3.8.26 across multiple package files, lockfiles, OpenAPI specifications, and localized changelogs. It also documents a CI fix in the main CHANGELOG regarding granting write permissions to the npm publish job for SBOM attachment. I have no feedback to provide as there are no review comments.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@github-actions

github-actions Bot commented Jun 15, 2026 •

Copy link
Copy Markdown
Contributor

CI Coverage Report

  • Coverage job: success
  • PR test policy: success

Coverage artifact was not available for this run.

diegosouzapw and others added 26 commits June 15, 2026 09:11
…d docs audit report

- README advertised a stale '177 providers'; the canonical generator
  (gen-provider-reference.ts) reports 226 unique provider IDs. Updated the README
  badges/anchors/heading and regenerated docs/reference/PROVIDER_REFERENCE.md (223→226)
  to match the source of truth.
- Adds DOCUMENTATION_AUDIT_REPORT.md (docs/i18n sync audit + plan).

Docs-only; carried over from in-progress working-tree changes and verified against the
generator.
…3894)

Document the real pipeline (Session-Dedup, CCR, RTK, Headroom, Caveman,
LLMLingua-2, Lite, Aggressive, Ultra) that replaced the old RTK+Caveman
framing; presets table kept. '7 options' -> '9 engines'.
…root (#3896)

Move the committed quality-gate state files out of the repo root into
config/quality/ and the v3.8.24 documentation audit into docs/ops/, then
re-point every gate script, test and .gitignore entry at the new paths.
Refresh docs/architecture/REPOSITORY_MAP.md (stale since v3.8.2) to match
the current layout.

Moved -> config/quality/:
  quality-baseline.json, complexity-baseline.json, duplication-baseline.json,
  file-size-baseline.json, test-discovery-baseline.json,
  dependency-allowlist.json, .license-allowlist.json
  (generated quality-metrics.json now written here too; still gitignored)

Moved -> docs/ops/:
  DOCUMENTATION_AUDIT_REPORT.md (+ meta.json entry + fabricated-docs skip)

Path updates: check-{complexity,duplication,file-size,test-discovery,deps,
licenses,dead-code,cognitive-complexity,type-coverage}.mjs, check-quality-
ratchet.mjs, collect-metrics.mjs, check-tracked-artifacts.mjs (+ its test and
check-deps test). Also gitignore /logs/ (was untracked-not-ignored).

Tracked root files: 56 -> 48. Tool configs left in root on purpose: most are
auto-discovered there, and the tsconfig variants have location-relative
files:[] arrays that would need 46 path rewrites for a 2-file gain.
#3900)

The wiki has no native generator and drifts each release — it lacked SUPPLY_CHAIN
plus 24 other docs pages, and the cover counts went stale (212+/14/37 vs 226/15/87).

Adds:
  - scripts/docs/sync-wiki.mjs — adds docs/ pages missing from the wiki (curated;
    internal reports/plans/index excluded) and syncs the four Home.md cover counts.
    Matches the hand-curated, non-deterministic wiki page names by a normalized fuzzy
    key and writes the EXISTING name, so it never creates duplicate pages. Overwriting
    existing-page content is opt-in (--update-existing) and intentionally OFF by
    default: several docs sources still carry stale counts (e.g. ARCHITECTURE.md says
    "177 providers / 37 MCP tools" while the wiki cover is 226/87), so a blind overwrite
    would REGRESS the wiki. Full parity is gated on regenerating those sources — see
    docs/ops/DOCUMENTATION_AUDIT_REPORT.md.
  - .github/workflows/wiki-sync.yml — runs the sync on every push to main that touches
    docs/ (or a count source) + workflow_dispatch, pushing via GITHUB_TOKEN.
  - tests/unit/sync-wiki.test.ts — pure-function coverage (8 tests).

The first run already pushed the 25 missing pages to the wiki.
Integrated into release/v3.8.26
Integrated into release/v3.8.26
Integrated into release/v3.8.26
…3883)

Integrated into release/v3.8.26 (scoped to the ESM-only loader fix)
…ocs build passes

docs/ops/DOCUMENTATION_AUDIT_REPORT.md (added in #3804) was the only file
under docs/ops/ without a `title:` frontmatter block. Fumadocs scans docs/**
into the `docs` collection and fails the production build with
"Invalid input: expected string, received undefined" (title) — the same MDX
frontmatter class of break as the v3.8.25 SUPPLY_CHAIN.md incident (#3864).
Fast Quality Gates does not run `npm run build`, so it stayed green on the
release branch and would only explode at release->main sync. Added the
frontmatter matching the sibling docs/ops/*.md convention; full build now
passes (Next.js compiled 549/549 pages).
…ols / 15 strategies / 42 locales) (#3904)

Several docs bodies carried stale counts from the v3.8.0–v3.8.2 era while the code
moved on. Brought them to the canonical values verified against source:
  - providers 177/160+/223 → 226  (docs/reference/PROVIDER_REFERENCE.md "Total providers")
  - MCP tools  37/42/43    → 87    (open-sse/mcp-server TOTAL_MCP_TOOL_COUNT)
  - routing strategies  14 → 15    (routingStrategies.ts ROUTING_STRATEGY_VALUES)
  - i18n locales     40/40+ → 42   (config/i18n.json)
  - MCP scopes   ~13/13 → 30

Files: ARCHITECTURE, CODEBASE_DOCUMENTATION, REPOSITORY_MAP, QUALITY_GATES,
ACP, AGENT-SKILLS, AGENTBRIDGE, PROVIDERS-GUIDE, SETUP_GUIDE, MCP-SERVER (headline),
OMNIROUTE_VS_ALTERNATIVES, README, RELEASE_CHECKLIST.

Executors (60), OAuth providers (16), A2A skills (6) and cloud agents (3) were already
correct (check-docs-counts-sync --strict still passes). Left untouched on purpose: the
point-in-time reports (DOCUMENTATION_AUDIT_REPORT, E2E shakedown) and the MCP tool
inventory diagram (mcp-tools-43.svg) — diagram regeneration is a separate task.

This unblocks full GitHub-wiki content parity: the wiki was synced from these corrected
sources via scripts/docs/sync-wiki.mjs --update-existing.
…inned proxy is unreachable (#3906)

Integrated into release/v3.8.26
…efault keepAlive (#3907)

Integrated into release/v3.8.26 (zai validator; global keepAlive change reverted on review)
…ilure on push) (#3892)

Integrated into release/v3.8.26
…3 follow-up) (#3899)

Integrated into release/v3.8.26
…ls (#3909)

* docs(mcp): correct the MCP tool-inventory diagram source + text to 87 tools

The mcp-tools diagram source was frozen at v3.8.8 (43 tools = 30 core + 3 memory +
4 skills + 6 notion) — missing the agent-skills, gamification, plugins and obsidian
modules, and Core had grown 30 → 33. Corrected to the real breakdown verified against
open-sse/mcp-server (TOTAL_MCP_TOOL_COUNT):

  33 core + 3 memory + 4 skills + 3 agent-skills + 8 gamification + 8 plugins
  + 6 notion + 22 obsidian = 87

- renamed mcp-tools-43.{mmd,svg} → mcp-tools-87.{mmd,svg}
- rewrote the .mmd source with the 8 real categories
- fixed MCP-SERVER.md: source-of-truth line, image alt, and the inventory caption
- fixed docs/diagrams/README.md index entry

check:doc-links PASS (links resolve).

⚠️ The committed mcp-tools-87.svg is the OLD render (still draws 43 tools): the SVG
must be regenerated with `npm run docs:render-diagrams` in an environment with a
working headless Chromium. It could NOT be rendered in this sandbox — Chromium is
missing system libraries (libnss3 / libatk / libcups / libxcb, no apt access). The
.mmd source and all surrounding text are correct, so a single render call finalizes
the image.

* docs(mcp): render mcp-tools-87.svg (87-tool inventory diagram)
…#3804)

Integrated into release/v3.8.26 — reconciled: kept #3900's superset wiki-sync, dropped the superseded sync-wiki-home; counts taken from the newer canonical release docs; net-new value = vale/markdownlint docs-lint infra + 7 new docs (Notion/Obsidian/Plugin-Marketplace/Cost-Tracking/Free-Provider-Rankings/Feature-Flags/Egress-Policy) + check-docs-counts-sync guard.
… source revert (#3933)

PR #3907 lowered the test assertions for fetchKeepAliveTimeoutMs from 4000 to
1000 expecting DEFAULT_FETCH_KEEPALIVE_TIMEOUT_MS to drop to 1000, but the source
change was reverted on review (kept at 4000, with keepAliveMaxTimeout pinning
instead). The test was left asserting 1000, turning the unit suite red
release-wide. Align the assertions back to the shipped source value (4000).
diegosouzapw and others added 12 commits June 15, 2026 20:39
…(Hard Rule #19) (#3939)

Multiple sessions/agents share the main checkout, so a git checkout/branch switch
there silently discards another session's uncommitted work. Document the worktree-
isolation workflow (ask the operator for the base branch first, cut a dedicated
worktree+branch off it, tear down only your own) as a new 'Worktree isolation'
subsection under Git Workflow, and codify it as Hard Rule #19.
Integrated into release/v3.8.26 — mid-stream failure persistence (follow-up to #3879). Validated locally: typecheck:core clean, 75/75 stream/usage tests, eslint 0 errors, file-size + any-budget OK.
…TP 400 (#3938)

Integrated into release/v3.8.26 — Perplexity-web schema v2.18 payload fix for HTTP 400. Validated: 24/24 perplexity tests, typecheck:core clean, file-size rebaselined (perplexity-web.ts 868->939, justified).
Integrated into release/v3.8.26 — keep pendingById in sync with the queue detail (Object.assign in place). Validated alongside #3937: typecheck:core clean, 42/42 request-logger + lifecycle tests, eslint 0 errors, file-size OK.
…lerts to blocking (#3945)

FIX 1 — security scanner install (gitleaks/osv/actionlint/zizmor):
the step ran under bash -e and aborted before the $GITHUB_PATH export when
'go install ...gitleaks/v8@latest' failed/produced a non-working binary, so no
scanner landed on PATH and every check self-skipped. Rewritten to set +e,
install from official release downloads, ALWAYS export $HOME/.local/bin, and
print diagnostics. Validated only on the next CI run (binaries install in CI).

FIX 2 — size-limit bundleSize: add @size-limit/file devDependency (the correct
preset for the plain FILE-size .size-limit.json) + allowlist entry. check:bundle-size
now measures the 4 bin entries via the preset (bundleSize=5601) instead of erroring
on the missing preset / falling back to fs.statSync.

FIX 3 — codeqlAlerts promoted to BLOCKING: check-codeql-ratchet.mjs now reads
metrics.codeqlAlerts.value, exits 1 ONLY on a real regression (measured > baseline),
and exits 0 (graceful skip) on any measurement failure (gh absent / no auth /
no repo / API error) so missing infra never blocks. Baseline seeded codeqlAlerts=0
(repo has 0 open alerts). Blocking step wired in the quality-gate job with
security-events:read; the duplicate advisory step removed from quality-extended.
New TDD: evaluateCodeqlRatchet (5 cases).
…visory baselines (#3947)

Three CI security gates in the quality-extended job never produced a value;
diagnose + fix each, then freeze the real measured numbers as advisory ratchet
baselines (dedicatedGate => SKIP in the blocking quality-gate ratchet).

FIX 1 — .zizmor.yml: migrate the config from the pre-1.0 'ignores: []' schema to
the 'rules: {}' schema. zizmor 1.25.2 rejected the old field ('unknown field
`ignores`, expected `rules`') and performed NO audit. Now check:workflows emits
zizmorFindings=195.

FIX 2 — scripts/check/check-secrets.mjs: the gate ran 'gitleaks detect --no-git
--source .', which walks the WHOLE tree including a real node_modules/ (90k+ files
under npm ci) and times out (ETIMEDOUT) — gitleaks has no traversal-exclude flag
(.gitleaks.toml paths filter findings AFTER reading). Scope the scan to the source
dirs (src/open-sse/bin/electron/scripts), one 'gitleaks dir <dir>' invocation each
('gitleaks dir' takes a single path; multiple args fall back to scanning the CWD).
Also fix .gitleaks.toml: it lacked [extend].useDefault=true, so the custom config
REPLACED the default ruleset with zero rules and detected nothing — the gate always
reported 0 regardless of real secrets. Now: ~10s (was 120s timeout), secretFindings=3
(generic-api-key false positives in beta-header strings / column names).

FIX 3 — .github/workflows/ci.yml: the scanner install resolved release URLs via
unauthenticated api.github.com (60 req/hr/IP; returns empty when throttled -> silent
no-op install -> every gate self-skips). Switch gitleaks + osv-scanner to 'gh release
download' (preinstalled + GITHUB_TOKEN-authed, 5000 req/hr); add GH_TOKEN to the step
env. actionlint/zizmor install paths unchanged.

MEASURE + FREEZE (advisory, dedicatedGate:true, direction down) in
config/quality/quality-baseline.json: secretFindings=3, zizmorFindings=195,
vulnCount=13 (LOW=4/MOD=7/HIGH=2), bundleSize=5601. Seeded from a local run with the
real binaries on PATH (2026-06-15). They stay advisory (SKIP in the blocking ratchet;
quality-extended is continue-on-error) until a green CI run confirms the fixed tooling
produces values; the flip to blocking is a follow-up PR. continue-on-error untouched.

Validated locally: zizmor --config parses; check:secrets <60s + real count;
check:workflows/check:vuln-ratchet emit real numbers; ci.yml actionlint-clean; baseline
JSON valid; 103 build-scanner unit tests + 19 check-secrets + 18 quality-ratchet pass;
the 4 keys SKIP in the ratchet. FIX 3 logic is sound but CI-only (cannot run gh release
download against the runner locally).
…plate-injection + allowlist guarded workflow_run (#3949)

Remediate the real findings the now-functional osv-scanner and zizmor gates
surfaced on release/v3.8.26.

Deps (osv-scanner, 2 HIGH -> 0):
- form-data 4.0.5 -> ^4.0.6 (GHSA-hmw2-7cc7-3qxx, transitive via axios)
- vite 8.0.5 -> ^8.0.16 (GHSA-fx2h-pf6j-xcff HIGH + GHSA-v6wh-96g9-6wx3
  MODERATE; dev-only via vitest/@vitejs/plugin-react/fumadocs-mdx)
Applied via package.json overrides of existing deps (no new allowlist entry
needed). vulnCount 13 -> 10; build:cli + vitest MCP suite (16 files/187 tests)
green post-bump.

Workflows (zizmor, 195 -> 187):
- env-harden 7 template-injection findings by moving each ${{ ... }} into env:
  and referencing "$VAR" in the script (GitHub-documented mitigation):
  ci.yml i18n; electron-release.yml validate/build/release steps.
- allowlist 1 dangerous-triggers FP: deploy-vps.yml on:workflow_run is guarded
  on conclusion=='success' and deploys via SSH without checking out untrusted
  code. Added .zizmor.yml rules.dangerous-triggers.ignore with justification.

Tighten baselines to the improved state (direction: down): vulnCount 13 -> 10,
zizmorFindings 195 -> 187. secretFindings (3) and bundleSize (5601) unchanged.
)

New advisory gate (Fase 8 B.4) that diffs the public API contract
docs/reference/openapi.yaml against the base branch via oasdiff, surfacing
removed endpoints, newly-required params, removed response fields, etc.

- scripts/check/check-openapi-breaking.mjs: resolves base spec via
  git show <BASE_REF>:docs/reference/openapi.yaml to a temp file, runs
  oasdiff breaking --format json, parses+counts breaking changes, emits
  openapiBreaking=N (KEY=VALUE for collect-metrics). ADVISORY: exit 0 always;
  graceful SKIP when oasdiff is absent or the base spec can't be resolved.
- package.json: check:openapi-breaking script.
- .github/workflows/ci.yml (quality-extended, advisory): install oasdiff via
  gh release download, add the breaking-change step (BASE_REF via env, never
  shell-interpolated), fetch-depth: 0 so git show can read the base spec.
- tests/unit/build/check-openapi-breaking.test.ts: parser counting/grouping +
  binary-absent SKIP integration.
- docs/architecture/QUALITY_GATES.md: document the quality-extended job table.
- docs/reference/openapi.yaml: define the BadRequest/NotFound/InternalError
  response components that were referenced (14 call sites) but never defined —
  a pre-existing dangling-$ref defect that blocked oasdiff from loading the spec.
  No path behavior changes; purely additive to components.responses.
…alog regression, sync i18n

- Reconcile the [3.8.26] CHANGELOG to cover all 43 commits since v3.8.25; move 3
  bullets (#3877/#3881/#3890) that were misfiled under [3.8.25] after the tag back
  into [3.8.26], restoring [3.8.25] to its published/tagged state.
- fix(providers): keep the /v1/models catalog alias-only. #3870 made generateModels()
  mirror models under each raw provider id, surfacing phantom opencode/* entries that
  collide with the opencode/ -> opencode-zen route (regression vs v3.8.25, caught by
  the #2798 catalog regression test). getProviderModels() now resolves raw id -> alias
  at lookup time instead, preserving #3870's intent (getProviderModels("github") ==
  the "gh" alias) without polluting the public model namespace.
- Inject the full EN [3.8.26] section into the 41 i18n CHANGELOG mirrors (docs-sync body-size).
- Allowlist BASE_REF in check-env-doc-sync (CI-only var for the OpenAPI breaking-change gate).
# Conflicts:
#	electron/package-lock.json
@diegosouzapw
diegosouzapw merged commit 81a37b6 into main Jun 16, 2026
7 checks passed
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot
0.0% Coverage on New Code (required ≥ 80%)
D Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
OmniRoute v3.8.26 — see CHANGELOG.md [3.8.26] for the full notes.

Highlights: Vertex AI media generation (cheaper-inference#3929), GLM-5.2 effort-tier routing (cheaper-inference#3885),
sticky round-robin combos (cheaper-inference#3846), OpenRouter connection presets (cheaper-inference#3878), compression
prompt-cache fix (cheaper-inference#3936/cheaper-inference#3890), and a security pass (form-data/vite + workflow hardening, cheaper-inference#3949).

Co-authored-by: artickc <artickc@users.noreply.github.com>
Co-authored-by: rdself <rdself@users.noreply.github.com>
Co-authored-by: herjarsa <herjarsa@users.noreply.github.com>
Co-authored-by: Jack Smith <16862258+YunyunZhai@users.noreply.github.com>
Co-authored-by: dhaern <dhaern@users.noreply.github.com>
Co-authored-by: adivekar-utexas <adivekar-utexas@users.noreply.github.com>
Co-authored-by: megamen32 <megamen32@users.noreply.github.com>
Co-authored-by: zhiru <zhiru@users.noreply.github.com>
Co-authored-by: insoln <insoln@users.noreply.github.com>
Co-authored-by: diego-anselmo <diego-anselmo@users.noreply.github.com>
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
OmniRoute v3.8.26 — see CHANGELOG.md [3.8.26] for the full notes.

Highlights: Vertex AI media generation (cheaper-inference#3929), GLM-5.2 effort-tier routing (cheaper-inference#3885),
sticky round-robin combos (cheaper-inference#3846), OpenRouter connection presets (cheaper-inference#3878), compression
prompt-cache fix (cheaper-inference#3936/cheaper-inference#3890), and a security pass (form-data/vite + workflow hardening, cheaper-inference#3949).

Co-authored-by: artickc <artickc@users.noreply.github.com>
Co-authored-by: rdself <rdself@users.noreply.github.com>
Co-authored-by: herjarsa <herjarsa@users.noreply.github.com>
Co-authored-by: Jack Smith <16862258+YunyunZhai@users.noreply.github.com>
Co-authored-by: dhaern <dhaern@users.noreply.github.com>
Co-authored-by: adivekar-utexas <adivekar-utexas@users.noreply.github.com>
Co-authored-by: megamen32 <megamen32@users.noreply.github.com>
Co-authored-by: zhiru <zhiru@users.noreply.github.com>
Co-authored-by: insoln <insoln@users.noreply.github.com>
Co-authored-by: diego-anselmo <diego-anselmo@users.noreply.github.com>
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
OmniRoute v3.8.26 — see CHANGELOG.md [3.8.26] for the full notes.

Highlights: Vertex AI media generation (cheaper-inference#3929), GLM-5.2 effort-tier routing (cheaper-inference#3885),
sticky round-robin combos (cheaper-inference#3846), OpenRouter connection presets (cheaper-inference#3878), compression
prompt-cache fix (cheaper-inference#3936/cheaper-inference#3890), and a security pass (form-data/vite + workflow hardening, cheaper-inference#3949).

Co-authored-by: artickc <artickc@users.noreply.github.com>
Co-authored-by: rdself <rdself@users.noreply.github.com>
Co-authored-by: herjarsa <herjarsa@users.noreply.github.com>
Co-authored-by: Jack Smith <16862258+YunyunZhai@users.noreply.github.com>
Co-authored-by: dhaern <dhaern@users.noreply.github.com>
Co-authored-by: adivekar-utexas <adivekar-utexas@users.noreply.github.com>
Co-authored-by: megamen32 <megamen32@users.noreply.github.com>
Co-authored-by: zhiru <zhiru@users.noreply.github.com>
Co-authored-by: insoln <insoln@users.noreply.github.com>
Co-authored-by: diego-anselmo <diego-anselmo@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] When Compression is enabled, providers cache miss [Feature] Nous research api key invalid but works in curl [BUG] BytePlus API Key Invalid