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:
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user