From a2489efcb95430999fc7da9c8a6fd2ba03a27175 Mon Sep 17 00:00:00 2001 From: Neal Daftary Date: Wed, 12 Aug 2026 05:05:38 +0530 Subject: [PATCH] fix(summary): keep every text block in structured tool results (#1619) formatResultContent recognized structured tool output shaped like `[{ type: "text", text: "..." }]` but read only `parsedContent[0].text`. When a tool result split its output across several text blocks, the step summary showed the first and silently dropped the rest, so extra findings, file paths and follow-up instructions vanished from the rendered Claude Code Report while remaining in the execution transcript. Collect the text from every block instead of just the first. Blocks of other types, such as images, are skipped rather than stringified into the summary. Fixes #1572 Co-authored-by: Claude Opus 5 --- src/entrypoints/format-turns.ts | 12 ++++++++--- test/format-turns.test.ts | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/entrypoints/format-turns.ts b/src/entrypoints/format-turns.ts index 88dd587c..c8d63e30 100644 --- a/src/entrypoints/format-turns.ts +++ b/src/entrypoints/format-turns.ts @@ -164,9 +164,15 @@ export function formatResultContent(content: any): string { typeof parsedContent[0] === "object" && parsedContent[0]?.type === "text" ) { - // Extract the text field from the first item. Tool output is arbitrary, - // so `text` is not guaranteed to be a string. - contentStr = String(parsedContent[0]?.text || ""); + // Keep every text block, not just the first: a tool result may split its + // output across several, and dropping the rest silently loses findings, + // file paths and follow-up instructions from the rendered summary. Blocks + // of other types (for example images) are skipped. Tool output is + // arbitrary, so `text` is not guaranteed to be a string. + contentStr = parsedContent + .filter((block: any) => block?.type === "text") + .map((block: any) => String(block?.text || "")) + .join("\n"); } else { contentStr = String(content).trim(); } diff --git a/test/format-turns.test.ts b/test/format-turns.test.ts index 28fc0db9..23020d75 100644 --- a/test/format-turns.test.ts +++ b/test/format-turns.test.ts @@ -111,6 +111,42 @@ describe("formatResultContent", () => { const result = formatResultContent(JSON.stringify(structuredContent)); expect(result).toBe("**→** Hello world\n\n"); }); + + test("keeps every text block, not just the first", () => { + const structuredContent = [ + { type: "text", text: "first line" }, + { type: "text", text: "second line" }, + { type: "text", text: "third line" }, + ]; + const result = formatResultContent(JSON.stringify(structuredContent)); + + expect(result).toContain("first line"); + expect(result).toContain("second line"); + expect(result).toContain("third line"); + }); + + test("keeps every text block when given an array directly", () => { + const result = formatResultContent([ + { type: "text", text: "alpha" }, + { type: "text", text: "beta" }, + ]); + + expect(result).toContain("alpha"); + expect(result).toContain("beta"); + }); + + test("skips non-text blocks while keeping the text ones", () => { + const structuredContent = [ + { type: "text", text: "visible" }, + { type: "image", source: { data: "ignored-binary" } }, + { type: "text", text: "also visible" }, + ]; + const result = formatResultContent(JSON.stringify(structuredContent)); + + expect(result).toContain("visible"); + expect(result).toContain("also visible"); + expect(result).not.toContain("ignored-binary"); + }); }); describe("formatToolWithResult", () => {