mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-11 17:52:31 +03:00
161 lines
6.4 KiB
TypeScript
161 lines
6.4 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { spawnSync } from "node:child_process";
|
|
import { dirname, join } from "node:path";
|
|
import test from "node:test";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
import { sessionDedupEngine } from "../../../open-sse/services/compression/engines/session-dedup/index.ts";
|
|
|
|
const REPO_ROOT = join(dirname(fileURLToPath(import.meta.url)), "../../..");
|
|
const FIXTURE = join(REPO_ROOT, "tests/fixtures/compression/session-dedup-memory-7849.ts");
|
|
// #7849 originally bounded session-dedup with a shared "suffix work budget" that
|
|
// emitted SUFFIX_WORK_BUDGET_WARNING when exhausted. Commit 7f36b192f0 REPLACED
|
|
// that mechanism with the MAX_SUFFIX_STARTS / MAX_TOTAL_BLOCK_BYTES guards and
|
|
// removed both the budget and its warning. The invariant #7849 exists for — a
|
|
// line-rich long context must not blow the heap, and the engine must fail open —
|
|
// is unchanged and still guarded below; only the pins on the removed mechanism
|
|
// were rewritten. The budget size is kept as the input-shaping constant that
|
|
// produces the pathological pair.
|
|
const SUFFIX_WORK_BUDGET = 32 * 1024 * 1024;
|
|
|
|
function makeFixedWidthText(lineCount: number, lineChars: number, tag: string): string {
|
|
return Array.from({ length: lineCount }, (_, index) => {
|
|
const prefix = `${tag}-${index.toString().padStart(4, "0")}:`;
|
|
assert.ok(prefix.length <= lineChars);
|
|
return prefix + "x".repeat(lineChars - prefix.length);
|
|
}).join("\n");
|
|
}
|
|
|
|
function projectedSuffixWork(text: string, passCount: number): number {
|
|
let work = 0;
|
|
for (let start = 0; start <= text.length; start++) {
|
|
if (start === 0 || text.charCodeAt(start - 1) === 10) {
|
|
work += (text.length - start) * passCount;
|
|
}
|
|
}
|
|
return work;
|
|
}
|
|
|
|
function makeSharedBudgetBody(): Record<string, unknown> {
|
|
return {
|
|
messages: [
|
|
{ role: "tool", content: makeFixedWidthText(600, 49, "first") },
|
|
{ role: "tool", content: makeFixedWidthText(600, 49, "second") },
|
|
],
|
|
};
|
|
}
|
|
|
|
test("#7849: the two-message pathological pair stays bounded", () => {
|
|
const body = makeSharedBudgetBody();
|
|
const messages = body.messages as Array<{ content: string }>;
|
|
const perMessageWork = messages.map(({ content }) => projectedSuffixWork(content, 2));
|
|
|
|
assert.ok(
|
|
perMessageWork.every((work) => work < SUFFIX_WORK_BUDGET),
|
|
"each message must fit the two-pass budget on its own"
|
|
);
|
|
assert.ok(
|
|
messages.reduce((total, { content }) => total + projectedSuffixWork(content, 1), 0) <
|
|
SUFFIX_WORK_BUDGET,
|
|
"the pair must fit if incorrectly charged for only one pass"
|
|
);
|
|
assert.ok(
|
|
perMessageWork.reduce((total, work) => total + work, 0) > SUFFIX_WORK_BUDGET,
|
|
"the pair must exceed the shared budget when correctly charged for two passes"
|
|
);
|
|
|
|
for (const message of messages) {
|
|
const individualResult = sessionDedupEngine.apply({
|
|
messages: [message, { role: "assistant", content: "a unique short companion" }],
|
|
});
|
|
assert.equal(individualResult.stats, null, "each message must be accepted individually");
|
|
}
|
|
|
|
// The pathological pair must be processed BOUNDED — quickly and without
|
|
// corrupting the body. Pre-#7849 this shape retained one full-length suffix
|
|
// string per line and OOM-killed the heap.
|
|
const started = Date.now();
|
|
const result = sessionDedupEngine.apply(body);
|
|
assert.ok(
|
|
Date.now() - started < 4000,
|
|
"the pathological pair must stay fast; quadratic work would take seconds"
|
|
);
|
|
assert.strictEqual(result.body, body, "bounded processing must preserve the input body");
|
|
assert.equal(result.compressed, false, "the non-deduplicable pair must fail open");
|
|
assert.ok(Array.isArray((result.body as { messages?: unknown[] }).messages));
|
|
});
|
|
|
|
test("#7849: the pathological pair fails open, returning the input body untouched", () => {
|
|
const body = makeSharedBudgetBody();
|
|
const result = sessionDedupEngine.apply(body);
|
|
|
|
// Fail-open is the surviving contract: nothing deduplicable in this shape, so
|
|
// the ORIGINAL body comes back by identity and no compression is claimed. The
|
|
// explanatory zero-savings stats belonged to the removed budget path — the
|
|
// current guards skip before producing any, so stats is null.
|
|
assert.strictEqual(result.body, body, "failing open must return the input body by identity");
|
|
assert.equal(result.compressed, false);
|
|
assert.equal(result.stats, null);
|
|
});
|
|
|
|
test("#7849: near-boundary under-budget request still deduplicates", () => {
|
|
const repeatedText = makeFixedWidthText(578, 49, "same");
|
|
const projectedWork = projectedSuffixWork(repeatedText, 2) * 2;
|
|
assert.ok(projectedWork <= SUFFIX_WORK_BUDGET);
|
|
assert.ok(
|
|
SUFFIX_WORK_BUDGET - projectedWork < 100_000,
|
|
"fixture must remain close to the work-budget boundary"
|
|
);
|
|
|
|
const body = {
|
|
messages: [
|
|
{ role: "user", content: repeatedText },
|
|
{ role: "user", content: repeatedText },
|
|
],
|
|
};
|
|
const result = sessionDedupEngine.apply(body);
|
|
const messages = result.body.messages as Array<{ content: string }>;
|
|
|
|
assert.equal(result.compressed, true);
|
|
assert.equal(messages[0].content, repeatedText);
|
|
assert.match(messages[1].content, /^\[dedup:ref sha=[0-9a-f]{24}\]$/);
|
|
assert.ok((result.stats?.savingsPercent ?? 0) > 0);
|
|
assert.deepEqual(result.stats?.validationWarnings ?? [], []);
|
|
});
|
|
|
|
test(
|
|
"#7849: line-rich long context stays within a 512 MiB heap and the stacked pipeline continues",
|
|
{ timeout: 60_000 },
|
|
() => {
|
|
const child = spawnSync(
|
|
process.execPath,
|
|
["--max-old-space-size=512", "--import", "tsx/esm", FIXTURE],
|
|
{
|
|
cwd: REPO_ROOT,
|
|
encoding: "utf8",
|
|
timeout: 45_000,
|
|
}
|
|
);
|
|
|
|
assert.equal(
|
|
child.status,
|
|
0,
|
|
`compression child must not OOM or time out\nstdout: ${child.stdout}\nstderr: ${child.stderr}`
|
|
);
|
|
|
|
const output = JSON.parse(child.stdout) as {
|
|
enginesRun: string[];
|
|
warnings: string[];
|
|
};
|
|
assert.deepEqual(output.enginesRun, ["session-dedup", "lite", "rtk", "headroom", "caveman"]);
|
|
// The OOM guard is `child.status === 0` plus the full engine chain above:
|
|
// pre-fix this fixture killed the 512 MiB heap before the pipeline finished.
|
|
// session-dedup must still REPORT its skip; the exact reason string moved
|
|
// with the mechanism (7f36b192f0), so only the prefix is pinned.
|
|
assert.ok(
|
|
output.warnings.some((warning) => warning.startsWith("session-dedup: skipped")),
|
|
`expected a session-dedup skip warning, got ${JSON.stringify(output.warnings)}`
|
|
);
|
|
}
|
|
);
|