Files
OmniRoute/tests/unit/stream-active-timeout-covers-model-budgets.test.ts
initguru 3e080877f2 fix(sse): bound active streams without terminal events (#12913)
* fix(sse): bound active streams without terminal events

* fix(sse): derive the active-stream ceiling from the largest registered model budget

The watchdog is a hard lifetime cap that never resets on bytes, so a flat
15-minute default killed models the registry already allows to run for 20
minutes (the Codex entries declare timeoutMs: 1_200_000). The default is now
that maximum plus a one-minute margin, and a new test re-derives the maximum
from the registry so a future larger budget fails the gate instead of silently
re-opening the bug.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-09-17 10:44:48 -03:00

61 lines
2.4 KiB
TypeScript

/**
* #12913 — the active-stream watchdog is a HARD lifetime cap: it never resets on
* upstream bytes. If its default ever drops below the largest per-model
* `timeoutMs` the provider registry declares, a model that is allowed to run for
* its full budget gets killed mid-answer by the watchdog instead of finishing.
*
* This test re-derives the maximum registered budget from the registry source and
* fails when the default stops covering it, so a future `timeoutMs: 1_800_000`
* entry cannot silently re-open the bug.
*/
import test from "node:test";
import assert from "node:assert/strict";
import { readdirSync, readFileSync, statSync } from "node:fs";
import { join } from "node:path";
import {
DEFAULT_STREAM_ACTIVE_TIMEOUT_MS,
MAX_REGISTERED_MODEL_TIMEOUT_MARGIN_MS,
} from "../../src/shared/utils/runtimeTimeouts.ts";
const REGISTRY_ROOT = join(process.cwd(), "open-sse/config/providers/registry");
const TIMEOUT_LITERAL = /timeoutMs:\s*([0-9_]+)/g;
function collectTsFiles(dir: string, out: string[] = []): string[] {
for (const entry of readdirSync(dir)) {
const full = join(dir, entry);
if (statSync(full).isDirectory()) collectTsFiles(full, out);
else if (full.endsWith(".ts")) out.push(full);
}
return out;
}
function maxRegisteredTimeoutMs(): { value: number; file: string } {
let best = { value: 0, file: "" };
for (const file of collectTsFiles(REGISTRY_ROOT)) {
const source = readFileSync(file, "utf8");
for (const match of source.matchAll(TIMEOUT_LITERAL)) {
const value = Number(match[1].replaceAll("_", ""));
if (Number.isFinite(value) && value > best.value) best = { value, file };
}
}
return best;
}
test("the default active-stream budget covers every per-model timeoutMs in the registry", () => {
const max = maxRegisteredTimeoutMs();
assert.ok(max.value > 0, "expected at least one timeoutMs literal in the provider registry");
assert.ok(
DEFAULT_STREAM_ACTIVE_TIMEOUT_MS >= max.value,
`DEFAULT_STREAM_ACTIVE_TIMEOUT_MS (${DEFAULT_STREAM_ACTIVE_TIMEOUT_MS}) must stay >= the largest ` +
`registered model timeoutMs (${max.value}, declared in ${max.file}); otherwise the active ` +
`watchdog kills a model that is still inside its own budget.`
);
assert.equal(
DEFAULT_STREAM_ACTIVE_TIMEOUT_MS,
max.value + MAX_REGISTERED_MODEL_TIMEOUT_MARGIN_MS,
"the default is documented as the largest registered budget plus the margin — update both together"
);
});