fix(slack): suppress room event typing indicators (#105813)

* fix(slack): suppress room event typing indicators

* fix(slack): suppress room event typing indicators
This commit is contained in:
Peter Steinberger
2026-07-12 18:41:49 -07:00
committed by GitHub
parent 8091292e3e
commit cba79b4aaa
2 changed files with 38 additions and 1 deletions
@@ -47,6 +47,8 @@ let mockedPinnedMainDmOwner: string | undefined;
let capturedReplyOptions:
| {
disableBlockStreaming?: boolean;
sourceReplyDeliveryMode?: "automatic" | "message_tool_only";
suppressTyping?: boolean;
suppressDefaultToolProgressMessages?: boolean;
commentaryProgressEnabled?: boolean;
onVerboseProgressVisibility?: (isActive: () => boolean) => void;
@@ -516,12 +518,15 @@ vi.mock("openclaw/plugin-sdk/channel-outbound", async (importOriginal) => {
},
resolveChannelMessageSourceReplyDeliveryMode: (params: {
cfg?: { messages?: { groupChat?: { visibleReplies?: string } } };
ctx?: { ChatType?: string };
ctx?: { ChatType?: string; InboundEventKind?: string };
requested?: "automatic" | "message_tool_only";
}) => {
if (params.requested) {
return params.requested;
}
if (params.ctx?.InboundEventKind === "room_event") {
return "message_tool_only";
}
const chatType = params.ctx?.ChatType;
if (chatType === "group" || chatType === "channel") {
return params.cfg?.messages?.groupChat?.visibleReplies === "automatic"
@@ -978,6 +983,8 @@ vi.mock("../reply.runtime.js", () => ({
};
replyOptions?: {
disableBlockStreaming?: boolean;
sourceReplyDeliveryMode?: "automatic" | "message_tool_only";
suppressTyping?: boolean;
suppressDefaultToolProgressMessages?: boolean;
onItemEvent?: (payload: {
kind?: string;
@@ -1130,6 +1137,8 @@ vi.mock("../reply.runtime.js", () => ({
dispatchInboundMessage: async (params: {
replyOptions?: {
disableBlockStreaming?: boolean;
sourceReplyDeliveryMode?: "automatic" | "message_tool_only";
suppressTyping?: boolean;
suppressDefaultToolProgressMessages?: boolean;
onAssistantMessageStart?: () => Promise<void> | void;
onReasoningEnd?: () => Promise<void> | void;
@@ -2087,6 +2096,30 @@ describe("dispatchPreparedSlackMessage preview fallback", () => {
expect(statusReactionControllerMock.setDone).not.toHaveBeenCalled();
});
it("suppresses Slack typing for ambient room events", async () => {
await dispatchPreparedSlackMessage(
createPreparedSlackMessage({
cfg: { messages: { groupChat: { visibleReplies: "automatic" } } },
ctxPayload: { ChatType: "channel", InboundEventKind: "room_event" },
}),
);
expect(capturedReplyOptions?.sourceReplyDeliveryMode).toBe("message_tool_only");
expect(capturedReplyOptions?.suppressTyping).toBe(true);
});
it("leaves Slack typing unsuppressed for normal channel turns", async () => {
await dispatchPreparedSlackMessage(
createPreparedSlackMessage({
cfg: { messages: { groupChat: { visibleReplies: "automatic" } } },
ctxPayload: { ChatType: "channel" },
}),
);
expect(capturedReplyOptions?.sourceReplyDeliveryMode).toBe("automatic");
expect(capturedReplyOptions?.suppressTyping).toBeUndefined();
});
it("escapes Slack mrkdwn in tool progress preview labels", async () => {
const draftStream = createDraftStreamStub();
createSlackDraftStreamMock.mockReturnValueOnce(draftStream);
@@ -503,6 +503,7 @@ export async function dispatchPreparedSlackMessage(prepared: PreparedSlackMessag
ctx: prepared.ctxPayload,
});
const sourceRepliesAreToolOnly = sourceReplyDeliveryMode === "message_tool_only";
const suppressRoomEventTyping = prepared.ctxPayload.InboundEventKind === "room_event";
// Shared context for the `message_sent` plugin hook emitted on each delivered
// reply (both the `deliverReplies` paths and the native-streaming finalizer).
@@ -1904,6 +1905,9 @@ export async function dispatchPreparedSlackMessage(prepared: PreparedSlackMessag
replyOptions: {
skillFilter: prepared.channelConfig?.skills,
sourceReplyDeliveryMode,
// Room events are observe-style turns; Slack status indicators imply an
// automatic visible reply and can auto-open assistant threads.
suppressTyping: suppressRoomEventTyping ? true : undefined,
hasRepliedRef,
disableBlockStreaming,
onModelSelected,