diff --git a/extensions/discord/src/actions/handle-action.test.ts b/extensions/discord/src/actions/handle-action.test.ts index b6c2620e97c..1798be6bcbe 100644 --- a/extensions/discord/src/actions/handle-action.test.ts +++ b/extensions/discord/src/actions/handle-action.test.ts @@ -216,6 +216,36 @@ describe("handleDiscordMessageAction", () => { expect(handleDiscordActionMock).not.toHaveBeenCalled(); }); + it("forwards top-level components on sends", async () => { + const components = { blocks: [{ type: "text", text: "Pick one" }] }; + + await handleDiscordMessageAction({ + action: "send", + params: { + message: "hello", + components, + }, + cfg: { + channels: { discord: { token: "tok" } }, + } as OpenClawConfig, + toolContext: { + currentChannelProvider: "discord", + currentChannelId: "channel:123", + }, + }); + + expect(handleDiscordActionMock).toHaveBeenCalledWith( + expect.objectContaining({ + action: "sendMessage", + to: "channel:123", + content: "hello", + components, + }), + expect.any(Object), + expect.any(Object), + ); + }); + it("does not use another provider's current target for Discord sends", async () => { await expect( handleDiscordMessageAction({ diff --git a/extensions/discord/src/actions/handle-action.ts b/extensions/discord/src/actions/handle-action.ts index dda640aa26e..5d9c24db91a 100644 --- a/extensions/discord/src/actions/handle-action.ts +++ b/extensions/discord/src/actions/handle-action.ts @@ -81,6 +81,7 @@ export async function handleDiscordMessageAction( const to = readSendTarget(); const asVoice = readBooleanParam(params, "asVoice") === true; const rawComponents = + params.components ?? buildDiscordPresentationComponents(normalizeMessagePresentation(params.presentation)) ?? buildDiscordInteractiveComponents(normalizeInteractiveReply(params.interactive)); const hasComponents =