Files
2026-07-13 13:39:12 +08:00

314 lines
11 KiB
TypeScript

/**
* TV1 — Transversal compression bail-out discipline (OPT-IN).
*
* Proves:
* 1. An engine that THROWS in apply() → step skipped (no throw, original body kept).
* 2. An engine whose gain is < minGainPercent (10%) → step skipped.
* 3. An engine with gain ≥ 10% → applied normally.
* 4. With bail-out DISABLED (default) → a <10%-gain engine IS applied
* (proving that opt-in default never changes existing behaviour).
*/
import { describe, it, before, after } from "node:test";
import assert from "node:assert/strict";
import {
applyStackedCompression,
applyStackedCompressionAsync,
} from "../../../open-sse/services/compression/index.ts";
import {
registerCompressionEngine,
unregisterCompressionEngine,
} from "../../../open-sse/services/compression/engines/registry.ts";
import type {
CompressionEngine,
CompressionEngineTarget,
} from "../../../open-sse/services/compression/engines/types.ts";
import type {
CompressionPipelineStep,
CompressionResult,
} from "../../../open-sse/services/compression/types.ts";
// ── helpers ──────────────────────────────────────────────────────────────────
/** Base skeleton shared by all fake engines. */
function makeBaseEngine(id: string): Omit<CompressionEngine, "apply"> {
return {
id,
name: id,
description: id,
icon: "x",
targets: ["messages"] as CompressionEngineTarget[],
stackable: true,
stackPriority: 0,
metadata: {
id,
name: id,
description: id,
inputScope: "messages",
targetLatencyMs: 1,
supportsPreview: false,
stable: true,
},
compress: (body) => ({ body, compressed: false, stats: null }),
getConfigSchema: () => [],
validateConfig: () => ({ valid: true, errors: [] }),
};
}
/** Engine that always throws during apply(). */
const THROW_ENGINE_ID = "bailout-throw-engine";
const throwEngine: CompressionEngine = {
...makeBaseEngine(THROW_ENGINE_ID),
apply: (_body) => {
throw new Error("simulated engine failure");
},
};
/** Engine that returns a low gain (5% < 10% threshold). */
const LOW_GAIN_ENGINE_ID = "bailout-low-gain-engine";
function makeLowGainEngine(id = LOW_GAIN_ENGINE_ID): CompressionEngine {
return {
...makeBaseEngine(id),
apply: (body) => {
const messages = (body.messages as Array<{ role: string; content: string }>) ?? [];
// Tag the user message; drop any padding (non-user) content so the body shrinks.
const next = messages.map((m) =>
m.role === "user" ? { ...m, content: m.content + "|low" } : { ...m, content: "" }
);
return {
body: { ...body, messages: next },
compressed: true,
stats: {
originalTokens: 100,
compressedTokens: 95,
savingsPercent: 5, // 5% < 10% threshold
techniquesUsed: [id],
mode: "stacked",
timestamp: 0,
durationMs: 0.1,
},
};
},
};
}
/** Engine that returns a high gain (20% ≥ 10% threshold). */
const HIGH_GAIN_ENGINE_ID = "bailout-high-gain-engine";
const highGainEngine: CompressionEngine = {
...makeBaseEngine(HIGH_GAIN_ENGINE_ID),
apply: (body) => {
const messages = (body.messages as Array<{ role: string; content: string }>) ?? [];
// Tag the user message; drop any padding (non-user) content so the body shrinks.
const next = messages.map((m) =>
m.role === "user" ? { ...m, content: m.content + "|high" } : { ...m, content: "" }
);
return {
body: { ...body, messages: next },
compressed: true,
stats: {
originalTokens: 100,
compressedTokens: 80,
savingsPercent: 20, // 20% ≥ 10% threshold
techniquesUsed: [HIGH_GAIN_ENGINE_ID],
mode: "stacked",
timestamp: 0,
durationMs: 0.1,
},
};
},
};
/** Async variant of the low-gain engine. */
const LOW_GAIN_ASYNC_ID = "bailout-low-gain-async";
const lowGainAsyncEngine: CompressionEngine = {
...makeLowGainEngine(LOW_GAIN_ASYNC_ID),
apply: (body) => ({ body, compressed: false, stats: null }), // sync pass-through (async-only pattern)
applyAsync: async (body) => makeLowGainEngine(LOW_GAIN_ASYNC_ID).apply(body),
};
/** Async variant of the throw engine. */
const THROW_ASYNC_ID = "bailout-throw-async";
const throwAsyncEngine: CompressionEngine = {
...makeBaseEngine(THROW_ASYNC_ID),
apply: (body) => ({ body, compressed: false, stats: null }), // sync pass-through
applyAsync: async (_body) => {
throw new Error("simulated async engine failure");
},
};
function pipeline(...ids: string[]): CompressionPipelineStep[] {
return ids.map((engine) => ({ engine })) as unknown as CompressionPipelineStep[];
}
function userContent(result: CompressionResult): string {
const messages = result.body.messages as Array<{ role: string; content: string }>;
return messages.find((m) => m.role === "user")!.content;
}
const BAILOUT_ON = { bailout: { enabled: true, minGainPercent: 10 } };
const BAILOUT_OFF = {}; // default — no bailout field
// A fixture body carrying a large droppable padding message. When an engine runs it
// drops that padding (and tags the user message), so the FINAL stacked body genuinely
// shrinks — keeping the #5527 (T02) inflation guard from reverting these advancement
// fixtures. The guard only reverts a pipeline whose final body did NOT shrink in tokens;
// these tests exercise bail-out/advancement, an orthogonal concern, so the body must
// realistically shrink for the marker assertions to survive the guard.
const PADDING = "padding tokens ".repeat(40);
function mkBody(): { messages: Array<{ role: string; content: string }> } {
return {
messages: [
{ role: "user", content: "hello" },
{ role: "assistant", content: PADDING },
],
};
}
// ── suite ────────────────────────────────────────────────────────────────────
describe("TV1 — stacked pipeline bail-out discipline (OPT-IN)", () => {
before(() => {
registerCompressionEngine(throwEngine);
registerCompressionEngine(makeLowGainEngine());
registerCompressionEngine(highGainEngine);
registerCompressionEngine(lowGainAsyncEngine);
registerCompressionEngine(throwAsyncEngine);
});
after(() => {
unregisterCompressionEngine(THROW_ENGINE_ID);
unregisterCompressionEngine(LOW_GAIN_ENGINE_ID);
unregisterCompressionEngine(HIGH_GAIN_ENGINE_ID);
unregisterCompressionEngine(LOW_GAIN_ASYNC_ID);
unregisterCompressionEngine(THROW_ASYNC_ID);
});
// ── SYNC tests ────────────────────────────────────────────────────────────
describe("sync — applyStackedCompression", () => {
it("bail-out ON: throwing engine → step skipped, pipeline does NOT throw", () => {
const body = mkBody();
// Must not throw and original body is kept (throw engine was the only step)
const result = applyStackedCompression(body, pipeline(THROW_ENGINE_ID), BAILOUT_ON);
assert.equal(result.compressed, false);
assert.equal(userContent(result), "hello"); // body unchanged
// TV1 fix: a crashing engine must be RECORDED in telemetry, not silently gone.
assert.equal(result.stats?.fallbackApplied, true, "throw must set fallbackApplied");
assert.ok(
result.stats?.validationErrors?.some((e) => e.includes(THROW_ENGINE_ID)),
"throwing engine must be recorded in validationErrors"
);
});
it("bail-out ON: throwing engine before a good engine → good engine still runs", () => {
const body = mkBody();
// throw engine first, then high-gain engine — the high-gain must still run
const result = applyStackedCompression(
body,
pipeline(THROW_ENGINE_ID, HIGH_GAIN_ENGINE_ID),
BAILOUT_ON
);
// high-gain engine appends "|high"
assert.equal(userContent(result), "hello|high");
assert.equal(result.compressed, true);
});
it("bail-out ON: low-gain engine (5%) → body NOT advanced (step skipped)", () => {
const body = mkBody();
const result = applyStackedCompression(body, pipeline(LOW_GAIN_ENGINE_ID), BAILOUT_ON);
// low-gain would append "|low" but it should be skipped
assert.equal(userContent(result), "hello");
// compressed is false because the only step was skipped
assert.equal(result.compressed, false);
});
it("bail-out ON: high-gain engine (20%) → body IS advanced normally", () => {
const body = mkBody();
const result = applyStackedCompression(body, pipeline(HIGH_GAIN_ENGINE_ID), BAILOUT_ON);
assert.equal(userContent(result), "hello|high");
assert.equal(result.compressed, true);
});
it("bail-out ON: low-gain then high-gain → only high-gain advances body", () => {
const body = mkBody();
const result = applyStackedCompression(
body,
pipeline(LOW_GAIN_ENGINE_ID, HIGH_GAIN_ENGINE_ID),
BAILOUT_ON
);
// "|low" should be absent; "|high" should be present
assert.equal(userContent(result), "hello|high");
});
it("bail-out OFF (default): low-gain engine IS applied (opt-in guard)", () => {
const body = mkBody();
// No bailout config at all — original behavior
const result = applyStackedCompression(body, pipeline(LOW_GAIN_ENGINE_ID), BAILOUT_OFF);
// Without bail-out, the step is always applied
assert.equal(userContent(result), "hello|low");
assert.equal(result.compressed, true);
});
it("bail-out OFF (default): throwing engine propagates — unchanged existing behavior", () => {
const body = mkBody();
// Without bail-out, a throw is NOT caught → pipeline throws
assert.throws(() => {
applyStackedCompression(body, pipeline(THROW_ENGINE_ID), BAILOUT_OFF);
}, /simulated engine failure/);
});
});
// ── ASYNC tests ───────────────────────────────────────────────────────────
describe("async — applyStackedCompressionAsync", () => {
it("bail-out ON: async throwing engine → step skipped, no throw", async () => {
const body = mkBody();
const result = await applyStackedCompressionAsync(body, pipeline(THROW_ASYNC_ID), BAILOUT_ON);
assert.equal(userContent(result), "hello");
assert.equal(result.compressed, false);
});
it("bail-out ON: async low-gain engine (5%) → step skipped", async () => {
const body = mkBody();
const result = await applyStackedCompressionAsync(
body,
pipeline(LOW_GAIN_ASYNC_ID),
BAILOUT_ON
);
assert.equal(userContent(result), "hello");
assert.equal(result.compressed, false);
});
it("bail-out OFF (default): async low-gain engine IS applied", async () => {
const body = mkBody();
const result = await applyStackedCompressionAsync(
body,
pipeline(LOW_GAIN_ASYNC_ID),
BAILOUT_OFF
);
assert.equal(userContent(result), "hello|low");
assert.equal(result.compressed, true);
});
});
});