From 85b6f91bd75a30cb02a9a677577cfb05468200d2 Mon Sep 17 00:00:00 2001 From: Peter Lindsey Date: Thu, 28 May 2026 19:15:26 +0800 Subject: [PATCH] fix(dispatch): forward channel-owned progress callbacks in all chat types when verbose is off Remove the chatType === 'direct' guard from shouldAllowQuietChannelOwnedProgressCallbacks so that channel-owned native progress callbacks (onToolStart, onItemEvent, onPlanUpdate, onApprovalEvent, onCommandOutput, onPatchSummary, onCompactionStart/End) are forwarded in group and group-channel sessions when verbose is off. Previously the guard required chatType === 'direct', which meant that /verbose off would suppress all progress callbacks in group sessions while direct sessions continued to relay them. Message-level tool summary suppression is handled separately; native channel relay hooks should not be gated on chat type. Closes #87612 --- .../reply/dispatch-from-config.test.ts | 30 +++++++++++++------ src/auto-reply/reply/dispatch-from-config.ts | 7 ++--- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/auto-reply/reply/dispatch-from-config.test.ts b/src/auto-reply/reply/dispatch-from-config.test.ts index 63fe6230b19..d881acbd5b6 100644 --- a/src/auto-reply/reply/dispatch-from-config.test.ts +++ b/src/auto-reply/reply/dispatch-from-config.test.ts @@ -1941,7 +1941,7 @@ describe("dispatchReplyFromConfig", () => { expect(dispatcher.sendFinalReply).toHaveBeenCalledTimes(1); }); - it("suppresses channel-owned group progress callbacks while verbose is off", async () => { + it("forwards channel-owned group progress callbacks while verbose is off", async () => { setNoAbort(); sessionStoreMocks.currentEntry = { verboseLevel: "off", @@ -2001,14 +2001,26 @@ describe("dispatchReplyFromConfig", () => { }, }); - expect(onToolStart).not.toHaveBeenCalled(); - expect(onItemEvent).not.toHaveBeenCalled(); - expect(onPlanUpdate).not.toHaveBeenCalled(); - expect(onApprovalEvent).not.toHaveBeenCalled(); - expect(onCommandOutput).not.toHaveBeenCalled(); - expect(onPatchSummary).not.toHaveBeenCalled(); - expect(onCompactionStart).not.toHaveBeenCalled(); - expect(onCompactionEnd).not.toHaveBeenCalled(); + expect(onToolStart).toHaveBeenCalledWith({ name: "exec", phase: "start" }); + expect(onItemEvent).toHaveBeenCalledWith({ + itemId: "1", + kind: "tool", + progressText: "running exec", + }); + expect(onPlanUpdate).toHaveBeenCalledWith({ phase: "update", steps: ["Run command"] }); + expect(onApprovalEvent).toHaveBeenCalledWith({ + phase: "requested", + command: "pnpm test", + }); + expect(onCommandOutput).toHaveBeenCalledWith({ + phase: "end", + name: "exec", + status: "ok", + exitCode: 0, + }); + expect(onPatchSummary).toHaveBeenCalledWith({ phase: "end", summary: "1 modified" }); + expect(onCompactionStart).toHaveBeenCalledTimes(1); + expect(onCompactionEnd).toHaveBeenCalledTimes(1); expect(onToolResult).not.toHaveBeenCalled(); expect(dispatcher.sendToolResult).not.toHaveBeenCalled(); expect(dispatcher.sendFinalReply).toHaveBeenCalledTimes(1); diff --git a/src/auto-reply/reply/dispatch-from-config.ts b/src/auto-reply/reply/dispatch-from-config.ts index 8b6a360fc3b..89b1026edb9 100644 --- a/src/auto-reply/reply/dispatch-from-config.ts +++ b/src/auto-reply/reply/dispatch-from-config.ts @@ -2265,12 +2265,11 @@ export async function dispatchReplyFromConfig( const onPatchSummaryFromReplyOptions = params.replyOptions?.onPatchSummary; const allowSuppressedSourceProgressCallbacks = params.replyOptions?.allowProgressCallbacksWhenSourceDeliverySuppressed === true; - const shouldAllowQuietDirectNativeProgressCallbacks = (options?: { + const shouldAllowQuietChannelOwnedProgressCallbacks = (options?: { requiresToolSummaryVisibility?: boolean; }) => options?.requiresToolSummaryVisibility === true && - params.replyOptions?.suppressDefaultToolProgressMessages === true && - chatType === "direct"; + params.replyOptions?.suppressDefaultToolProgressMessages === true; let hasPendingDirectBlockReplyDelivery = false; const waitForPendingDirectBlockReplyDelivery = async (abortSignal?: AbortSignal) => { if (!hasPendingDirectBlockReplyDelivery) { @@ -2289,7 +2288,7 @@ export async function dispatchReplyFromConfig( if ( options?.requiresToolSummaryVisibility === true && !shouldSendToolSummaries() && - !shouldAllowQuietDirectNativeProgressCallbacks(options) + !shouldAllowQuietChannelOwnedProgressCallbacks(options) ) { return false; }