Files
OmniRoute/tests/unit/probe-10268-structural-503.test.ts
Diego Rodrigues de Sa e Souza d49ccdaaf1 fix(sse): gate structural chat admission shedding on real heap pressure (#10437)
* fix(sse): gate structural chat admission shedding on real heap pressure

Closes #10183, Closes #10268

3.8.49 (#9654/#9940) replaced the 3.8.48 heap-ratio shed
(heapUsed/heapLimit >= 0.75) in chatBodyAdmission.ts with an
unconditional CHAT_MAX_HEAVY_IN_FLIGHT=1 structural lease. A second
concurrent "structurally heavy" chat request (>=200 messages, >=64
tools, or >=32k estimated tokens — routine for coding-agent fan-out
like Hermes/Cursor/Claude Code) was hard-rejected with a retryable
HTTP 503 chat_admission_busy/structure_limit regardless of actual
heap pressure, even on a host with ample free RAM.

Restore the heap-conditional gate as an ADDITIONAL check layered on
top of (not a replacement for) the #9654 bounded-concurrency /
per-connection-lane protection: when heavyweight capacity is busy,
only enter the bounded-wait/shed path when a live heap-pressure probe
(heapUsed / v8 heap_size_limit >= OMNIROUTE_CHAT_ADMISSION_HEAP_SHED_RATIO,
default 0.75) confirms real pressure. A healthy heap now admits the
second heavy request immediately via a no-op lease instead of parking
or shedding it. The probe is injectable via
admitChatStructure({ heapPressureCheck }) for deterministic tests.

Regression tests:
- tests/unit/bug-10183-admission-heavy-healthy-heap.test.ts (new,
  permanent): healthy-heap 2nd heavy request now admitted (was RED);
  genuinely pressured heap still sheds it.
- tests/unit/probe-10268-structural-503.test.ts (promoted to
  permanent): the exact reported 503 chat_admission_busy shape is
  still produced under real heap pressure, and the same fan-out is
  admitted on a healthy heap.
- tests/unit/chat-body-admission.test.ts,
  tests/unit/chat-body-admission-queue.test.ts,
  tests/unit/per-connection-admission-9654.test.ts updated to inject
  heapPressureCheck: () => true where they exercise the busy/shed
  path, preserving #9654/#4380 coverage.

Gates run: npm run typecheck:core (clean), eslint --suppressions-location
config/quality/eslint-suppressions.json on changed files (clean),
scripts/check/check-file-size.mjs (OK), scripts/check/check-test-discovery.mjs
(OK), focused admission suite (68/68 passing) and npm run test:unit
(in progress at commit time under heavy shared-devbox contention from
a 13-way parallel session fan-out; no admission-related failures
observed through 1873 lines of output, the sole failure seen was a
pre-existing unrelated proxy/search timeout consistent with known
load-induced flakiness, not a regression from this change).

⚠️ base-red inherited: #9985 — ESLint errors (2) from #10250

* docs(env): document OMNIROUTE_CHAT_ADMISSION_HEAP_SHED_RATIO (#10183, #10268)

* fix(sse): bound the healthy-heap admission fast path (#10437)

The #10183/#10268 fix admitted a busy heavyweight request immediately
whenever the heap was healthy, via an unconditional no-op lease with no
bound of its own -- an unlimited number of "healthy heap" requests could
pile in ahead of the heap-pressure shed path, defeating the point of
admission control.

Adds an independent, bounded healthy-heap headroom budget
(CHAT_ADMISSION_HEALTHY_HEADROOM, tryAcquireHealthyHeadroom()) that the
healthy-heap fast path draws from; once exhausted, requests fall through
to the same bounded-wait/shed path used under real heap pressure, which
is otherwise unchanged. Also fixes a pre-existing gap in
per-connection-admission-9654.test.ts's shared-budget test, which needed
an explicit heapPressureCheck override to keep exercising the #10110
invariant now that a healthy heap gets bounded headroom instead of an
outright reject.

* docs(env): document OMNIROUTE_CHAT_ADMISSION_HEALTHY_HEADROOM in .env.example

Documented in docs/reference/ENVIRONMENT.md but missing from .env.example,
caught by the env-doc-sync gate when combined with other PRs in the
release merge-train.

---------

Co-authored-by: adevwithpurpose <adevwithpurpose@users.noreply.github.com>
2026-08-18 10:50:09 -03:00

71 lines
3.3 KiB
TypeScript

// #10268: "[BUG] API call failed (attempt 1/3): InternalServerError [HTTP 503]" — Hermes
// Agent / Cursor coding-agent fan-out landed on the same structural admission gate as
// #10183 and burned its 3 retries on OmniRoute's own `chat_admission_busy` 503, which it
// misread as an upstream capacity error. Same root cause, same fix (heap-conditional
// shedding in `admitChatStructure`): this test is the permanent regression guard proving
// the exact reported 503 shape is still produced when heap pressure is GENUINELY high,
// so the #4380 heap-amplification shed path is preserved rather than removed outright.
import { test } from "node:test";
import assert from "node:assert/strict";
import {
admitChatStructure,
ChatAdmissionController,
type ChatAdmissionLease,
} from "../../src/shared/middleware/chatBodyAdmission.ts";
function heavyBody() {
const messages = Array.from({ length: 201 }, (_, i) => ({ role: "user", content: `prompt ${i}` }));
const tools = Array.from({ length: 32 }, (_, i) => ({
type: "function",
function: { name: `tool_${i}`, description: "a".repeat(64), parameters: { type: "object" } },
}));
return { model: "grok-4.5-fast-high", messages, tools, stream: true };
}
test("#10268: 2nd structurally-heavy agent request is rejected 503 (chat_admission_busy) under real heap pressure", async () => {
const controller = new ChatAdmissionController(1);
const first = await admitChatStructure(heavyBody(), null, { controller, queueMs: 0 });
assert.equal(first.admit, true);
const lease = (first as { admit: true; lease: ChatAdmissionLease | null }).lease;
assert.ok(lease);
try {
const second = await admitChatStructure(heavyBody(), null, {
controller,
queueMs: 0,
// Simulate genuine heap pressure (#10183/#10268 fix: shedding is now
// conditional on this, not unconditional on capacity alone).
heapPressureCheck: () => true,
});
assert.equal(second.admit, false); // reported failure path, still reachable under real pressure
const res = (second as { admit: false; response: Response }).response;
assert.equal(res.status, 503); // client is shown HTTP 503
const body = await res.json();
assert.equal(body.error?.message, "Structurally heavy chat request capacity is busy; retry shortly.");
assert.equal(body.error?.code, "chat_admission_busy");
assert.equal(body.error?.reason, "structure_limit");
} finally {
lease.release();
}
});
test("#10268: 2nd structurally-heavy agent request is admitted on a healthy heap (the fix)", async () => {
const controller = new ChatAdmissionController(1);
const first = await admitChatStructure(heavyBody(), null, { controller, queueMs: 0 });
assert.equal(first.admit, true);
const lease = (first as { admit: true; lease: ChatAdmissionLease | null }).lease;
assert.ok(lease);
try {
const second = await admitChatStructure(heavyBody(), null, {
controller,
queueMs: 0,
// No override: default heap probe reads live process stats (healthy here),
// reproducing legitimate Hermes/Cursor fan-out traffic that must no longer
// be shed on ample free RAM.
});
assert.equal(second.admit, true, "healthy heap must admit legitimate agent fan-out");
if (second.admit) second.lease?.release();
} finally {
lease.release();
}
});