From a9bc065996f6c6760531d18d68ecfc1242aa3905 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Mon, 20 Jul 2026 15:27:40 -0400 Subject: [PATCH] fix(core): balance truncated patch summaries --- packages/core/src/tool/structured.ts | 11 +++++++++-- packages/core/test/tool-edit.test.ts | 2 +- packages/core/test/tool-patch.test.ts | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/core/src/tool/structured.ts b/packages/core/src/tool/structured.ts index 50a691fc1b..968e5a52bf 100644 --- a/packages/core/src/tool/structured.ts +++ b/packages/core/src/tool/structured.ts @@ -44,10 +44,17 @@ export function patch(input: string, maximumBytes: number) { const parsed = parsePatch(input)[0] const hunk = parsed?.hunks[0] if (!parsed || !hunk) return truncate(input, maximumBytes) - const changed = [hunk.lines.find((line) => line.startsWith("-")), hunk.lines.find((line) => line.startsWith("+"))] + const changedLines = parsed.hunks.flatMap((item) => item.lines).filter((line) => /^[+-]/.test(line)) + const removed = changedLines.filter((line) => line.startsWith("-")) + const added = changedLines.filter((line) => line.startsWith("+")) + const changed = [removed[0], added[0]] .filter((line) => line !== undefined) .map((line) => line[0] + truncate(line.slice(1), Math.max(0, Math.floor(maximumBytes / 2) - 1))) - const lines = [...changed, " ... diff truncated ..."] + const lines = [ + ...changed, + ...(removed.length > 1 ? [`-... ${removed.length - 1} removed lines omitted ...`] : []), + ...(added.length > 1 ? [`+... ${added.length - 1} added lines omitted ...`] : []), + ] return formatPatch({ ...parsed, hunks: [ diff --git a/packages/core/test/tool-edit.test.ts b/packages/core/test/tool-edit.test.ts index 47182a59ce..3dd002fbc4 100644 --- a/packages/core/test/tool-edit.test.ts +++ b/packages/core/test/tool-edit.test.ts @@ -198,7 +198,7 @@ describe("EditTool", () => { const hunk = parsePatch(structured.files[0]?.patch ?? "")[0]?.hunks[0] expect(hunk?.lines.some((line) => line.startsWith("-"))).toBe(true) expect(hunk?.lines.some((line) => line.startsWith("+"))).toBe(true) - expect(hunk).toMatchObject({ oldLines: 2, newLines: 2 }) + expect(hunk).toMatchObject({ oldLines: 1, newLines: 1 }) expect(structured).toMatchObject({ replacements: 1, files: [ diff --git a/packages/core/test/tool-patch.test.ts b/packages/core/test/tool-patch.test.ts index ca9e132bd5..ecbb97a1e2 100644 --- a/packages/core/test/tool-patch.test.ts +++ b/packages/core/test/tool-patch.test.ts @@ -241,7 +241,7 @@ describe("PatchTool", () => { const hunk = parsePatch(structured.files[0]?.patch ?? "")[0]?.hunks[0] expect(hunk?.lines.some((line) => line.startsWith("-"))).toBe(true) expect(hunk?.lines.some((line) => line.startsWith("+"))).toBe(true) - expect(hunk).toMatchObject({ oldLines: 2, newLines: 2 }) + expect(hunk).toMatchObject({ oldLines: 1, newLines: 1 }) expect(structured).toMatchObject({ applied: [{ type: "update", resource: "large.txt" }], files: [{ file: "large.txt", patch: expect.stringContaining("... truncated ...") }],