diff --git a/CHANGELOG.md b/CHANGELOG.md index e7b6a078a9b..d8f15ff26a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ Docs: https://docs.openclaw.ai ### Fixes - Models/UI: hide unauthenticated providers from the default Web chat, `/models`, and model setup pickers while keeping explicit full-catalog browse paths through `view: "all"`, `/models all`, and `models list --all`. Fixes #74423. Thanks @guarismo and @SymbolStar. +- Slack/tools: expose `fileId` in the shared message tool schema so `download-file` can receive Slack attachment IDs from inbound placeholders. Fixes #45574. Thanks @chadvegas. - Exec: reject invalid per-call `host` values instead of silently falling back to the default target, so hostname-like values fail before commands run. Fixes #74426. Thanks @scr00ge-00 and @vyctorbrzezowski. - Google/Gemini: send non-empty placeholder content when a Gemini run is triggered with empty or filtered user content, avoiding `contents is not specified` API errors. Thanks @CaoYuhaoCarl. - Heartbeat: preserve non-task `HEARTBEAT.md` context around `tasks:` blocks and apply `agents.defaults.heartbeat` to all agents unless per-agent heartbeat entries restrict scope. Thanks @Sekhar03. diff --git a/src/agents/tools/message-tool.test.ts b/src/agents/tools/message-tool.test.ts index 31eee4a1386..80bae379c46 100644 --- a/src/agents/tools/message-tool.test.ts +++ b/src/agents/tools/message-tool.test.ts @@ -699,6 +699,29 @@ describe("message tool schema scoping", () => { expect.arrayContaining(["send", "broadcast"]), ); }); + + it("advertises Slack download-file fileId in scoped schemas", () => { + const slackFilePlugin = createChannelPlugin({ + id: "slack", + label: "Slack", + docsPath: "/channels/slack", + blurb: "Slack test plugin.", + actions: ["download-file"], + }); + + setActivePluginRegistry( + createTestRegistry([{ pluginId: "slack", source: "test", plugin: slackFilePlugin }]), + ); + + const tool = createMessageTool({ + config: {} as never, + currentChannelProvider: "slack", + }); + const properties = getToolProperties(tool); + + expect(getActionEnum(properties)).toContain("download-file"); + expect(properties.fileId).toMatchObject({ type: "string" }); + }); }); describe("message tool description", () => { diff --git a/src/agents/tools/message-tool.ts b/src/agents/tools/message-tool.ts index 77f507aac67..f1e90691ebc 100644 --- a/src/agents/tools/message-tool.ts +++ b/src/agents/tools/message-tool.ts @@ -281,6 +281,7 @@ function buildChannelTargetSchema() { function buildStickerSchema() { return { + fileId: Type.Optional(Type.String()), emojiName: Type.Optional(Type.String()), stickerId: Type.Optional(Type.Array(Type.String())), stickerName: Type.Optional(Type.String()),