feat(coding-agent): compacted oversized sse payloads in debug buffer

- Added tool schema and description compaction for oversized data payloads in `packages/coding-agent/src/debug/raw-sse-buffer.ts`.
- Implemented head-tail trimming to preserve leading and trailing event fields when events exceed character budgets.
- Added test coverage verifying SSE debug event truncation, elision markers, and JSON-safe tool compaction behavior.
This commit is contained in:
can1357
2026-07-24 15:19:23 +02:00
parent 27e019981a
commit c6dcfa4137
4 changed files with 206 additions and 31 deletions
@@ -170,4 +170,51 @@ describe("RawSseDebugBuffer", () => {
expect(dataLines.at(-1)).toBe(1_005);
expect(dataLines.every((n, idx) => n === 6 + idx)).toBe(true);
});
it("keeps head and tail of an over-budget event with the middle elided", () => {
const buffer = new RawSseDebugBuffer();
const line = `data: {"type":"response.completed","id":"gen-head-marker","filler":"${"x".repeat(130_000)}","usage":{"output_tokens":42}}`;
buffer.recordEvent(
{ event: "response.completed", data: line.slice("data: ".length), raw: ["event: response.completed", line] },
model,
);
const record = buffer.snapshot().records[0];
if (record.kind !== "event") throw new Error("expected event record");
expect(record.truncated).toBe(true);
expect(record.originalChars).toBe("event: response.completed".length + 1 + line.length + 1);
expect(record.raw[0]).toBe("event: response.completed");
const text = record.raw.join("\n");
expect(text).toContain("gen-head-marker");
expect(text).toContain('"usage":{"output_tokens":42}}');
expect(text).toContain(": omp-debug-elided chars=");
expect(record.raw.at(-1)).toBe(`: omp-debug-truncated originalChars=${record.originalChars}`);
expect(text.length).toBeLessThanOrEqual(64_000);
});
it("compacts tool schemas in oversized data payloads so the JSON stays parseable", () => {
const buffer = new RawSseDebugBuffer();
const tools = Array.from({ length: 20 }, (_, i) => ({
type: "function",
name: `tool_${i}`,
description: "d".repeat(1_000),
parameters: { type: "object", properties: { arg: { type: "string", description: "p".repeat(4_000) } } },
}));
const data = JSON.stringify({
type: "response.created",
response: { id: "resp_1", tools, usage: { input_tokens: 7 } },
});
buffer.recordEvent({ event: "response.created", data, raw: [`data: ${data}`] }, model);
const record = buffer.snapshot().records[0];
if (record.kind !== "event") throw new Error("expected event record");
expect(record.truncated).toBe(true);
expect(record.raw.at(-1)).toBe(`: omp-debug-truncated originalChars=${data.length + "data: ".length + 1}`);
const parsed = JSON.parse(record.raw[0].slice("data: ".length));
expect(parsed.response.usage.input_tokens).toBe(7);
expect(parsed.response.tools).toHaveLength(20);
expect(parsed.response.tools[0].name).toBe("tool_0");
expect(typeof parsed.response.tools[0].parameters).toBe("string");
expect(parsed.response.tools[0].parameters).toContain("… (+");
expect(parsed.response.tools[0].description).toHaveLength(200 + "… (+800 chars)".length);
});
});