import { bench, describe } from "vitest"; import { stripAnsi } from "../../extensions/compress/stages/ansi.js"; import { normalizeWhitespace } from "../../extensions/compress/stages/whitespace.js"; import { foldConsecutiveDuplicates } from "../../extensions/compress/stages/dedup.js"; import { normalizeSeparators } from "../../extensions/compress/stages/separator.js"; import { compressPaths, compilePathEntries } from "../../extensions/compress/stages/paths.js"; import { jsonToToon } from "../../extensions/compress/stages/toon.js"; import { countTokens, estimateTokens } from "../../extensions/compress/stages/tokens.js"; import { compressDynamicTokens } from "../../extensions/compress/stages/tokens_dyn.js"; // ── Fixtures ────────────────────────────────────────────────────────────────── const WS = "/Users/testuser/projects/my-long-workspace-path"; /** Simulate a realistic tool_result: mixed output with ANSI, trailing spaces, blanks */ const TOOL_OUTPUT_SMALL = `\x1b[32m✓\x1b[0m Tests passed \x1b[31m✗\x1b[0m 2 failures \x1b[1mfailure 1\x1b[22m: expected true but got false \x1b[1mfailure 2\x1b[22m: timeout after 5000ms `.repeat(5); const TOOL_OUTPUT_LARGE = TOOL_OUTPUT_SMALL.repeat(20); /** npm ls / ls -la style output */ const LS_OUTPUT = Array.from({ length: 80 }, (_, i) => `${WS}/src/components/Component${i}.tsx `, ).join("\n"); /** Stack trace with repeated paths */ const STACK_TRACE = Array.from({ length: 30 }, (_, i) => ` at Object. (${WS}/src/lib/utils.ts:${i + 1}:23)`, ).join("\n"); /** Log file with repeated lines */ const LOG_REPEATED = Array.from({ length: 50 }, (_, i) => i % 5 === 0 ? `[INFO] Processing batch ${i}` : `[DEBUG] connection established to db.local:5432`, ).join("\n"); /** Large uniform JSON array */ const JSON_ARRAY = JSON.stringify( Array.from({ length: 100 }, (_, i) => ({ id: i, name: `User ${i}`, email: `user${i}@example.com`, role: i % 3 === 0 ? "admin" : "user", active: i % 4 !== 0, createdAt: `2024-01-${String((i % 28) + 1).padStart(2, "0")}`, })), null, 2, ); const compiledPaths = compilePathEntries([{ path: WS, sigil: "$WS" }]); // ── Benchmarks ──────────────────────────────────────────────────────────────── describe("ansi.stripAnsi", () => { bench("small input with ANSI (~500 chars)", () => { stripAnsi(TOOL_OUTPUT_SMALL); }); bench("large input with ANSI (~10KB)", () => { stripAnsi(TOOL_OUTPUT_LARGE); }); bench("input with no ANSI (fast path)", () => { stripAnsi(LS_OUTPUT); }); }); describe("whitespace.normalizeWhitespace", () => { bench("ls-style output with trailing spaces (~3KB)", () => { normalizeWhitespace(LS_OUTPUT); }); bench("tool output with blank lines (~500 chars)", () => { normalizeWhitespace(TOOL_OUTPUT_SMALL); }); bench("already clean input (fast path)", () => { normalizeWhitespace("line1\nline2\nline3\nclean content here"); }); }); describe("dedup.foldConsecutiveDuplicates", () => { bench("log with repeated lines (~2KB)", () => { foldConsecutiveDuplicates(LOG_REPEATED); }); bench("stack trace with unique lines (~2KB)", () => { foldConsecutiveDuplicates(STACK_TRACE); }); }); describe("separator.normalizeSeparators", () => { bench("text with no separators (fast path)", () => { normalizeSeparators(LS_OUTPUT); }); bench("text with separator lines", () => { const withSeps = Array.from({ length: 20 }, (_, i) => i % 3 === 0 ? "─".repeat(80) : `content line ${i}`, ).join("\n"); normalizeSeparators(withSeps); }); }); describe("paths.compressPaths", () => { bench("stack trace with pre-compiled paths (~3KB)", () => { compressPaths(STACK_TRACE, [], compiledPaths); }); bench("ls output with pre-compiled paths (~4KB)", () => { compressPaths(LS_OUTPUT, [], compiledPaths); }); bench("stack trace without pre-compiled paths (on-the-fly)", () => { compressPaths(STACK_TRACE, [{ path: WS, sigil: "$WS" }]); }); }); describe("toon.jsonToToon", () => { bench("large uniform JSON array (~8KB)", () => { jsonToToon(JSON_ARRAY); }); bench("non-JSON text (fast path)", () => { jsonToToon(STACK_TRACE); }); bench("small JSON (below MIN_SIZE, fast path)", () => { jsonToToon('{"a":1}'); }); }); describe("tokens.countTokens (BPE)", () => { bench("small text (~50 chars)", () => { countTokens("The quick brown fox jumps over the lazy dog"); }); bench("medium text (~1KB)", () => { countTokens(TOOL_OUTPUT_SMALL); }); bench("large text (~10KB)", () => { countTokens(TOOL_OUTPUT_LARGE.slice(0, 10000)); }); }); describe("tokens.estimateTokens (÷3.5)", () => { bench("estimate for 1K chars", () => { estimateTokens(1000); }); bench("estimate for 100K chars", () => { estimateTokens(100000); }); }); describe("tokens_dyn.compressDynamicTokens", () => { bench("stack trace with repeated paths (~3KB)", () => { compressDynamicTokens(STACK_TRACE); }); bench("log with no structured tokens (fast path)", () => { compressDynamicTokens(LOG_REPEATED); }); bench("ls output with many unique paths (~4KB)", () => { compressDynamicTokens(LS_OUTPUT); }); });