CopilotKitDocs
  • Docs
  • Reference
  • Cookbook
Get Intelligence free
CopilotKitDocs
DocsReferenceCookbook
DocsReferenceCookbook

@copilotkit/bot

@copilotkit/bot-slack

slackrenderBlockKitmarkdownToMrkdwndefaultSlackToolsdefaultSlackContextSanitizingHttpAgent
ReferencebotSlack

slack

The Slack platform adapter factory — Socket Mode ingress via Bolt, Block Kit egress, chat.update streaming, and ack-first opaque-id interactions.


Overview

slack(opts) returns a SlackAdapter — the Slack implementation of the engine's PlatformAdapter boundary. It handles ingress via Bolt (Socket Mode by default), renders the JSX vocabulary to Block Kit within Slack's per-element budgets, streams agent replies via throttled chat.update, and decodes interactions to opaque action ids. @copilotkit/bot-slack is the only package in the stack that talks to Slack.

For app creation, tokens, and first run, see the Slack quickstart.

Signature

import { slack } from "@copilotkit/bot-slack";

function slack(opts: SlackAdapterOptions): SlackAdapter;

Parameters

Prop

Type

Return Value

A SlackAdapter to pass into createBot({ adapters }). It advertises platform: "slack", ackDeadlineMs: 3000, and:

capabilities: {
  supportsStreaming: true,
  supportsModals: false,
  supportsTyping: false,
  supportsReactions: false,
  maxBlocksPerMessage: 50,
}

The capability-gated Thread methods are all backed: getMessages() via conversations.replies, lookupUser(query) via directory search, and postFile(...) via files.uploadV2. Inbound file uploads are downloaded and delivered to the agent as multimodal content parts.

Usage

import { createBot } from "@copilotkit/bot";
import { slack, defaultSlackTools, defaultSlackContext } from "@copilotkit/bot-slack";

const bot = createBot({
  adapters: [
    slack({
      botToken: process.env.SLACK_BOT_TOKEN!, // xoxb-…
      appToken: process.env.SLACK_APP_TOKEN!, // xapp-… (Socket Mode)
    }),
  ],
  agent: (threadId) => makeAgent(threadId),
  tools: [...defaultSlackTools, ...appTools],
  context: [...defaultSlackContext, ...appContext],
});

Behavior

Ingress

The Slack listener pre-filters events to the turns the bot should answer — @-mentions, replies in threads it owns, and DMs — so a single onMention handler usually covers everything. Conversation history is rebuilt from Slack (conversations.replies / conversations.history) on every turn: Slack is the source of truth, so bot restarts don't lose conversations.

Streaming

thread.runAgent() and thread.stream(...) post a placeholder and edit it in place as text arrives: chat.update calls are queued per message with a minimum gap between flushes (default 800ms); long replies roll over into follow-up messages at a soft 3500-character limit (under Slack's ~4000), breaking at the last newline or space and keeping fenced code blocks whole; dangling markdown (an unclosed fence or bold span) is auto-closed on each flush so the in-flight message always renders. Text is translated per chunk by markdownToMrkdwn.

Interactions (ack-first)

Every block_actions click is acked within Slack's 3-second deadline (ackDeadlineMs: 3000), then handled asynchronously. decodeInteraction extracts the opaque minted id (ck:…), the control's value, and the message ref — those are the only things that ride in the Slack payload; handler code, other props, and bind() args stay server-side. Unrelated clicks decode to events the bot harmlessly ignores; clicks on actions lost to a restart (with the default in-memory ActionStore) are acked but ignored.

Initialization

The underlying Bolt App is constructed with deferInitialization — construction is side-effect-free, and bot.start() owns initialization (Bolt init(), then an awaited auth.test to resolve the bot's own user id), so auth and config errors surface to the caller instead of firing in the background.

What's NOT in v1

  • Modals / true batched form submit
  • OAuth / multi-workspace install (single bot token only)
  • Durable (Redis/DB) ActionStore — in-memory only; actions expire on restart
  • Proactive posting (the bot replies only to turns it's part of)
  • Reactions

Related

  • renderBlockKit — the JSX → Block Kit mapping and per-element budgets
  • markdownToMrkdwn — the Markdown → mrkdwn translation
  • defaultSlackTools / defaultSlackContext — the shipped built-ins
  • SanitizingHttpAgent — connecting to a remote AG-UI backend
  • Slack quickstart — app manifest, tokens, first run
10d3939