From 40b175a69571e6dc5002735880c96a46d3a6f28f Mon Sep 17 00:00:00 2001 From: zidongdesign Date: Sat, 7 Mar 2026 19:34:14 +0800 Subject: [PATCH] fix: send compaction completion notice via onBlockReply in streaming mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In block-streaming mode, the reply pipeline bypasses buildReplyPayloads, so notices only pushed to verboseNotices were never delivered to the user. The start notice ("🧹 Compacting context...") was already sent via opts.onBlockReply directly in agent-runner-execution.ts; mirror the same path for the completion notice. - If opts.onBlockReply is present (streaming mode): await onBlockReply with the completion text directly, so it reaches the user immediately. - Otherwise (non-streaming): push to verboseNotices as before so it gets prepended to the final payload batch. Also consolidate the verbose vs. non-verbose text selection into a single completionText variable, removing the redundant pop/push pattern. --- src/auto-reply/reply/agent-runner.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/auto-reply/reply/agent-runner.ts b/src/auto-reply/reply/agent-runner.ts index fba204eccad..e8874366201 100644 --- a/src/auto-reply/reply/agent-runner.ts +++ b/src/auto-reply/reply/agent-runner.ts @@ -702,12 +702,18 @@ export async function runReplyAgent(params: { // so the completion message closes the loop for every user regardless of // their verbose setting. const suffix = typeof count === "number" ? ` (count ${count})` : ""; - verboseNotices.push({ text: `✅ Context compacted${suffix}.` }); - if (verboseEnabled) { - // Verbose mode already gets the completion — keep the legacy notice - // text only for verbose so power users see the traditional wording. - verboseNotices.pop(); - verboseNotices.push({ text: `🧹 Auto-compaction complete${suffix}.` }); + const completionText = verboseEnabled + ? `🧹 Auto-compaction complete${suffix}.` + : `✅ Context compacted${suffix}.`; + + // In block-streaming mode, onBlockReply bypasses buildReplyPayloads, so + // we must deliver the completion notice the same way the start notice was + // sent (via onBlockReply directly). Otherwise the user sees the "🧹 + // Compacting context..." start notice but never receives the completion. + if (opts?.onBlockReply) { + await opts.onBlockReply({ text: completionText }); + } else { + verboseNotices.push({ text: completionText }); } } if (verboseNotices.length > 0) {