Release v3.8.0 - #2111
Release v3.8.0#2111
Conversation
Integrated into release/v3.8.0
Integrated into release/v3.8.0
Integrated into release/v3.8.0
….user_id (#2053) Integrated into release/v3.8.0
# Conflicts: # open-sse/handlers/chatCore.ts # open-sse/services/comboConfig.ts # open-sse/services/usage.ts # src/app/(dashboard)/dashboard/providers/[id]/page.tsx # src/app/(dashboard)/dashboard/usage/components/ProviderLimits/index.tsx # src/app/(dashboard)/dashboard/usage/components/ProviderLimits/utils.tsx # src/app/api/usage/analytics/route.ts # src/lib/db/migrationRunner.ts # src/lib/usage/providerLimits.ts # src/shared/constants/providers.ts # src/sse/handlers/chat.ts # tests/unit/provider-limits-ui.test.ts # tests/unit/usage-analytics.test.ts # tests/unit/usage-service-hardening.test.ts
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive CLI integration suite for OmniRoute, including commands for guided setup, system diagnostics, and provider management. It also integrates Redis for rate limiting in Docker environments and significantly expands documentation and internationalization. Technical feedback highlights several critical issues, including a database schema mismatch in the CLI key management, unsafe SQLite backup procedures using file copying, and missing dependencies in the production Docker image for the diagnostic tools. Additionally, the review flags a security vulnerability regarding plaintext password entry during setup and a version typo in the Redis configuration.
| ); | ||
| log(`API key for ${provider} updated`, "green"); | ||
| } else { | ||
| db.prepare( |
There was a problem hiding this comment.
| for (const file of filesToBackup) { | ||
| const sourcePath = join(dataDir, file.name); | ||
| if (existsSync(sourcePath)) { | ||
| const destPath = join(backupPath, file.dest); |
| } | ||
|
|
||
| async function checkNodeRuntime(rootDir) { | ||
| const { getNodeRuntimeSupport } = await import( |
| return warn("Native binary", "better-sqlite3 native binary was not found", { candidates }); | ||
| } | ||
|
|
||
| const { isNativeBinaryCompatible } = await import( |
| services: | ||
| # ── Redis (Rate Limiter Backend) ────────────────────────────────── | ||
| redis: | ||
| image: redis:8.6.2 |
There was a problem hiding this comment.
The Redis image version 8.6.2 appears to be a typo. The current stable version of Redis is 7.x, and version 8.0 is in early development. This will likely result in an 'image not found' error.
References
- Ensure all unit tests, scripts, and utilities are correctly placed and configured. Redundant or broken configurations should be avoided. (link)
|
|
||
| try { | ||
| // Try multiple methods | ||
| execCommand("lsof -ti:20128 | xargs kill -9 2>/dev/null || true", 2000); |
There was a problem hiding this comment.
| } | ||
| } | ||
|
|
||
| function checkPort(port, label) { |
| const answer = await prompt.ask("Set an admin password now? [y/N]", "N"); | ||
| if (!/^y(es)?$/i.test(answer)) return ""; | ||
|
|
||
| const password = await prompt.ask("Admin password"); |
| return initializer?.kind === ts.SyntaxKind.TrueKeyword; | ||
| } | ||
|
|
||
| function extractProviderBlocks(source, filePath) { |
There was a problem hiding this comment.
Parsing source code files using the TypeScript compiler API at runtime to extract provider definitions is fragile. If the structure of src/shared/constants/providers.ts changes slightly, the CLI logic may break. Consider exporting the provider list as a JSON file or a structured object that can be safely imported.
…essions - Fix stream readiness loop and upstream error code propagation in chatCore.ts - Resolve Headers iterator TypeScript errors - Fix type mismatches and missing props in BuilderIntelligentStep, Card, and providers page - Fix providerLimits typecasts and resolve implicit any errors - Ensure green build and strict type compliance for production
…ns (#2116) Integrated into release/v3.8.0
…ress false-positive hash warnings - Sanitize error messages in errorResponse() and cursor buildErrorResponse() to strip stack traces before sending to client (fixes js/stack-trace-exposure) - Add explicit CodeQL suppression comments for intentional SHA-256 usage in API key hashing (fast O(1) lookup, not password storage) and deterministic UUID generation (fixes js/insufficient-password-hash false positives)
…2122) Integrated into release/v3.8.0 — thank you @abhinavjnu for this contribution! 🎉
Integrated into release/v3.8.0 — thank you @clousky2020 for this contribution! 🎉
Integrated into release/v3.8.0 — thank you @rdself for this contribution! 🎉
Integrated into release/v3.8.0 — thank you @boa-z for this contribution! 🎉
Integrated into release/v3.8.0 — thank you @HoaPham98 for this contribution! 🎉
Integrated into release/v3.8.0 — thank you @backryun! 🎉
… and sync CHANGELOG i18n - Fix check-docs-sync.mjs: CHANGELOG.md i18n mirrors use translation-aware validation (version sections + size check) instead of exact byte comparison, since translated CHANGELOGs have translated section headings - Add v3.8.0 Community Contributors section with 38 external contributors credited - Sync CHANGELOG.md translations across 40 locales
Integrated into release/v3.8.0
…ad (#2218) Integrated into release/v3.8.0
The local-aliases-precedence path used `typeof aliases[parsed.model] === "string"` to guard string-only operations, but TypeScript does not narrow the variable `directTarget` from that index-expression test — the variable retained the union type ModelAliasValue (string | object), so `indexOf`/`slice` were typed as property accesses on the object branch and the strict-core typecheck failed. Refactors to capture `directTarget` first and run `typeof directTarget === "string"` on the variable, which TS does narrow. No runtime semantics change — local-aliases tests still pass.
After merging PRs #2221 (ModelSync shared loopback readiness gate + IPv4 force) and #2219 (Antigravity loadCodeAssist bootstrap + fetchAvailableModels fallback) into release/v3.8.0, two test suites needed updates to match the new routing: - tests/unit/model-sync-route.test.ts: * resetStorage() now calls __resetLoopbackReadinessForTests() so the module-level __loopbackReadyPromise cache does not leak between tests. * Every fetch mock now answers the /__readiness_probe__/ URL with 404 so the gate opens immediately (any HTTP response satisfies the probe). * Self-fetch target URL assertions updated from http://localhost/... to http://127.0.0.1:20128/... per PR #2221's IPv4-force. - tests/unit/provider-models-route.test.ts: * The Antigravity discovery-retry test now treats loadCodeAssist calls as non-fatal failures so the discovery path is still exercised. * The expected discovery URL sequence is updated to the new fetchAvailableModels-first order introduced by PR #2219.
Co-authored-by: nickwizard <nickwizard@users.noreply.github.com>
… stricter proxies (#2233) Integrated into release/v3.8.0 with idle timeout default reverted to 600s
Integrated into release/v3.8.0 as bf83aa5 (i18n keys propagated)
Integrated into release/v3.8.0 with Zod schema validation replacing JSON.parse(parsed)
Integrated into release/v3.8.0 with unit tests for Azure-AI /responses routing
- antigravity: AntigravityCredentials.projectId widened to string|null to match base ProviderCredentials shape post-#2227 squash merge. - responses-handler: heartbeat assertion updated for #2233's new openai-responses-in-progress shape (was: keepalive comment). - search-registry: expected count is now 12 (ollama-search + zai-search both landed in this release).
- Add tool-detector.ts (6 CLI tools: claude, codex, opencode, cline, kilocode, continue) - Add config-generator/ factory + 6 generators (JSON + YAML) - Add doctor/checks.ts for CLI tool health checks - Add log-streamer.ts for usage log streaming - Add @omniroute/opencode-provider npm package - Add 5 CLI commands: config, status, logs, update, provider - Add 3 API routes: config, detect, apply - Update bin/omniroute.mjs, bin/cli/index.mjs, package.json - Update docs: SETUP_GUIDE.md, CLI-TOOLS.md - All tests pass (4302/4326, 24 pre-existing failures unchanged)
…d Code API (#2243) Integrated into release/v3.8.0 — Command Code validation now sends correct external environment and stream=false.
…o arrays (#2242) Integrated into release/v3.8.0 — surgical streaming translator shim for submit_pr_review functionalChanges/findings array fields.
Integrated into release/v3.8.0 (http-proxy-middleware bumped to 4.x; engines.node updated in follow-up)
… 20.x) The root package.json was updated in 52f3285 to drop Node 20.x support (http-proxy-middleware 4.x requirement). electron/package.json had no engines field declared, leaving the desktop build implicitly permissive. Adds the same constraint (>=22.22.2 <23 || >=24.0.0 <27) to keep the electron workspace consistent with the root engine policy. Refs: #2228 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… blocks verbatim Fixes Anthropic HTTP 400 errors (~49/h on claude-opus-4-7) by preserving the latest assistant message's thinking blocks verbatim instead of rewriting them to redacted_thinking. Co-authored-by: NomenAK <anton@nomenak.dev>
…rry-pick from PR #2231) Cherry-picks non-overlapping changes from @kang-heewon's PR #2231: - isDeepSeekV4Model() check in responseSanitizer - providerRegistry V4 model entries with supportsReasoning - schemaCoercion model-param for injectEmptyReasoningContentForToolCalls - reasoningCache request-ID-based stable keys - translator reasoning-only message replay for DeepSeek - Comprehensive test coverage (81 tests across 5 providers) Co-authored-by: kang-heewon <owen@kangheewon.dev>
- chatCore.ts: pass {requestId:skillRequestId,messageIndex:0} to cacheReasoningFromAssistantMessage
- responseSanitizer.ts: widen isDeepSeekV4Model regex to match all deepseek-v4 variants
…ct signature After cherry-picking PR #2231, the function signature changed from positional (provider, model) to object ({ provider, model }). Fixes the 2 pre-existing tests that still used the old positional style.
…tation - Resolve <<<<<<< HEAD conflict in RoutingTab.tsx by keeping the HEAD version with aria-disabled and pre-computed titleText - Fix inconsistent indentation in CLI help text (providers commands and CLI Tools section)
Adds 5 new CLI management commands (config, status, logs, update, provider),
3 API endpoints (/api/cli-tools/{detect,config,apply}), config generators
for 6 tools (Claude, Cline, Codex, Continue, KiloCode, OpenCode), zero-config
auto-routing via auto/ prefix, and @omniroute/opencode-provider npm package.
Fixes: merge conflict in RoutingTab.tsx, help text indentation, README conflicts.
Closes #2016
Co-authored-by: oyi77 <paijo@users.noreply.github.com>
Deep audit of all 320 commits since v3.7.9 found: - 18 merged PRs not documented in CHANGELOG (4 features, 10 bug fixes, 1 security, 2 chores, 1 debug improvement) - 3 contributors entirely missing from credits table (@NomenAK with 12 PRs, @kang-heewon, @one-vs) - 4 existing contributors with inaccurate PR counts (@oyi77 8→12, @ddarkr 2→3, @andrewmunsell 2→3, @nickwizard 2→3) New entries added: - feat: #2135 (1proxy settings), #2227 (antigravity project ID), #2238 (Z.AI Search), #2240 (CLI Suite) - fix: #2217, #2218, #2219, #2221, #2222, #2223, #2224, #2231, #2233, #2236, #2242, #2243 - security: #2209 (stack trace exposure) - chore: #2228, #2234 Total contributors updated from 50+ to 55+.
Release v3.8.0
Release v3.8.0
[3.8.0] — 2026-05-06
✨ New Features
maxOutputTokenscalculation, identity fingerprinting overhaul, and Cloud Code envelope payload sanitization (fix(antigravity): align identity protocol and fix streaming duplex #2055, fix(sse): send Antigravity Claude requests as Gemini schema #2063)omniroute providers,omniroute combos,omniroute doctor(feat(cli): Comprehensive CLI Enhancement Suite - 20+ new commands #2074)fallbackDelayMsto combo configuration and related settingsSTREAM_READINESS_TIMEOUT_MSand integrate into chat handlingtargetFormat: openai-responsesto all GitHub models (feat(github): add targetFormat openai-responses to all GitHub models #2122)buildComboCatalogMetadata()inlines contextLength, strategy, and target count for combo entries (Add metadata aggregation for combo models in /v1/models #2166 — thanks @faisalill)auto/prefix — dynamic virtual combo from connected providers with 6 variant profiles (coding, fast, cheap, offline, smart, lkgp), analytics tab, and settings UI (feat(auto): complete zero-config auto-routing with dashboard, settings, analytics, docs #2131 — thanks @oyi77)useUpstream429BreakerHintstoggle — per-provider default policy for upstream 429 hint trust at the circuit-breaker cooldown layer with tri-state PATCH semantics (feat(resilience): useUpstream429BreakerHints toggle (#2100 follow-up to #2116) #2133 — thanks @eleata)CHAT_LOG_TEXT_LIMIT,CHAT_LOG_ARRAY_TAIL_ITEMS,CHAT_LOG_MAX_DEPTH,CHAT_LOG_MAX_OBJECT_KEYS) andCHAT_DEBUG_FILEmode for untruncated JSON payloads (fix: Added in debug mode, support for storing raw data in json #2156 — thanks @bypanghu)background: trueto synchronous execution with a warning instead of throwingunsupportedFeature(feat(responses): degrade background mode to synchronous execution #2164 — thanks @Yosee11)config,status,logs,update,provider), 3 API endpoints, config generators for 6 tools (Claude, Cline, Codex, Continue, KiloCode, OpenCode), zero-configauto/routing, and@omniroute/opencode-providernpm package (feat: CLI Integration Suite for issue #2016 #2240 — thanks @oyi77)🐛 Bug Fixes
getPricingForModelfully case-insensitive to ensure custom prices correctly reflect in new incoming requests cost calculationsfunctionDeclarationsfrom being dropped by the sanitizer whengoogleSearchtool is present ([BUG] gemini cannot call tool use #2077)jsonMode: trueflag in the request transformation to enforce correct JSON structure from Pollinations API ([BUG] pollination AI #2109)/docsdirectory during build ensuring API catalog availability at runtime ([BUG] API catalog unavailable and Error Loading Documentation #2083)auto/*model prefix (fix: add fuzzy auto-combo routing for 'auto/*' model prefix #2010)/dashboard/onboardingas PUBLIC to unblock setup wizard (fix(authz): classify /dashboard/onboarding as PUBLIC to unblock setup wizard #2127)auto/prefix modelsbody.systemin openai→claude translator when Claude Code sends native Anthropic system array through /chat/completions — fixes v3.7.9 regression where system prompt was silently dropped, triggering Anthropic 429 ([BUG] v3.7.9 regression: system prompt missing for Claude Code OAuth on Linux, triggers Anthropic 429 #2130)reasoning_contenton assistant messages withtool_callsorfunction_call— fixes Kimi and other thinking-enabled providers returning 400 errors when reasoning_content was incorrectly stripped (fix(sanitizer): preserve reasoning_content on assistant messages with tool_calls #2140 — thanks @DavyMassoneto)context_lengthviagetTokenLimit()fallback chain — prevents OpenCode and other clients from falling back to conservative ~4000 token limit (fix(catalog): ensure individual models get context_length via getTokenLimit fallback #2136 — thanks @herjarsa).dockerignoreso API catalog documentation is available at runtime inside containers (fix: remove docs from .dockerignore #2120 #2137, [BUG] openapi.yaml file missing when building docker #2120 — thanks @hartmark)anytype elimination across 8 core files —antigravity.ts,accountFallback.ts,usage.ts,geminiHelper.ts,error.ts,apiKeys.ts,settings.ts,logger.ts(fix: remove docs from .dockerignore #2120 #2137 — thanks @hartmark)CLOUD_AGENT_PROVIDERSdeclaration, move Kiro dash→dot Claude model aliases toPROVIDER_MODEL_ALIASES, and trim deprecated Kiro registry entries (fix: remove duplicate cloud agent provider constants #2141 — thanks @backryun)/v1/modelsfor health when CPA 6.x has no/healthendpoint (fix(cliproxyapi): probe /v1/models for health (CPA 6.x has no /health) #2189 — thanks @Brkic-Nikola)/v1/messages, strip Capy extras, and round-tripmcp_*tool name rewrites toMcp_*(fix(cliproxyapi): Anthropic-shape body routing and gate compatibility #2165 — thanks @Brkic-Nikola)[DONE]terminator for Claude SSE clients (fix(stream): skip [DONE] terminator for Claude SSE clients #2190 — thanks @Brkic-Nikola)datafield onredacted_thinking, drop bogus signature (fix(claudeHelper): emit data field on redacted_thinking, drop bogus signature #2191 — thanks @Brkic-Nikola)body.toolsis omitted but message history containstool_calls, preventing 400 errors from Claude Code and OpenCode (fix(kiro): synthesize tools schema when history references tool_calls without body.tools #2149 — thanks @Gioxaa)classify429FromErrorto prevent premature account deactivation (fix(kiro): avoid treating high-traffic 429s as quota exhaustion #2153 — thanks @Gioxaa)includearray (e.g.reasoning.encrypted_content) during Chat→Responses API translation, fixing broken thinking panel in Codex/OpenCode (fix(openai-responses): propagate include so chat clients stream reasoning summaries #2154 — thanks @Gioxaa)delta.reasoning_content(flat) instead ofdelta.reasoning.summary(nested) for Chat Completions client compatibility (fix(openai-responses): emit reasoning summary as delta.reasoning_content #2159 — thanks @Gioxaa)cloudflaredTunnel.ts(fix: Added in debug mode, support for storing raw data in json #2156 — thanks @bypanghu)generationConfig.thinkingConfigfor Claude models routed through Antigravity to prevent upstream errors (fix(antigravity): strip generationConfig.thinkingConfig for Claude models #2217 — thanks @NomenAK)loadCodeAssist+fetchAvailableModelsfallback for robust startup (fix(antigravity): bootstrap project via loadCodeAssist + fetchAvailableModels fallback #2219 — thanks @NomenAK).stop()during runtime reset, evict cache instead to prevent stale rate-limit state (fix(rateLimit): never .stop() during runtime reset, evict cache instead #2218 — thanks @NomenAK)reasoning_contentthrough full pipeline for DeepSeek V4 models — prevents reasoning context loss on multi-turn conversations (fix(deepseek): preserve reasoning_content through full pipeline for DeepSeek V4 models #2231 — thanks @kang-heewon)submit_pr_reviewfunctionalChanges/findingsto arrays to prevent upstream schema errors (fix(translator): coerce submit_pr_review functionalChanges/findings to arrays #2242 — thanks @NomenAK)🔒 Security
📝 Documentation
GITLAB_DUO_OAUTH_CLIENT_IDto.env.example(docs(env): add GITLAB_DUO_OAUTH_CLIENT_ID to .env.example #2031)🔧 Improvements
sanitizeReasoningEffortForProvider()hook inBaseExecutor.execute()— downgradesxhigh→highfor unsupporting providers, strips effort for mistral/devstral and github claude models (fix(executors): sanitize reasoning_effort for non-supporting providers #2162 — thanks @hachimed)targetFormat === FORMATS.CLAUDEbodies (fix(translator): inject thinking placeholder for all Claude-shape upstreams #2161 — thanks @johndoe-oss).tsextension imports, eliminate allas anycasts, addCustomModelEntryinterface andComboModelSteptype predicate, normalize alias resolution withresolveCanonicalProviderId()(refactor(catalog): remove .ts imports, as any casts, normalize alias resolution #2152 — thanks @herjarsa)useUpstream429BreakerHintstri-state PATCH field —true/falsepersists,nullresets to undefined (omitted from JSON) (feat(resilience): expose model cooldown list with manual re-enable #2146 tests — thanks @rafacpti23)🧹 Chores & Maintenance
@lobehub/iconsweb fonts (chore(providers): prune redundant provider icon assets #1992)contextLengthandmaxOutputTokensfor claude, kiro, github, kimi-coding, xiaomi-mimo, codex/gpt-5.5 models (chore(registry): refresh per-model contextLength/maxOutputTokens for active providers #2163 — thanks @brucevoin)gpt-4omodel ID, update OpenCode Zen model (chore(models): tidy up alibaba-coding-plan and cursor provider #2150 — thanks @backryun)gray-matterfrom devDependencies to dependencies (runtime requirement) (fix: Added in debug mode, support for storing raw data in json #2156 — thanks @bypanghu)fast-urifrom 3.1.0 to 3.1.2 (deps: bump fast-uri from 3.1.0 to 3.1.2 #2078)honofrom 4.12.14 to 4.12.18 (deps: bump hono from 4.12.14 to 4.12.18 #2065, deps: bump hono from 4.12.14 to 4.12.18 #2079)electron-builderfrom 26.9.1 to 26.10.0 (deps: bump electron-builder from 26.9.1 to 26.10.0 in /electron #2183)package-lock.jsonto matchhttp-proxy-middleware4.x bump (build(deps): regenerate package-lock.json to match http-proxy-middleware bump #2228 — thanks @NomenAK)🏆 v3.8.0 Community Contributors
Thank you to all 55+ community contributors who made v3.8.0 possible! 🎉