From f422d3363d71c6f59294e74a05a56ae38c587df5 Mon Sep 17 00:00:00 2001 From: chenpitang Date: Sat, 7 Mar 2026 19:21:26 +0800 Subject: [PATCH] feat: notify user when context compaction starts and completes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During auto-compaction the agent goes silent for several seconds while the context is summarised. Users on every channel (Discord, Feishu, Telegram, webchat …) had no indication that something was happening — leading to confusion and duplicate messages. Changes: - agent-runner-execution.ts: listen for compaction phase='start' event and immediately deliver a "🧹 Compacting context..." notice via the existing onBlockReply callback. This fires for every channel because onBlockReply is the universal in-run delivery path. - agent-runner.ts: make the completion notice unconditional (was previously guarded behind verboseEnabled). Non-verbose users now see "✅ Context compacted (count N)."; verbose users continue to see the legacy "🧹 Auto-compaction complete (count N)." wording. Why onBlockReply for start? onBlockReply is already wired to every channel adapter and fires during the live run, so the notice arrives in-band with zero new plumbing. Using verboseNotices (appended after the run) would be too late and would miss the start signal entirely. Fixes: users seeing silent pauses of 5-15 s with no feedback during compaction on any channel. --- src/auto-reply/reply/agent-runner-execution.ts | 10 ++++++++-- src/auto-reply/reply/agent-runner.ts | 10 +++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/auto-reply/reply/agent-runner-execution.ts b/src/auto-reply/reply/agent-runner-execution.ts index c25342e4a28..e88c227d0a1 100644 --- a/src/auto-reply/reply/agent-runner-execution.ts +++ b/src/auto-reply/reply/agent-runner-execution.ts @@ -394,11 +394,17 @@ export async function runAgentTurnWithFallback(params: { await params.opts?.onToolStart?.({ name, phase }); } } - // Track auto-compaction completion and notify UI layer. + // Track auto-compaction and notify higher layers. if (evt.stream === "compaction") { const phase = typeof evt.data.phase === "string" ? evt.data.phase : ""; if (phase === "start") { - await params.opts?.onCompactionStart?.(); + if (params.opts?.onCompactionStart) { + await params.opts.onCompactionStart(); + } else { + // Use the universal in-run block reply path so every + // channel sees a notice while compaction is pausing the run. + await params.opts?.onBlockReply?.({ text: "🧹 Compacting context..." }); + } } const completed = evt.data?.completed === true; if (phase === "end" && completed) { diff --git a/src/auto-reply/reply/agent-runner.ts b/src/auto-reply/reply/agent-runner.ts index fbdad1be160..fba204eccad 100644 --- a/src/auto-reply/reply/agent-runner.ts +++ b/src/auto-reply/reply/agent-runner.ts @@ -697,8 +697,16 @@ export async function runReplyAgent(params: { }); } + // Always notify the user when compaction completes — not just in verbose + // mode. The "🧹 Compacting context..." notice was already sent at start, + // 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) { - const suffix = typeof count === "number" ? ` (count ${count})` : ""; + // 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}.` }); } }