fix(auto-reply): suppress room-event fast progress dispatch

This commit is contained in:
Ayaan Zaidi
2026-07-01 22:21:10 -07:00
parent 5fc9b20d24
commit dbccddbf34
2 changed files with 48 additions and 3 deletions

View File

@@ -9904,6 +9904,44 @@ describe("sendPolicy deny — suppress delivery, not processing (#53328)", () =>
expect(dispatcher.sendFinalReply).not.toHaveBeenCalled();
});
it("suppresses fast auto progress for room-event message-tool-only turns", async () => {
setNoAbort();
sessionStoreMocks.currentEntry = {
sessionId: "s1",
updatedAt: 0,
sendPolicy: "allow",
};
const dispatcher = createDispatcher();
const replyResolver = vi.fn(async (_ctx: MsgContext, opts?: GetReplyOptions) => {
await opts?.onToolResult?.({
text: "💨Fast: auto-off(75s>=60s)",
channelData: { openclawProgressKind: "fast-mode-auto" },
});
return { text: "NO_REPLY" } satisfies ReplyPayload;
});
const ctx = buildTestCtx({
SessionKey: "test:session",
ChatType: "channel",
InboundEventKind: "room_event",
});
const result = await dispatchReplyFromConfig({
ctx,
cfg: emptyConfig,
dispatcher,
replyResolver,
replyOptions: {
sourceReplyDeliveryMode: "message_tool_only",
suppressDefaultToolProgressMessages: true,
},
});
expect(result.queuedFinal).toBe(false);
expect(result.sourceReplyDeliveryMode).toBe("message_tool_only");
expect(dispatcher.sendToolResult).not.toHaveBeenCalled();
expect(dispatcher.sendFinalReply).not.toHaveBeenCalled();
});
it("suppresses fast auto progress when sendPolicy is deny", async () => {
setNoAbort();
sessionStoreMocks.currentEntry = {

View File

@@ -2383,6 +2383,11 @@ export async function dispatchReplyFromConfig(
ctx.InboundEventKind !== "room_event" &&
!sendPolicyDenied &&
params.replyOptions?.forceToolResultProgress === true;
const shouldDeliverFastModeAutoProgressDespiteSourceSuppression = () =>
suppressAutomaticSourceDelivery &&
sourceReplyDeliveryMode === "message_tool_only" &&
ctx.InboundEventKind !== "room_event" &&
!sendPolicyDenied;
let finalReplyDeliveryStarted = false;
const hasExecApprovalPayload = (payload: ReplyPayload) => {
const execApproval =
@@ -3074,8 +3079,7 @@ export async function dispatchReplyFromConfig(
suppressTyping: typing.suppressTyping,
onPartialReply: wrapProgressCallback(params.replyOptions?.onPartialReply),
onReasoningStream: wrapProgressCallback(params.replyOptions?.onReasoningStream),
streamReasoningInNonStreamModes:
params.replyOptions?.streamReasoningInNonStreamModes,
streamReasoningInNonStreamModes: params.replyOptions?.streamReasoningInNonStreamModes,
onReasoningEnd: wrapProgressCallback(params.replyOptions?.onReasoningEnd),
onAssistantMessageStart: wrapProgressCallback(
params.replyOptions?.onAssistantMessageStart,
@@ -3140,6 +3144,9 @@ export async function dispatchReplyFromConfig(
return;
}
const isFastModeAutoProgress = isFastModeAutoProgressPayload(payload);
const isFastModeAutoProgressDelivery =
isFastModeAutoProgress &&
shouldDeliverFastModeAutoProgressDespiteSourceSuppression();
const isForcedToolProgress =
shouldDeliverForcedToolProgressDespiteSourceSuppression();
const progressCallbackForwarded = shouldForwardToolResultProgressCallback(
@@ -3164,7 +3171,7 @@ export async function dispatchReplyFromConfig(
}
if (
shouldSuppressProgressDelivery() &&
!isFastModeAutoProgress &&
!isFastModeAutoProgressDelivery &&
!isForcedToolProgress
) {
return;