fix: send compaction completion notice via onBlockReply in streaming mode

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.
This commit is contained in:
zidongdesign 2026-03-07 19:34:14 +08:00 committed by Josh Lehman
parent f422d3363d
commit 40b175a695
No known key found for this signature in database
GPG Key ID: D141B425AC7F876B

View File

@ -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) {