diff --git a/CHANGELOG.md b/CHANGELOG.md index dbc4189c045..39371b40f34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ Docs: https://docs.openclaw.ai - MCP/OpenAI: normalize parameter-free tool schemas whose top-level object `properties` is missing, null, or invalid before sending tools to OpenAI, so MCP tools without params stay usable. Fixes #75362. Thanks @tolkonepiu and @SymbolStar. - TTS: honor explicit short `[[tts:text]]...[[/tts:text]]` blocks while keeping untagged short auto-TTS suppressed, so tagged voice replies are synthesized instead of being dropped as empty voice-only payloads. Fixes #73758. Thanks @yfge. - Proxy/audio: convert standard `FormData` bodies before proxy-backed undici fetches, so audio transcription and multipart uploads no longer send `[object FormData]` when `HTTP_PROXY` or `HTTPS_PROXY` is configured. Fixes #48554. Thanks @dco5. +- Discord: allow explicitly configured ack reactions in tool-only guild channels while keeping automatic lifecycle/status reactions suppressed. Fixes #74922. Thanks @samvilian and @BlueBirdBack. - Gateway/diagnostics: include a bounded redacted startup error message in stability bundles, so crash-loop reports identify the failing plugin or contract without exposing secrets. Refs #75797. Thanks @ymebosma. - Gateway/pricing: abort in-flight model pricing catalog fetches when Gateway shutdown stops the refresh loop, and avoid post-stop cache writes or refresh timers. Fixes #72208. Thanks @rzcq. - Codex/app-server: make startup retry cleanup ownership-aware so concurrent Codex lanes cannot close another lane's freshly restarted shared app-server client. Thanks @vincentkoc. diff --git a/extensions/discord/src/monitor/message-handler.process.test.ts b/extensions/discord/src/monitor/message-handler.process.test.ts index 1964f2922c3..8622c4be862 100644 --- a/extensions/discord/src/monitor/message-handler.process.test.ts +++ b/extensions/discord/src/monitor/message-handler.process.test.ts @@ -900,7 +900,7 @@ describe("processDiscordMessage session routing", () => { expect(createDiscordDraftStream).not.toHaveBeenCalled(); }); - it("suppresses automatic status reactions for always-on guild replies", async () => { + it("sends the configured ack while suppressing automatic status reactions for always-on guild replies", async () => { const ctx = await createBaseContext({ shouldRequireMention: false, effectiveWasMentioned: false, @@ -921,7 +921,7 @@ describe("processDiscordMessage session routing", () => { await runProcessDiscordMessage(ctx); expect(getLastDispatchReplyOptions()?.sourceReplyDeliveryMode).toBe("message_tool_only"); - expect(sendMocks.reactMessageDiscord).not.toHaveBeenCalled(); + expect(getReactionEmojis()).toEqual(["👀"]); expect(sendMocks.removeReactionDiscord).not.toHaveBeenCalled(); }); diff --git a/extensions/discord/src/monitor/message-handler.process.ts b/extensions/discord/src/monitor/message-handler.process.ts index 9c660b50481..6271b38ecd1 100644 --- a/extensions/discord/src/monitor/message-handler.process.ts +++ b/extensions/discord/src/monitor/message-handler.process.ts @@ -176,9 +176,11 @@ export async function processDiscordMessage( shouldBypassMention, }), ); - const shouldSendAckReaction = !sourceRepliesAreToolOnly && shouldAckReaction(); + const shouldSendAckReaction = shouldAckReaction(); const statusReactionsEnabled = - shouldSendAckReaction && cfg.messages?.statusReactions?.enabled !== false; + !sourceRepliesAreToolOnly && + shouldSendAckReaction && + cfg.messages?.statusReactions?.enabled !== false; const feedbackRest = createDiscordRestClient({ cfg, token,