From 68912111cfeafa72b7c62eb6f2ebb82fa5e10a3b Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 29 Apr 2026 19:15:49 +0100 Subject: [PATCH] fix(slack): avoid generic inline button prompt hint --- CHANGELOG.md | 1 + src/agents/system-prompt.test.ts | 20 ++++++++++++++++++++ src/agents/system-prompt.ts | 13 ++++++++----- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15aa0bb6590..36d4a793818 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/prompts: rely on Slack `interactiveReplies` guidance instead of generic `inlineButtons` config hints so enabled Slack button directives are not contradicted. Fixes #46647. Thanks @jeremykoerber. - Slack/reactions: treat duplicate `already_reacted` responses as idempotent success so repeated agent reaction adds no longer surface as tool failures. Fixes #69005. Thanks @shipitsteven and @martingarramon. - 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. diff --git a/src/agents/system-prompt.test.ts b/src/agents/system-prompt.test.ts index 9b4e978279e..cb252c88f94 100644 --- a/src/agents/system-prompt.test.ts +++ b/src/agents/system-prompt.test.ts @@ -759,6 +759,26 @@ describe("buildAgentSystemPrompt", () => { expect(prompt).toContain("`style` can be `primary`, `success`, or `danger`"); }); + it("uses Slack interactive reply hints instead of generic inline button config guidance", () => { + const prompt = buildAgentSystemPrompt({ + workspaceDir: "/tmp/openclaw", + toolNames: ["message"], + runtimeInfo: { + channel: "slack", + }, + messageToolHints: [ + "- Prefer Slack buttons/selects for 2-5 discrete choices or parameter picks instead of asking the user to type one.", + "- Slack interactive replies: use `[[slack_buttons: Label:value, Other:other]]` to add action buttons that route clicks back as Slack interaction system events.", + ], + }); + + expect(prompt).toContain("Slack interactive replies"); + expect(prompt).toContain("[[slack_buttons: Label:value, Other:other]]"); + expect(prompt).not.toContain("Inline buttons not enabled for slack"); + expect(prompt).not.toContain("slack.capabilities.inlineButtons"); + expect(prompt).not.toContain("buttons=[[{text,callback_data,style?}]]"); + }); + it("describes message-tool-only source delivery without requiring target", () => { const prompt = buildAgentSystemPrompt({ workspaceDir: "/tmp/openclaw", diff --git a/src/agents/system-prompt.ts b/src/agents/system-prompt.ts index d393ec340e9..6305385fd48 100644 --- a/src/agents/system-prompt.ts +++ b/src/agents/system-prompt.ts @@ -346,6 +346,7 @@ function buildMessagingSection(params: { return []; } const messageToolOnly = params.sourceReplyDeliveryMode === "message_tool_only"; + const showGenericInlineButtonHint = params.runtimeChannel !== "slack"; const hasSessionsSpawn = params.availableTools.has("sessions_spawn"); const hasSubagents = params.availableTools.has("subagents"); const subagentOrchestrationGuidance = hasSessionsSpawn @@ -376,11 +377,13 @@ function buildMessagingSection(params: { messageToolOnly ? "- If you use `message` (`action=send`) to deliver visible output, do not repeat that visible content in your final answer; final answers are private in this mode." : `- If you use \`message\` (\`action=send\`) to deliver your user-visible reply, respond with ONLY: ${SILENT_REPLY_TOKEN} (avoid duplicate replies).`, - params.inlineButtonsEnabled - ? "- Inline buttons supported. Use `action=send` with `buttons=[[{text,callback_data,style?}]]`; `style` can be `primary`, `success`, or `danger`." - : params.runtimeChannel - ? `- Inline buttons not enabled for ${params.runtimeChannel}. If you need them, ask to set ${params.runtimeChannel}.capabilities.inlineButtons ("dm"|"group"|"all"|"allowlist").` - : "", + showGenericInlineButtonHint + ? params.inlineButtonsEnabled + ? "- Inline buttons supported. Use `action=send` with `buttons=[[{text,callback_data,style?}]]`; `style` can be `primary`, `success`, or `danger`." + : params.runtimeChannel + ? `- Inline buttons not enabled for ${params.runtimeChannel}. If you need them, ask to set ${params.runtimeChannel}.capabilities.inlineButtons ("dm"|"group"|"all"|"allowlist").` + : "" + : "", ...(params.messageToolHints ?? []), ] .filter(Boolean)