From 5f4e34dc2344f212121d85d5d5f23565ee897cd1 Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Sat, 31 Jan 2026 16:07:33 -0800 Subject: [PATCH] feat(slack): add web search to Slack bot agent via Claude built-in tool Use Claude's built-in web_search_20250305 server tool to give the Slack bot web search capability. The API handles search execution server-side, so no external API keys or dependencies are needed. Also handle the pause_turn stop reason for long-running server-side tool execution. --- .../slack/events/utils/run-agent/run-agent.ts | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/apps/api/src/app/api/integrations/slack/events/utils/run-agent/run-agent.ts b/apps/api/src/app/api/integrations/slack/events/utils/run-agent/run-agent.ts index 8ff1cd7fe4f..c0ad3d552b3 100644 --- a/apps/api/src/app/api/integrations/slack/events/utils/run-agent/run-agent.ts +++ b/apps/api/src/app/api/integrations/slack/events/utils/run-agent/run-agent.ts @@ -206,6 +206,7 @@ const SYSTEM_PROMPT = `You are a helpful assistant in Slack for Superset, a task You can: - Create, update, search, and manage tasks using superset_* tools - Read recent channel messages using slack_get_channel_history +- Search the web for current information using web_search - Help users understand conversations and create actionable items from discussions Guidelines: @@ -213,6 +214,8 @@ Guidelines: - When creating tasks, extract key details from the conversation - Use Slack formatting: *bold*, _italic_, \`code\`, > quotes - If an action fails, explain what went wrong and suggest alternatives +- When answering questions that need up-to-date info, use web_search to find current information +- Cite sources when sharing information from web search results Context gathering: - Thread context is automatically included if the mention is in a thread @@ -262,9 +265,14 @@ export async function runSlackAgent( .map((t) => mcpToolToAnthropicTool(t, "superset")) .filter((t) => !DENIED_SUPERSET_TOOLS.has(t.name)); - const tools: Anthropic.Tool[] = [ + const tools: Anthropic.Messages.ToolUnion[] = [ ...supersetTools, SLACK_GET_CHANNEL_HISTORY_TOOL, + { + type: "web_search_20250305" as const, + name: "web_search" as const, + max_uses: 3, + }, ]; const contextualSystem = `${SYSTEM_PROMPT} @@ -297,10 +305,26 @@ Current context: let iterations = 0; while ( - response.stop_reason === "tool_use" && + (response.stop_reason === "tool_use" || + response.stop_reason === "pause_turn") && iterations < MAX_TOOL_ITERATIONS ) { iterations++; + + // pause_turn: server-side tool (web search) paused a long-running turn + if (response.stop_reason === "pause_turn") { + messages.push({ role: "assistant", content: response.content }); + response = await anthropic.messages.create({ + model: "claude-sonnet-4-5", + max_tokens: 2048, + system: contextualSystem, + tools, + messages, + }); + continue; + } + + // tool_use: handle client-side tools (MCP + slack_get_channel_history) const toolUseBlocks = response.content.filter( (b): b is Anthropic.ToolUseBlock => b.type === "tool_use", );