mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-07 07:42:13 +03:00
Squash merge from local merge-train (Hard Rule owner-approved). Tip 029cdf4215cf465f0e1716ac9f84a84692b1e881 validated on 192.168.0.113: 26631/26653 pass.
95 lines
3.7 KiB
TypeScript
95 lines
3.7 KiB
TypeScript
import test from "node:test";
|
||
import assert from "node:assert/strict";
|
||
import { compressContext } from "../../open-sse/services/contextManager.ts";
|
||
|
||
// #8594 — six production call sites (compressContext layers + purifyHistory binary
|
||
// search + the combo.ts fallback threshold) pre-JSON.stringify the messages before
|
||
// handing them to estimateTokens(). Stringifying forces the char/4 text path and
|
||
// undoes the #8368 inline-base64-image bounded estimate, so an image-bearing request
|
||
// that fits comfortably is mis-measured as ~100× larger and compressed needlessly.
|
||
|
||
function makeFakePngBase64(approxBytes: number): string {
|
||
return Buffer.alloc(approxBytes, 65).toString("base64");
|
||
}
|
||
|
||
test("#8594: compressContext does NOT compress a within-limit inline-image request", () => {
|
||
// ~500KB image => ~666KB base64. As raw text that is ~166k tokens (over the limit);
|
||
// as a bounded image estimate it is ~1.2k tokens (well under). maxTokens=20000 sits
|
||
// between the two, so the bug (stringify) trips compression and the fix does not.
|
||
const base64 = makeFakePngBase64(500_000);
|
||
const body = {
|
||
model: "gpt-image-vision",
|
||
messages: [
|
||
{ role: "system", content: "You are a helpful vision assistant." },
|
||
{
|
||
role: "user",
|
||
content: [
|
||
{ type: "text", text: "What is in this image?" },
|
||
{ type: "image_url", image_url: { url: `data:image/png;base64,${base64}` } },
|
||
],
|
||
},
|
||
],
|
||
};
|
||
|
||
const result = compressContext(body, { maxTokens: 20000, reserveTokens: 0 });
|
||
|
||
assert.equal(
|
||
result.compressed,
|
||
false,
|
||
`BUG #8594 reproduced: within-limit image request was compressed. ` +
|
||
`stats.original=${(result.stats as { original?: number }).original} tokens ` +
|
||
`(should be a bounded ~1.2k image estimate, not the ~166k base64-as-text value)`
|
||
);
|
||
assert.ok(
|
||
(result.stats as { original: number }).original < 5000,
|
||
`expected bounded image-token estimate (<5000), got ${(result.stats as { original: number }).original}`
|
||
);
|
||
});
|
||
|
||
test("#8594: purifyHistory keeps all image-bearing turns when they fit within the limit", () => {
|
||
// Multiple image messages that, measured correctly, fit under the limit. The bug
|
||
// makes the Layer-3 binary search over-estimate and prune turns; the fix preserves them.
|
||
const base64 = makeFakePngBase64(200_000);
|
||
const imageTurn = (n: number) => ({
|
||
role: "user",
|
||
content: [
|
||
{ type: "text", text: `Image number ${n}` },
|
||
{ type: "image_url", image_url: { url: `data:image/png;base64,${base64}` } },
|
||
],
|
||
});
|
||
const body = {
|
||
model: "gpt-image-vision",
|
||
messages: [
|
||
{ role: "system", content: "vision" },
|
||
imageTurn(1),
|
||
{ role: "assistant", content: "ok 1" },
|
||
imageTurn(2),
|
||
{ role: "assistant", content: "ok 2" },
|
||
imageTurn(3),
|
||
{ role: "assistant", content: "ok 3" },
|
||
],
|
||
};
|
||
const originalCount = body.messages.length;
|
||
|
||
const result = compressContext(body, { maxTokens: 20000, reserveTokens: 0 });
|
||
|
||
assert.equal(result.compressed, false, "within-limit image history must not be compressed");
|
||
assert.equal(
|
||
(result.body as { messages: unknown[] }).messages.length,
|
||
originalCount,
|
||
"all image-bearing turns must be retained when they fit"
|
||
);
|
||
});
|
||
|
||
test("#8594: control — an oversized text request is still compressed (no regression)", () => {
|
||
const body = {
|
||
model: "gpt-text",
|
||
messages: [
|
||
{ role: "system", content: "s" },
|
||
{ role: "user", content: "a".repeat(200_000) }, // ~50k tokens, over a 20k limit
|
||
],
|
||
};
|
||
const result = compressContext(body, { maxTokens: 20000, reserveTokens: 0 });
|
||
assert.equal(result.compressed, true, "oversized text must still trigger compression");
|
||
});
|