From a50239a9f5eeb61887d5dbfcaa07ea8bd9acf4b6 Mon Sep 17 00:00:00 2001 From: yushen Date: Fri, 6 Feb 2026 19:12:51 +0800 Subject: [PATCH] fix(subagent): require coalesced announce to include all findings --- src/agent/subagent/announce.test.ts | 18 +++++++++++++++++- src/agent/subagent/announce.ts | 18 +++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/agent/subagent/announce.test.ts b/src/agent/subagent/announce.test.ts index 28fafee1..f532dd5c 100644 --- a/src/agent/subagent/announce.test.ts +++ b/src/agent/subagent/announce.test.ts @@ -232,7 +232,23 @@ describe("formatCoalescedAnnouncementMessage", () => { const msg = formatCoalescedAnnouncementMessage(records); - expect(msg).toContain("combined findings"); + expect(msg).toContain("MUST include findings from every task item above"); expect(msg).toContain("NO_REPLY"); }); + + it("includes raw findings for every task in coalesced payload", () => { + const records = [ + makeRecord({ runId: "run-1", label: "南京天气", findings: "南京:晴,12°C" }), + makeRecord({ runId: "run-2", label: "上海天气", findings: "上海:多云,9°C" }), + ]; + + const msg = formatCoalescedAnnouncementMessage(records); + + expect(msg).toContain("Raw findings from each task (MUST cover all items):"); + expect(msg).toContain("[1] 南京天气:"); + expect(msg).toContain("南京:晴,12°C"); + expect(msg).toContain("[2] 上海天气:"); + expect(msg).toContain("上海:多云,9°C"); + expect(msg).toContain("MUST include findings from every task item above"); + }); }); diff --git a/src/agent/subagent/announce.ts b/src/agent/subagent/announce.ts index 7afeb707..5f9b5438 100644 --- a/src/agent/subagent/announce.ts +++ b/src/agent/subagent/announce.ts @@ -213,7 +213,8 @@ export function formatCoalescedAnnouncementMessage( }); } - // Multiple records: build combined message + // Multiple records: build combined message. + // Include a strict raw-findings section so parent can reliably cover every task result. const parts: string[] = [ `All ${records.length} background tasks have completed. Here are the combined results:`, "", @@ -249,11 +250,22 @@ export function formatCoalescedAnnouncementMessage( const failCount = records.length - okCount; parts.push(`Results: ${okCount} succeeded, ${failCount} failed/timed out`); + parts.push("", "Raw findings from each task (MUST cover all items):", ""); + for (let i = 0; i < records.length; i++) { + const r = records[i]!; + const displayName = r.label || r.task.slice(0, 60); + parts.push( + `[${i + 1}] ${displayName}:`, + r.findings || "(no output)", + "", + ); + } + parts.push( "", "Summarize these results naturally for the user.", - "Present the combined findings as a coherent summary, not a list of separate reports.", - "Keep it concise but cover the key findings from each task.", + "You MUST include findings from every task item above, without omission.", + "Keep it concise, but preserve concrete findings from each task.", "Do not mention technical details like session IDs or that these were background tasks.", "You can respond with NO_REPLY if no announcement is needed.", );