Skip to content

v3.8.42

Latest

Choose a tag to compare

@diegosouzapw diegosouzapw released this 30 Jun 09:55
0adae00

✨ New Features

  • compression (pipeline): add an honest default-on inflation guard to the stacked compression pipeline (T02 / Headroom H1). If the fully-stacked engines produce a body that did not actually shrink — its token count is >= the original — the compressed body is discarded and the verbatim original request is sent upstream instead, with a pipeline-inflation-guard warning recorded in the compression stats. This is safe by construction (the only fallback is the unmodified original, always a valid payload) and complements the existing opt-in per-step TV1 bail-out, which governs step-to-step advancement rather than the final output. New open-sse/services/compression/pipelineGuards.ts; wired at the single finalizeStackedResult choke point shared by the sync and async stacked paths. Regression guards (incl. an inflating-engine integration test) in tests/unit/compression-pipeline-inflation-guard.test.ts.

  • compression (caveman): complete the German, French, and Japanese rule packs with the dedup (repeated-context collapsing) and ultra (abbreviation / terse) categories they were missing — these three languages previously shipped only context/filler/structural, while en/es/id/pt-BR had all five. So a de/fr/ja conversation compressed at higher intensities now collapses repeated boilerplate ("wie bereits besprochen" → "Siehe oben.", "comme mentionné précédemment" → "Voir ci-dessus.", "前述のとおり" → "(上記参照)") and abbreviates dense technical vocabulary (DatenbankDB, AuthentifizierungAuth; base de donnéesBD, authentificationauth; データベースDB, アプリケーションapp). Patterns mirror the existing es pack and stay ReDoS-safe (bounded literal alternations; the CJK pack uses no \b since Japanese has no word boundaries). Regression guard: tests/unit/caveman-packs-de-fr-ja.test.ts (packs load + validate + shrink a representative sample). gaps v3.8.42 — T05/C2.

  • compression (caveman): add a Chinese (zh / wenyan 文言) input-side rule pack — the counterpart of the existing output-side terse-cjk style. New rules/zh/{dedup,filler,ultra}.json collapse repeated context ("如前所述" → "见上。"), drop pleasantries/hedging ("请帮我…/谢谢/我觉得"), strip sentence-final modal particles ("吗/呢/吧"), and abbreviate dense technical terms ("数据库"→"DB", "应用程序"→"app"). Chinese is now auto-detected: detectCompressionLanguage distinguishes zh from ja by Han-without-kana (kana is Japanese-exclusive, so a Han-heavy Japanese sentence still resolves to ja), and zh is listed in listSupportedCompressionLanguages. Patterns are ReDoS-safe (bounded literal alternations, no \b since CJK has no word boundaries). Regression guard: tests/unit/caveman-packs-zh-wenyan.test.ts (packs load + validate + shrink; zh/ja/non-CJK detection). gaps v3.8.42 — T05/C6.

  • compression (RTK): add Gradle and .NET CLI (dotnet) to the RTK tool-output filter catalog. Tool output for gradle/gradlew and dotnet build|test|restore|publish is now recognized (both by command and by output content) and compressed: Gradle daemon/welcome banners and no-op > Task … UP-TO-DATE/SKIPPED/FROM-CACHE lines are dropped while BUILD SUCCESSFUL/FAILED, "What went wrong", and stack traces are preserved; the .NET build banner, copyright, and Determining projects to restore/Restored … chatter are dropped while Build succeeded/FAILED, error CS####/warning CS####, and test summaries are preserved. New builtin filters engines/rtk/filters/{gradle,dotnet}.json (with inline tests run by the catalog gate) plus gradle/dotnet entries in the command detector. Regression guard: tests/unit/rtk-gradle-dotnet-filters.test.ts. gaps v3.8.42 — T07/R9.

🔧 Bug Fixes

  • providers (chatgpt-web): fix 502 ChatGPT sentinel failed: Digest method not supported on the Electron desktop app, which made every chatgpt-web/* request fail. The sentinel proof-of-work hashed with native createHash("sha3-512"), but Electron's Node is built against BoringSSL, which does not implement the SHA-3 family (electron/electron#30530), so the digest threw at construction — the provider was unusable on the desktop build (works under plain Node/OpenSSL). The PoW now hashes through a new runtime-portable helper (open-sse/utils/sha3-512.ts) that prefers the native digest and transparently falls back to a dependency-free pure-JS Keccak-f[1600] when native SHA-3 is absent. The fallback is validated bit-for-bit against native createHash("sha3-512") (300 random inputs) and the published FIPS-202 known-answer vectors. Regression guards in tests/unit/chatgpt-web-sha3-boringssl-5531.test.ts. (#5531)

  • providers (bytez): fix Bytez key validation ("Provider validation endpoint not supported") and the chat base URL, verified live with a real key. Bytez is OpenAI-compatible at …/models/v2/openai/v1, but the registry stored the bare …/models/v2 base, so the validation chat-probe hit …/models/v2/chat/completions404 → the misleading "endpoint not supported". Two parts: (1) the registry baseUrl now carries the full OpenAI-compat chat path (…/models/v2/openai/v1/chat/completions); (2) key validation no longer uses a chat probe — a Bytez account only serves models explicitly added to its catalog, so even valid keys 404 on any model id. A dedicated validateBytezProvider instead probes the auth-only GET …/models/v2/list/tasks endpoint (200 ⇒ valid, 401/403 ⇒ invalid), which is independent of catalog provisioning. Regression guard: tests/unit/bytez-validation-5422.test.ts. (#5422)

  • dashboard (provider add): two provider-add UX fixes. (1) #5420 — the "Import Models" button now stays hidden for tool-only providers (web search / web fetch), not just *-search ids: firecrawl and jina-reader (declared serviceKinds: ["webFetch"]) previously showed an Import button that hit the 400 "does not support models listing" route. A new capability check (providerLacksModelListing over the resolved serviceKinds) gates the section without ever hiding an LLM/media provider. (2) #5426 — Coze key validation no longer leaks the raw upstream envelope ({code,msg,logId,from}) into the UI; the Coze-shaped error becomes a friendly Coze rejected the key: <msg> (code <n>) message (scoped to provider === "coze" so no other provider is affected). Regression guards: tests/unit/model-listing-capability-5420.test.ts, tests/unit/coze-validation-error-5426.test.ts. (#5420, #5426)

  • providers (friendliai, novita): fix two provider registry endpoints that rejected valid keys (verified live with real keys). FriendliAI pointed at …/dedicated/v1/chat/completions, which 403 Forbiddens a serverless flp_* token — switched to …/serverless/v1/chat/completions (+ a serverless modelsUrl). Novita pointed at the legacy …/v3/… base with a typo'd model id ai-ai/llama-3.1-8b-instruct (both 404) — switched to the OpenAI-compatible …/openai/v1/… base + the valid meta-llama/llama-3.1-8b-instruct id. Regression guard: tests/unit/provider-endpoints-friendliai-novita.test.ts. (#5430, #5455)

  • providers (muse-spark): align the Muse Spark Web (Meta AI) cookie copy with the live cookie name. The default session cookie migrated from the retired abra_sess to ecto_1_sess (META_AI_DEFAULT_COOKIE), but the provider form hint and one 401 auth-failure message still told users to paste abra_sess — a cookie that no longer exists. Both strings now name ecto_1_sess. Regression guard: tests/unit/muse-spark-cookie-copy-5449.test.ts. (#5449)

  • dashboard (provider add): fix three rough edges in the Add-API-Key / model-import flow reported across the provider-catalog audit. (1) The Validation Model and Account ID form fields shipped untranslated i18n stub copy ("Validation Model Id Label", "Account Id Placeholder", …) that surfaced verbatim in the modal — replaced with real labels/placeholders/hints in en.json. (2) Model import silently fell back to the cached/local catalog: the route already returned a warning ("API unavailable — using local catalog"), but useModelImportHandlers only read models/error and dropped it, so the user got local models with no indication — the warning is now surfaced as an import log line (new pure helper extractImportWarning). (3) The required connection-name field defaulted to "", which let browser autofill inject garbage (e.g. wiw) — it now defaults to "main". Regression guard: tests/unit/provider-add-ux-i18n-import-warning.test.ts. (#5421, #5428, #5429, #5431, #5435)

  • services (installer): fix spawn EINVAL when installing an embedded service (9Router / CLIProxy) on Windows + Node.js 24+. Node 24 stopped letting child_process.execFile() run .cmd batch files without a shell (nodejs/node#52554), and npm on Windows is npm.cmd, so runNpm() threw EINVAL the moment a user clicked Install. runNpm now enables shell on win32 only. To keep Hard Rule #13 intact under a shell — where the shell, not execFile, parses argv — the install --prefix (a DATA_DIR path that can legitimately contain spaces, e.g. C:\Users\John Doe\.omniroute\…) is now passed via the npm_config_prefix environment variable instead of an argv path, and the user-supplied install version is constrained to a dist-tag/semver shape (SERVICE_VERSION_PATTERN) at the route boundary so it can never carry shell metacharacters. With the prefix in the environment and the version validated, every remaining argv entry is a static flag. Regression guards: tests/unit/services/installers/runNpm-shell-5379.test.ts (+ existing ninerouter.test.ts aligned to npm's npm_config_prefix env). (#5379)

  • cli (serve): restore dist/tls-options.mjs to the npm tarball — the opt-in native HTTPS/TLS sidecar (#5361) was copied into the staged dist/ by the build but then pruned by the prepublish allowlist step, so omniroute serve crashed on the published 3.8.41 with ERR_MODULE_NOT_FOUND (dist/server-ws.mjs imports ./tls-options.mjs). Added tls-options.mjs to APP_STAGING_ALLOWED_EXACT_PATHS (survives the prune) and dist/tls-options.mjs to PACK_ARTIFACT_REQUIRED_PATHS (the check:pack-artifact gate now fails loudly if it ever vanishes again — same guard pattern as webdav-handler.mjs). Regression guards in tests/unit/pack-artifact-policy.test.ts. (#5452 — thanks @KooshaPari for the parallel fix #5494)

  • dashboard: fix the Add Provider / onboarding wizard button silently doing nothing. The /dashboard/providers/new route was a redirect stub (it bounced straight back to /dashboard/providers), so every "Add Provider" button and dashboard widget link opened nothing, and the fully-built ProviderOnboardingWizard component stayed orphaned (never rendered by any route). The route now renders the wizard directly; auth is enforced centrally by the (dashboard) layout, same as the sibling provider routes. Regression guard in tests/unit/onboarding-wizard-route-5427.test.ts. (#5427)

  • db (import): fix EBUSY: resource busy or locked when importing a database on Windows. The import route deleted the live storage.sqlite + WAL/-shm/-journal sidecars with a plain fs.unlinkSync immediately after resetDbInstance(), but Windows releases the SQLite file handle asynchronously after close() (mmap / antivirus), so the unlink raced and threw EBUSY. The route now deletes via unlinkFileWithRetry (EBUSY/EPERM backoff) — the same helper the restore path already uses. Regression guard in tests/unit/db-import-ebusy-5406.test.ts. (#5406, consolidated under #5161)

  • build: keep ioredis out of the client/CLI bundle — a dast-smoke regression revealed the module was being pulled into browser/Electron client-side chunks; adding it to the SPAWN_CAPABLE_PREFIXES leaf excludes it from client bundles while keeping it available on the server path. (#5546)

  • providers (mimocode): route per-account traffic through SOCKS5 proxy dispatchers — each mimocode account's requests are now dispatched via its configured SOCKS5 proxy rather than the default direct connection. (#5521 — thanks @pizzav-xyz)

  • providers: persist the Configured provider filter selection across page reloads — the filter was resetting to "All" on every navigation. (#5510 — thanks @KooshaPari)

  • providers (chatgpt-web): support GPT-5.5 Pro model handoff — adds the model mapping and handoff routing needed for the GPT-5.5 Pro tier. (#5536 — thanks @Thinkscape)

  • dashboard: keep onboarding schemas browser-safe — the schema module imported a server-side db reference that crashed the browser bundle; it is now imported only on the server path. (#5525 — thanks @KooshaPari)

  • routing (bifrost): add auto-fallback cooldown for bifrost targets — prevents rapid re-selection of a failing bifrost backend within the cooldown window, complementing the existing circuit-breaker mechanism. (#5519 — thanks @KooshaPari)

  • providers (opencode-plugin): bump the opencode plugin to v0.2.0 and wire auto-publish on release so the plugin package tracks OmniRoute releases automatically. (#5363 — thanks @herjarsa)

  • rate-limit: normalize queue refresh settings — aligns the queue-refresh interval configuration across rate-limit strategies so stale queues are released on a consistent schedule. (#5499 — thanks @KooshaPari)

  • fallback: normalize provider error-rule header extraction — ensures fallback retry decisions correctly read all response headers regardless of casing, fixing cases where a provider's Retry-After or custom error header was silently dropped. (#5473 — thanks @KooshaPari)

  • routing: gate Claude adaptive-thinking defaults behind the feature flag — prevents the thinking budget from being injected into requests for models that do not support the extended-thinking parameter, avoiding upstream 400 errors on non-thinking Claude variants. (#5480 — thanks @KooshaPari)

  • ci: fix post-merge CI regressions introduced by the dead-code sweep — restores test imports and type references broken when the ratchet landed before downstream consumers were updated. (#5467 — thanks @KooshaPari)

  • sse: treat terminal stream cancels as complete — an aborted SSE stream was being left in a partial state, causing downstream consumers to wait indefinitely for a final event that would never arrive. (#5491 — thanks @JxnLexn)

  • api: fix framing of non-streaming JSON responses — stream: false chat-completions responses were returned without correct content-length framing, causing some clients to misparse the response body. (#5416 — thanks @rdself)

  • dashboard (tests): protect dynamic dashboard endpoint tests with CSRF validation — the test suite was exercising dashboard API routes without CSRF tokens, masking a coverage gap for those endpoints. (#5405 — thanks @rdself)

  • providers: remove the dead Phind provider (service shut down) and deduplicate the HuggingChat catalog listing that had accumulated a stale duplicate entry. (#5530 — thanks @backryun)

  • providers (longcat): correct the LongCat free tier — LongCat-2.0 is now GA; the one-time 10M-token promo (KYC required) is correctly reflected in the catalog, replacing the stale legacy beta entry. (#5508 — thanks @backryun)

📝 Maintenance

  • dashboard (refactor): consolidate the duplicate caveman on/off toggle from the compression settings tab onto the single-source panel (T11), eliminating the stale off-sync copy. (#5524)

  • tests: add quota guard for Claude-Code identity version lockstep (Phase 2) — asserts that the Claude-Code version reported in quota accounting stays in sync with the deployed version, preventing silent drift. (#5514)

  • docs: add relay backend strategy guide documenting supported relay backend types, selection criteria, and configuration patterns. (#5547)

  • docs: clarify bifrost relay backend environment variables — documents which env vars control bifrost's relay backend selection and failover behavior. (#5520 — thanks @KooshaPari)

  • tests: add relay routing fallback header behavior tests — regression guard asserting that fallback-triggered relay requests carry the correct forwarded headers through the routing layer. (#5526 — thanks @KooshaPari)

  • ci: add npm fetch-retry configuration and codify the release-freeze protocol (Hard Rule #21) — reduces transient npm registry fetch failures in CI and establishes the documented procedure for freezing releases. (#5506)

  • deps: bump 11 production dependencies to their latest compatible versions. (#5414)

  • deps: bump Electron from 42.4.1 to 42.5.1 in /electron. (#5413)

  • deps: bump the development dependency group with 9 updates. (#5415)

  • maintenance (dead-code): repo-wide sweep of unused exported symbols, types, and schemas — removes 35 no-longer-referenced exports across cloud-agent, a2a, SSE, memory, quota, skills, gamification, codex, qdrant, playground, provider catalog, and combo modules, reducing the exported API surface and eliminating stale misleading types. (#5372, #5373, #5374, #5375, #5376, #5377, #5378, #5380, #5381, #5382, #5383, #5384, #5385, #5386, #5387, #5388, #5389, #5390, #5391, #5392, #5393, #5395, #5396, #5397, #5398, #5399, #5400, #5401, #5402, #5403, #5404, #5463, #5464, #5466, #5468 — thanks @JxnLexn)

  • maintenance (DRY): DRY consolidation of shared helpers — extracts 17 duplicated utilities into single shared modules: vscode metadata helpers, proxy route handlers, auth zip extractors, combo-builder model options, vscode tokenized-request helpers, quota strategy ranking helpers, recharts donut card, provider-specific validation, batch response formatter, Redis runtime helpers, version-manager request parsing, media-generation route helpers, service install helpers, settings transform schemas, relay stream finalizer, machine-id fallback, and node SQLite adapter. (#5471, #5472, #5475, #5477, #5479, #5482, #5484, #5485, #5488, #5490, #5492, #5493, #5495, #5496, #5497, #5498, #5500 — thanks @JxnLexn)


What's Changed

Full Changelog: v3.8.41...v3.8.42