Commit Graph

6551 Commits

Author SHA1 Message Date
Brandon Bennett
8d78e3dfd3 fix: per-connection virtual admission lanes (#9654) (#9940)
* fix: add per-connection virtual admission lanes (#9654)

Worst-day-ever analysis to harden AdaptiveAdmissionController:

- Guard expireEntry() against null entry (CRITICAL null deref)
- Add deleteLane() to drain+reject on LRU eviction (HIGH orphaned promises)
- Fix Map mutation during evictIdleLanes iteration (MEDIUM safety)
- Add ADMISSION_LANE_EVICTED reject code (MEDIUM clarity)
- Pass sessionId to admitChatRequest in route.ts
- virtualLanes defaults to false in validateConfig
- 7 new controller tests + 14 new byte-level admission tests
- Assertions tightened from >= to === (Matt Pocock methodology)

Debunked 2 false positives: concurrency race (single-threaded JS)
and memory amplification (FairCostQueue bounds per-lane).

Fixes #9654

* fix(admission): restore bounded queue-wait on per-connection lanes (#9654)

The per-connection lane refactor dropped the bounded queue-wait
(acquireHeavyWithin / #waiters / queueMs). #9654's acceptance criteria and
#9608 section C prefer server-side wait/pacing up to defaultMaxWaitMs over
an instant retryable 503.

- ChatAdmissionController: re-add #waiters FIFO + acquireHeavyWithin(timeoutMs);
  queueMs: 0 preserves the instant-503 path
- admitChatStructure and admitChatRequest.reserve are async again and take queueMs
- route: pass CHAT_ADMISSION_QUEUE_MAX_MS and await the admission calls
- per-connection lane tests await the async admitChatStructure

Admission suite: 114/114 pass (bun test, 7 files).

* chore: re-trigger CI after dast-smoke infra cancellation (#9654)

* feat(admission): cancel queue-wait on client abort (#9654)

U2 from KC plan 2026-08-09-001. Thread the request AbortSignal through
acquireHeavyWithin so a disconnected client stops parking in the FIFO
for the full queueMs.

- acquireHeavyWithin(timeoutMs, signal?): on abort the waiter is removed
  from the FIFO immediately and the promise resolves null early;
  pre-aborted signals never park; the deadline timer is cleared when
  abort/release wins the race
- admitChatRequest reserve() passes request.signal; admitChatStructure
  gains options.signal; the route threads request.signal
- 5 exact-assertion tests (settle-early, pre-aborted, byte-heavy,
  structural, FIFO-preservation): 119/119 across the 7-file suite

* fix(admission): bound queued bytes for the queue-wait heap valve (#9654)

U3 from KC plan 2026-08-09-001. The restored queue-wait parks fully-buffered
bodies; without a cap, several large coding-agent bodies (~750 KB) waiting at
once recreates the #4380 heap amplification this module was built to stop.

- acquireHeavyWithin(timeoutMs, signal?, queuedBytes): each parked waiter is
  charged its buffered size against CHAT_ADMISSION_MAX_QUEUED_BYTES (default
  4 MB); over-budget waits reject immediately with a retryable 503 and never
  park. The charge is released on wake, abort, or timeout.
- Real sizes threaded from admitChatRequest (declared length / sniffed bytes);
  structural waits charge the conservative 256 KB weight.
- Lower default OMNIROUTE_CHAT_ADMISSION_QUEUE_MS to 2000ms (was 5000ms).
- Env vars documented in .env.example; 6 exact-assertion tests: 125/125 across
  the 7-file admission suite (was 119).

* docs: map the two admission-lane systems for operators (#9654)

U5 from KC plan 2026-08-09-001. Verifies lane metrics are exposed by the health
payload (GET /api/monitoring/health -> adaptiveAdmission -> lane* fields) and
records which lane system reports where: byte-level per-connection lanes (always
on, memory scope) vs adaptive virtual lanes (opt-in via OMNIROUTE_CHAT_VIRTUAL_LANES,
dispatch scope) plus the explicit opt-in ops note.

* docs: add required frontmatter to admission-lanes doc (dast-smoke build fix)

* docs: sync env vars with .env.example and ENVIRONMENT.md (docs gate fix)

* fix(admission): complete REJECT_MAP, literal lane env read, split oversized test file

Three CI-gate fixes surfaced by the post-merge check run (head 3de77166e):

1. open-sse-typecheck (TS2741): REJECT_MAP was missing the ADMISSION_LANE_EVICTED
   entry that controller.ts:662 emits on lane eviction. Add the 503 mapping so the
   Record<AdmissionRejectCode, RejectHttpMapping> is total.
2. Docs Gates fabricated-claim: OMNIROUTE_CHAT_VIRTUAL_LANES was read dynamically
   via ENV_KEYS.virtualLanes (env[key]), invisible to the literal env.X scanner.
   Read it literally — behavior-identical, doc claim now verifiable.
3. check:file-size: chat-body-admission.test.ts (1307 lines) exceeded the 1000-line
   new-file cap. Split the queue-wait/abort/heap-valve section into
   chat-body-admission-queue.test.ts (818 + 513 lines, both under cap).

Suite: 125/125 across 8 files. All three checkers pass locally.

* refactor(admission): drop dead ENV_KEYS.virtualLanes entry + lock lane-evicted mapping test

Code-review follow-up on 50c93d266:

1. ENV_KEYS.virtualLanes is now unreferenced since the literal env read landed;
   remove it so the config map only lists keys actually read through the map.
2. Add an exact-assertion runtime test for the ADMISSION_LANE_EVICTED mapping:
   a queued lane waiter evicted by the 60s idle TTL rejects with 503 /
   admission_lane_evicted / Retry-After 1 / sanitized body (no raw tenant key).
   Proves the REJECT_MAP entry end-to-end through buildAdmissionRejectResponse.

Suite: 126/126 (17 in runtime file, 125 in the 8-file admission suite).

---------

Co-authored-by: Brandon Bennett <brandonbennett@macbookair.myfiosgateway.com>
2026-08-10 03:25:13 -03:00
Vasily Larin
40f9709071 fix(executors): preserve non-strict Codex tool semantics (#9931)
* fix(executors): preserve non-strict Codex tool semantics

* docs(changelog): add Codex strict semantics fix
2026-08-10 03:25:07 -03:00
SB Yoon
e4a7da7526 feat(usage): add Command Code quota tracking (#9921)
Wire Bearer /alpha billing credits and 5h/weekly windows into Provider
Limits and genericQuotaFetcher so dashboard and preflight see live CC quotas.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-10 03:25:02 -03:00
agisota
b80afbb74f fix(proxy): isolate TLS sessions by account (#9837)
Co-authored-by: Antigravity Agent (via Agisota) <agisota@users.noreply.github.com>
2026-08-10 03:24:51 -03:00
Xiangzhe
2e6c151902 fix(providers): support data URL icons for compatible nodes (#9555)
Co-authored-by: xz-dev <xz-dev@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-08-10 03:22:59 -03:00
Aman
ee0073dc4a fix(db): invalidate stale LKGP pins on connection delete (#9936) 2026-08-10 02:54:59 -03:00
Bob.Hou
4fc04a5604 fix(combo): classify Cloudflare 1010 fingerprint rejection as non-auth (#9929)
opencode.ai/zen/v1 rejects non-browser clients (urllib) with 403
error_code 1010 while curl on the same key succeeds. The 403 was
treated as an auth-level failure and two of them crystallized a
misleading ALL_ACCOUNTS_INACTIVE on the free pool.

- errorClassifier: new FINGERPRINT_REJECTION type; a 403 carrying
  error_code 1010 / browser_signature_banned is the CDN refusing the
  client TLS/UA signature, not the account credentials.
- combo/targetExhaustion: fingerprint rejections skip auth-level
  exhaustion so remaining targets stay eligible.
- auth: resolveTerminalConnectionStatus no longer treats the
  fingerprint rejection as a terminal banned account state.

UA passthrough is deliberately untouched: #5997/#5720 make the
forward-only behavior load-bearing.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
2026-08-10 00:30:10 -03:00
rinseaid
a93f64ed5f fix(video): support Fal-hosted Grok Imagine Video (#9969)
Co-authored-by: rinseaid <rinseaid@rinseaid.net>
2026-08-10 00:30:04 -03:00
Aman
9bcb48a2d2 fix(db): avoid skipping pending job registry migration 146 (#9965) 2026-08-10 00:30:00 -03:00
backryun
7ad091be11 fix(types): complete responses stream failure contract (#9979) 2026-08-10 00:28:47 -03:00
backryun
cc3aa05c34 fix(stream): collect all synthesized response tool events (#9978) 2026-08-10 00:28:43 -03:00
backryun
160fd55a6d fix(types): normalize stream usage before cost calculation (#9977) 2026-08-10 00:28:37 -03:00
AgnesRiber
4cd9c8e39c fix(i18n): escape angle brackets in denoRelayOrgDomainHint across all 43 locales (#9976)
Replace literal <app-name> and <org-slug> with HTML entities (&lt; &gt;)
in the denoRelayOrgDomainHint translation key for all 43 locale files.

The React Flight (RSC) protocol parser interprets unclosed angle-bracket
tokens as HTML tags, causing INVALID_MESSAGE: UNCLOSED_TAG errors when
rendering the DenoRelayModal component on /dashboard/system/proxy.

Add regression test suite (tests/unit/i18n-deno-relay-unclosed-tag.test.ts)
covering four axes: valid JSON (no BOM), key existence, no raw angle brackets,
and correct HTML entities in all locales.
2026-08-10 00:28:31 -03:00
backryun
578bd379a9 chore(types): remove orphan combo manifest metrics (#9975) 2026-08-10 00:28:26 -03:00
backryun
a13107731f fix(types): type Copilot WebSocket construction (#9974) 2026-08-10 00:28:21 -03:00
backryun
6285cfd26e fix(types): align Claude message contracts (#9973) 2026-08-10 00:28:16 -03:00
backryun
987b03c334 fix(types): narrow combo model collections (#9972) 2026-08-10 00:28:11 -03:00
backryun
de2679f6d1 fix(types): stabilize skill token extraction (#9920) 2026-08-10 00:28:07 -03:00
Donald Thompson
f390327c88 fix(cleanup): prune mcp_tool_audit/a2a_task_events by created_at column (#9963)
Both tables (002_mcp_a2a_tables.sql) store their row timestamp in
created_at; the cleanup queries used WHERE timestamp < ? which does not
exist, so every boot-time cleanup logged:
  Error cleaning mcp_tool_audit: SqliteError: no such column: timestamp
  Error cleaning a2a_task_events: SqliteError: no such column: timestamp
and retention pruning for these two tables never ran. Fix the DELETE
columns and align the log labels/doc comments with the real table names.

Adds source-level invariant tests (cleanup-column-fix.test.mjs) asserting
the created_at column for both tables.
2026-08-10 00:28:02 -03:00
tald26
9cd5d64484 fix(mcp): stop omniroute_get_health silently discarding real data (#9959)
process.uptime() returns a number, but the handler ran it through a
string-only toString() helper that fell back to "unknown" for anything
that wasn't already a string -- so every real uptime value was
discarded, 100% reproducibly.

Also stop masking upstream fetch failures as fake healthy defaults:
when /api/monitoring/health, /api/resilience, or /api/rate-limits
can't be reached, the tool now reports which source failed (via a new
optional `degraded` field) instead of returning zeros/empty arrays
indistinguishable from genuine "no data".

Regression coverage dispatches through the real MCP handler (client.callTool)
rather than asserting on the mock directly, since the prior mock-only
tests could never have caught either bug.
2026-08-10 00:27:58 -03:00
Sahil Singh
d0e15a8c0b fix(backend): retain streaming usage for providers with choices:[{delta:{}}] final chunk (#9938) 2026-08-10 00:27:52 -03:00
Rakibul Hasan
4938a435ea fix(memory): env-configurable strict system-message-first providers (#9924)
* fix(memory): allow OMNIROUTE_STRICT_SYSTEM_PROVIDERS to extend the system-first provider list

PROVIDERS_SYSTEM_MUST_BE_FIRST (added in #6225 for #6135) gates both the
memory-injection placement fix and the #7293 hoistLeadingSystemMessage
translator fix, but was hardcoded to xiaomi-mimo/mimo only. Self-hosted
deployments routing other strict backends (e.g. a custom OpenAI-compatible
connection in front of a self-hosted Qwen3.5+/3.6 model, whose chat template
rejects any non-leading system message the same way) had no way to opt in
without forking and rebuilding the image.

Adds OMNIROUTE_STRICT_SYSTEM_PROVIDERS (comma-separated, case-insensitive
provider ids) to extend the built-in set at read time, mirroring the
injectable-env pattern already used in src/lib/memory/typedDecay.ts. No
behavior change for anyone who doesn't set it.

* chore: fix changelog fragment PR number
2026-08-10 00:27:47 -03:00
K R HARI PRAJWAL
27abbba740 docs: add quickstart code examples for Python, Node.js, PHP and cURL (#9922)
Add examples/quickstart/ with minimal copy-paste scripts that let new
users get a response from a local OmniRoute server in under a minute,
without needing to read the full docs first.

Files added:
- examples/quickstart/python_requests.py  (requests library)
- examples/quickstart/nodejs_axios.js     (axios)
- examples/quickstart/curl_terminal.sh    (bash one-liner)
- examples/quickstart/php_curl.php        (cURL extension)
- examples/quickstart/README.md           (table + key-settings cheatsheet)

README.md: add one sub-line pointer to examples/quickstart/ below the
existing zero-config curl snippet, matching the surrounding <sub> style.
2026-08-10 00:27:43 -03:00
Lucas Aleixo
580df8d0bb chore: ignore docker-compose.override.yml (#9919) 2026-08-10 00:27:38 -03:00
diegosouzapw
44fd0edd85 chore(quality): file-size baseline +30% (DRIFT rebaseline for v3.8.51)
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-08-10 00:24:13 -03:00
Diego Rodrigues de Sa e Souza
6553ba31f2 feat(dashboard): Modality Bridge settings page (vision tabs, model selector, stats, test button) (#9782)
* feat(i18n): modality bridge page strings (en + synced locales)

* feat(dashboard): ModalityBridgeVisionTab + stats row + test button

* feat(dashboard): Modality Bridge settings page with vision/audio/video tabs + sidebar entry

* feat(dashboard): relocate vision bridge card to link + media-providers shortcuts

* docs(guardrails): document Modality Bridge dashboard

* chore: preserve upstream formatting after base merge

* fix(modality-bridge): satisfy i18n quality gates

* fix(i18n): preserve canonical Chinese glossary terms

* fix(modality-bridge): clear dashboard quality regressions

* fix(settings): use catalog-only modality labels

* fix(i18n): isolate modality bridge availability copy

* chore(i18n): prepare conflict-free Modality Bridge base sync

* docs(modality-bridge): align migration note with dead-code decision

* fix(i18n): sync capability filter locales after release merge

* fix(i18n): restore canonical Traditional Chinese glossary

---------

Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
2026-08-10 00:16:06 -03:00
Diego Rodrigues de Sa e Souza
06a691f8fe Merge pull request #9424 from diegosouzapw/feat/5696-layer-a-capability-filter
feat(core): add Layer A capability filter at router (#5696)
2026-08-09 20:51:28 -03:00
SB Yoon
40e1562850 fix(i18n): re-escape CC discovery-alias angle brackets for next-intl (#9917)
* fix(i18n): re-escape CC discovery-alias angle brackets for next-intl

Restore #8747 HTML-entity escaping for claude/<provider>/<model> in the
three CC discovery-alias message keys so next-intl stops logging
INVALID_MESSAGE: UNCLOSED_TAG on provider detail pages after the bulk
entity-unescape regression.

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(i18n): align conflict context with release

* fix(i18n): cover localized CC alias placeholders

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
2026-08-09 20:27:18 -03:00
diegosouzapw
63bf4b909d Merge remote-tracking branch 'origin/release/v3.8.50' into codex/wave3b-9424
# Conflicts:
#	config/quality/file-size-baseline.json
2026-08-09 20:02:17 -03:00
Diego Rodrigues de Sa e Souza
fade1cbab3 Merge pull request #9341 from diegosouzapw/feat/9268-gemini-schema-recursive-type-empty-choices
feat(gemini): recursive schema type:object + empty choices interceptor (#9268)
2026-08-09 20:01:44 -03:00
Diego Rodrigues de Sa e Souza
3aa0a7306f Merge pull request #9337 from diegosouzapw/feat/9322-nanogpt-endpoint-surface
feat: expose full NanoGPT endpoint surface (#9322)
2026-08-09 20:01:41 -03:00
Diego Rodrigues de Sa e Souza
9d06dcfd6c Merge pull request #9493 from diegosouzapw/feat/8468-bun-windows-ci-coverage
feat(ci): add windows-latest leg to test-bun-sqlite job (#8468)
2026-08-09 20:01:39 -03:00
diegosouzapw
9747123f00 test(flags): account for capability filter flag 2026-08-09 19:41:17 -03:00
Diego Rodrigues de Sa e Souza
ab8f3e83b7 fix(ci): allow test-masking to finish in release preflight (#9964)
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
2026-08-09 19:41:03 -03:00
diegosouzapw
8685815235 fix(i18n): translate capability filter messages 2026-08-09 19:23:58 -03:00
diegosouzapw
e53ca645f3 Merge remote-tracking branch 'origin/release/v3.8.50' into codex/wave3b-9424 2026-08-09 19:23:58 -03:00
Diego Rodrigues de Sa e Souza
1828b6c14a Merge pull request #9784 from benzntech/feat/cookie-editor-guide-ui
feat(providers): add Cookie Editor fast-path to web session credential guide
2026-08-09 19:10:32 -03:00
diegosouzapw
cf0f416da3 Merge remote-tracking branch 'origin/release/v3.8.50' into codex/wave3b-9424 2026-08-09 18:57:50 -03:00
diegosouzapw
2c8cb81fc0 Merge remote-tracking branch 'origin/release/v3.8.50' into codex/wave3b-9341 2026-08-09 18:57:46 -03:00
diegosouzapw
1287a4f2ec Merge remote-tracking branch 'origin/release/v3.8.50' into codex/wave3b-9337 2026-08-09 18:57:00 -03:00
diegosouzapw
471d39bc1f Merge remote-tracking branch 'origin/release/v3.8.50' into codex/wave3b-9493 2026-08-09 18:56:57 -03:00
diegosouzapw
99781e000d Merge remote-tracking branch 'origin/release/v3.8.50' into codex/wave2b-9784 2026-08-09 18:56:19 -03:00
Diego Rodrigues de Sa e Souza
159b90125c Merge pull request #9749 from benzntech/fix/lean-defaults-three-defects
fix(logging): make stream-chunk capture and request-shape logging opt-in
2026-08-09 18:55:56 -03:00
diegosouzapw
70fca36f9d fix(i18n): complete web session guide translations
Co-authored-by: benzntech <4044180+benzntech@users.noreply.github.com>
2026-08-09 18:54:55 -03:00
diegosouzapw
94d386dbc5 fix(quality): update capability gate frozen cap 2026-08-09 18:51:34 -03:00
diegosouzapw
3ff25a484f fix(stream): type empty-choice collector events 2026-08-09 18:47:22 -03:00
diegosouzapw
2bea34b0a6 chore(quality): attribute capability gate growth 2026-08-09 18:47:22 -03:00
diegosouzapw
f3ba480c08 Merge remote-tracking branch 'origin/release/v3.8.50' into codex/wave3b-9341 2026-08-09 18:28:40 -03:00
diegosouzapw
8e812c53e5 Merge remote-tracking branch 'origin/release/v3.8.50' into codex/wave3b-9424 2026-08-09 18:28:40 -03:00
diegosouzapw
f39daccfcb Merge remote-tracking branch 'origin/release/v3.8.50' into codex/wave3b-9337 2026-08-09 18:28:39 -03:00