mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
Adds compression engine that collapses repeated sibling lines (≥30 items with same indent + role prefix) into head + summary + tail, preserves [ref=eXX] anchors required by Playwright/computer-use MCPs, and hard-truncates oversized text with a navigation hint footer. Reduces token usage 60-80% on browser snapshots/accessibility trees from external MCP servers (playwright-mcp, chrome-mcp). Configurable via settings.compression.mcpAccessibility namespace. Changes: - open-sse/services/compression/engines/mcpAccessibility/: new engine (constants.ts, collapseRepeated.ts, index.ts with smartFilterText) - open-sse/services/compression/types.ts: re-exports McpAccessibilityConfig - src/lib/db/compression.ts: getMcpAccessibilityConfig/setMcpAccessibilityConfig - src/lib/db/migrations/056_mcp_accessibility_compression.sql: default settings - open-sse/mcp-server/server.ts: apply filter to all tool result text blocks - tests/unit/compression/mcpAccessibility.test.ts: 4 unit tests - tests/unit/mcp/serverSmartFilter.test.ts: 4 integration tests (DB getter/setter) Ref: 9router/src/lib/mcp/stdioSseBridge.js:14-90 (algorithm origin).
41 lines
1.8 KiB
TypeScript
41 lines
1.8 KiB
TypeScript
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { smartFilterText } from "@omniroute/open-sse/services/compression/engines/mcpAccessibility/index.ts";
|
|
import { DEFAULT_MCP_ACCESSIBILITY_CONFIG } from "@omniroute/open-sse/services/compression/engines/mcpAccessibility/constants.ts";
|
|
|
|
test("collapses ≥30 sibling buttons into head + summary + tail", () => {
|
|
const lines = [];
|
|
for (let i = 0; i < 50; i++) {
|
|
lines.push(` - button "Item ${i}" [ref=e${i}]`);
|
|
}
|
|
const input = lines.join("\n").padEnd(3000, " ");
|
|
const out = smartFilterText(input, DEFAULT_MCP_ACCESSIBILITY_CONFIG);
|
|
assert.ok(out.includes("Item 0"), "keeps head");
|
|
assert.ok(out.includes("Item 49"), "keeps tail");
|
|
assert.ok(out.includes('similar "button" items omitted'), "summarizes middle");
|
|
assert.ok(out.length < input.length, "compressed");
|
|
});
|
|
|
|
test("preserves [ref=eXX] anchors during truncation", () => {
|
|
const huge = ' - button "X" [ref=e123]\n' + "a".repeat(60000);
|
|
const out = smartFilterText(huge, DEFAULT_MCP_ACCESSIBILITY_CONFIG);
|
|
assert.ok(out.includes("[ref=e123]"), "preserves refs even on truncate");
|
|
assert.ok(out.length <= 50500, "respects maxTextChars + footer");
|
|
});
|
|
|
|
test('removes noise lines (- generic:, - text: "")', () => {
|
|
const input = [' - button "OK"', " - generic:", ' - text: ""', ' - link "Sign in"']
|
|
.join("\n")
|
|
.padEnd(3000, " ");
|
|
const out = smartFilterText(input, DEFAULT_MCP_ACCESSIBILITY_CONFIG);
|
|
assert.ok(!out.includes("- generic:"), "drops generic noise");
|
|
assert.ok(!out.match(/- text: ""/), "drops empty text noise");
|
|
assert.ok(out.includes("button"), "keeps signal");
|
|
});
|
|
|
|
test("returns unchanged when below minLengthToProcess", () => {
|
|
const small = "tiny";
|
|
const out = smartFilterText(small, DEFAULT_MCP_ACCESSIBILITY_CONFIG);
|
|
assert.equal(out, small);
|
|
});
|