- Fix `handoffProviders` and `nextBody` unknown property TS errors in contextHandoff
- Correct fallback payload parsing from responses `input` array in combo service
Fixes Cursor/Codex Responses compatibility: hoists system messages to instructions, normalizes tools, and translates responses-style traffic. Integrated into release/v3.5.4.
Adds support for non-standard stream aliases (non_stream, disable_stream, disable_streaming, streaming=false). Includes unit tests. Integrated into release/v3.5.4.
Fixes critical Anthropic streaming input token undercount + adds detailed token tracking with DB migration 018. Includes 18 new unit tests. Integrated into release/v3.5.4.
Preserves built-in Responses API tool types (web_search, file_search, computer, etc.) from empty-name filter. Includes 3 new unit tests. Integrated into release/v3.5.4.
Escape backslashes before injecting combo stream tags so tagged SSE
payloads remain valid JSON, and call the provider models handler
directly during sync to avoid internal fetch SSRF warnings.
Also restore crypto UUID generation for Gemini request translation,
tighten dashboard error sanitization, and update tests to use stricter
URL matching and UUID-based fixture keys.
Update the direct Next.js dependency to a patched release in response
to the reported audit findings.
Switch the provider diversity test to Vitest's expect API for
consistent test runner usage and add the audit report snapshot for
release verification.
Allow chat core callers to disable the emergency fallback path during
routed retries and expose proxy cache reset helpers for deterministic
state handling.
Add regression coverage for chat routing edge cases, combo strategies,
stream utilities, cursor SSE termination, and JSON-to-SQLite db
migration behavior.
Only use provider apiRegion values when they are strings before resolving
the GLM quota endpoint, preventing invalid metadata from affecting usage
requests.
Run unit tests with single-test concurrency to avoid shared-state flakes
and expand coverage for auth-protected routes, provider node validation,
proxy and stream handling, model sync, token refresh, and protobuf
parsing.
Keep the original combo and budget exhaustion errors when global or
emergency fallbacks also fail so callers see the real upstream cause.
Also preserve translated responses for memory extraction before output
post-processing, track pending rate-limit async work for deterministic
test resets, and expose usage helpers needed for deeper branch
coverage.
Expand unit coverage across moderation, media generation, streaming,
response logging, usage helpers, and fallback proxy error handling.
Move chat pipeline validation, circuit breaker execution, proxy
resolution, logging, and session header handling into dedicated
helpers to keep the SSE handler smaller and easier to verify.
Also fix shared API option precedence, rebuild skill version caches
after deletions, ignore api.trycloudflare.com false positives, and
add rate-limit manager test flush/reset hooks for deterministic
coverage.
Expand integration and unit coverage across chat routing, auth,
cloud sync, skills, executors, streaming, DB helpers, proxy handling,
and provider/model utilities.
- Removed the expensive (40s+) `npm run test:unit` step from the `pre-commit` hook
- Created `.husky/pre-push` to run the unit test suite before pushing rather than per commit
- This prevents spurious async teardown errors from local test runners from blocking fast commits
- Replaced an explicit `any` cast with `Record<string, unknown> | undefined` in `chatCore.ts` to pass the `check:any-budget:t11` strict checker which enforces a budget of 0
* feat(qoder): native cosy integration
* feat(qoder): implement native COSY encryption algorithm and remove CLI child instances, plus workflow bumps
* feat(resilience): context overflow fallback, OAuth token detection, empty content guard & context-optimized combo strategy
- Add isContextOverflowError + isContextOverflow detectors (400 + token-limit signals)
- Auto-fallback to next family model on context overflow in chatCore
- Add isEmptyContentResponse to catch fake-success empty responses, trigger fallback + recursive retry
- Add OAUTH_INVALID_TOKEN error type (T11) with isOAuthInvalidToken signal matching; warn instead of deactivating node
- Add getModelContextLimit helper in modelsDevSync (reads limit_context from synced capabilities)
- Upgrade getTokenLimit in contextManager to check models.dev DB before registry (fixes gemini-2.5-pro: 1000000→1048576)
- Add findLargerContextModel in modelFamilyFallback for context-aware model selection
- Add sortModelsByContextSize + context-optimized combo strategy in combo.ts
- Update context-manager unit test for corrected gemini-2.5-pro limit
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(review): address Gemini code review — tool_calls path, infinite recursion, dedup signals, findLargerContextModel
- Fix isEmptyContentResponse: check message.tool_calls/delta.tool_calls instead
of firstChoice.tool_calls (wrong OpenAI API path, caused tool-call responses
to be falsely flagged as empty)
- Fix empty content fallback: replace recursive handleChatCore call (infinite
recursion risk + wrong model due to original body.model) with non-recursive
pattern — call executeProviderRequest, parse fallback response body, reassign
responseBody and fall through to existing processing
- Fix context overflow: use findLargerContextModel over family candidates first,
fall back to getNextFamilyFallback — ensures we pick a model with actually
larger context window on overflow
- Fix signal dedup: export CONTEXT_OVERFLOW_SIGNALS + CONTEXT_OVERFLOW_REGEX
from errorClassifier.ts; import shared regex in modelFamilyFallback.ts,
removing duplicate signal list and per-call RegExp construction
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(UI): add context-optimized strategy to frontend schema and options
* fix(sse): preserve Responses API events in stream translation
When translating Claude-format responses (e.g. GLM) to Responses API
format for Codex CLI, the sanitizer stripped {event, data} structured
items to {"object":"chat.completion.chunk"}, losing all content and
the critical response.completed event.
Only run sanitizeStreamingChunk on OpenAI Chat Completions chunks,
skipping items that have the Responses API {event, data} structure.
* test(sse): add regression test for Claude→Responses stream sanitization
Verifies that {event,data} structured items from the Responses API
translator bypass sanitizeStreamingChunk when translating Claude-format
providers (e.g. GLM) to Responses API format for Codex CLI.
* fix(sse): strengthen Responses API event detection with response. prefix check
Use explicit `response.` prefix check instead of generic `event && data`
presence check, as recommended in PR review.
* fix: pin Next.js to 16.0.10 to prevent Turbopack hashed module bug
Remove ^ prefix from next and eslint-config-next to prevent
automatic upgrades to 16.1.x+ which introduced content-based
hashing for external module references in Turbopack.
Also remove duplicate Material Symbols @import from globals.css
(font already loaded via <link> in layout.tsx).
Fixes#509
* align cc-compatible cache handling with client passthrough
* chore: integrate resilience and turbopack fixes (PRs #992, #990, #987)
* chore(release): bump to v3.5.2 — changelog, docs, version sync
* docs(i18n): sync documentation updates to 33 languages
* fix(qoder): replace any with unknown to comply with strict any-budget
---------
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
Co-authored-by: oyi77 <oyi77@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Chris Staley <christopher-s@users.noreply.github.com>
Co-authored-by: Ivan <shanin-i2011@yandex.ru>
Co-authored-by: R.D. <rogerproself@gmail.com>
The hardcoded BUFFER_TOKENS = 2000 constant inflates prompt_tokens and
input_tokens in every API response, which is helpful for CLI tools that
rely on reported usage to manage context windows but misleading for SDK
users, cost dashboards, and any integration comparing token counts
across providers.
This change makes the buffer configurable via three layered sources
(in priority order):
1. Environment variable: USAGE_TOKEN_BUFFER=0
2. Settings API / Dashboard: PATCH /api/settings { usageTokenBuffer: 0 }
3. Default: 2000 (preserves existing behavior)
Setting the value to 0 disables the buffer entirely, causing OmniRoute
to return raw provider token counts. The setting is cached in-process
with a 30-second TTL and invalidated immediately when updated through
the settings API.
Changes:
- open-sse/utils/usageTracking.ts: replace hardcoded constant with
getBufferTokens() that reads env / DB settings with TTL cache
- src/shared/validation/settingsSchemas.ts: add usageTokenBuffer field
(int, 0–50000) to the Zod update schema
- src/app/api/settings/route.ts: invalidate buffer cache on update
- Add proxy support to all OAuth flows (authorization, token exchange, import)
- Add proxy support to token refresh operations for all providers
- Add proxy support to model synchronization
- Initialize global fetch proxy patch at server startup
- Use Proxy Registry with priority: Provider Proxy → Global Proxy → Direct
- Fix Global Proxy display in settings UI to show proxy from Proxy Registry
Changes:
- open-sse/services/tokenRefresh.ts: Add proxyConfig parameter to all refresh functions
- src/sse/services/tokenRefresh.ts: Resolve proxy before calling refresh functions
- src/app/api/oauth/*/route.ts: Use resolveProxyForProvider for OAuth flows
- src/app/api/providers/[id]/models/route.ts: Add proxy support for model sync
- src/instrumentation-node.ts: Initialize proxy patch at startup
- src/app/api/settings/proxy/route.ts: Read Global Proxy from Proxy Registry
- src/lib/db/proxies.ts: Export resolveProxyForProvider
- src/lib/localDb.ts: Re-export resolveProxyForProvider
- src/models/index.ts: Re-export resolveProxyForProvider
15 files changed, 405 insertions(+), 240 deletions(-)
Co-authored-by: growab <growab@users.noreply.github.com>
The tool was fully defined in schemas/tools.ts and backed by the
working /v1/search endpoint, but server.registerTool() was never
called, leaving it absent from tools/list.
Changes:
- server.ts: add webSearchInput import, handleWebSearch handler, and
server.registerTool("omniroute_web_search") after sync_pricing block
- schemas/tools.ts: align webSearchInput with /v1/search contract --
query max reduced 1000->500, provider narrowed to explicit enum
- essentialTools.test.ts: rewrite web_search stubs to dispatch through
a real McpServer+InMemoryTransport+Client, providing actual handler
coverage (POST method, body fields, error paths, tools/list check)
- vitest.mcp.config.ts: dedicated vitest config for MCP server tests;
update test:vitest script to use it
Note: omniRouteFetch hardcodes AbortSignal.timeout(10000) unconditionally
(server.ts line 126), so caller signals are silently discarded -- the
effective search timeout is 10s. Follow-up PR can add timeoutMs param.
cacheStatsTool and cacheFlushTool are also unregistered; out of scope.
🤖 Generated with Claude Sonnet 4.6 via Claude Code (https://claude.com/claude-code) + Compound Engineering v2.58.1
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>