@ copilotkit/ channels- slack (英语)
这个 偷懒 PlatformAdapter 页:1 @copilotkit/channels它连接一个
任何AG-UI代理的黑工作空间:通过Bolt(Socket Mode)入侵,作为Egress
Block Kit 调制自 @copilotkit/channels-ui JSX词汇,加上文本
流出,不透明-id相互作用,以及HITL.
你曾经将你的UI写成JSX(@copilotkit/channels-ui和驱动机器人与
@copilotkit/channels这个包裹是唯一能和斯莱克说话的.
适配器保存自己的Slack证书(botToken 编号 : appToken()——在
控制路径 频道运行在 copilotKit 智能配置
CopilotRuntime (免费计划可用),它开始并拥有频道的
生命周期。 在SDK原始版上建造和操作自己的频道跑道
也是一条支持路径.
管理频道: 持有自己证书的替代办法
这个适配器是 自动托管 路径:您的进程持有 Slack 证书,运行 Slack 入侵,并直接与 Slack 交谈.
管理情报频道 是另一个选择。 Intelligence拥有提供者边缘——签名的入侵,入侵,和加密的证书存储——所以你的程序没有Slack证书,也没有暴露公开的Slack端点. 您也可以从浏览器向导或CLI获得耐用线条、带每个频道健康和记录的频道仪表板以及引导提供者的设置:
npx copilotkit channels add support
您的机器人代码在其他方面是完全相同的——代理,工具,上下文,命令,和转弯处理器不会改变. 只有运输才有 见 examples/slack/app/managed.ts 同一瓶装双向电线 副驾驶通道 用于运行时接线的技巧.
这个自备适配器仍然得到充分的支持. 如果您想要在自己的基础设施内连接供应商, 请选择它 .
安装
pnpm add @copilotkit/channels-slack @copilotkit/channels @copilotkit/channels-ui
快速启动
import { createChannel } from "@copilotkit/channels";
import {
slack,
defaultSlackTools,
defaultSlackContext,
} from "@copilotkit/channels-slack";
import { CopilotRuntime, CopilotKitIntelligence } from "@copilotkit/runtime/v2";
import { createCopilotNodeListener } from "@copilotkit/runtime/v2/node";
const bot = createChannel({
name: "support-bot", // project-unique Intelligence Channel name
identifyUser: "platform", // provider + workspace + human Slack user
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], // lookup_slack_user + your tools
context: [...defaultSlackContext, ...appContext], // tagging/mrkdwn/thread guidance
});
bot.onMention(({ thread }) => thread.runAgent());
// The runtime owns the channel's lifecycle — there is no `bot.start()`.
const runtime = new CopilotRuntime({
intelligence: new CopilotKitIntelligence({
// apiUrl and wsUrl default to cloud-hosted CopilotKit Intelligence — override
// both together only for a self-hosted deployment.
apiKey: process.env.CPK_INTELLIGENCE_API_KEY!, // free tier available
}),
channels: [bot],
});
// Creating the listener starts the Channel's connection.
const listener = createCopilotNodeListener({ runtime });
// Optional: await that activation so a broken config fails startup loudly.
await listener.channels.ready(); // listener.channels.stop() tears it down
slack(opts) 返回 a SlackAdapter。默认情况下,它会运行于 套接字模式
(单位:千美元)socketMode: true)——仅出站WebSocket,不需要公共URL. HTTP 密码
模式 (socketMode: false需求 signingSecret (单位:千美元) port。Slack (英语)
听者预过滤器 侵入到转弯 机器人应该回答。 默认,
模式草案是对话性的,应用软件在内容中提及答复,在内容中则提及简单答复
频道/ 私人频道线程需要另外的应用程序提及.
必需的嵌入
| 瓦尔 | 脚本 | 目的 |
|---|---|---|
SLACK_BOT_TOKEN | xoxb- | 网络 API 的 Bot 令牌 . |
SLACK_APP_TOKEN | xapp- | Socket 模式的 App-level 令牌 . |
响应路线
使用 respondTo 选择Slack消息事件将变成什么 onMention 转弯 :
| 表面 | 默认行为 | 选项 |
|---|---|---|
直接信息 (message.im(中文(简体) ) | 响应 | respondTo.directMessages |
App提及(app_mention(中文(简体) ) | 已响应行中 | respondTo.appMentions 编号 : appMentions.reply |
| 普通渠道/私人渠道的答复 | 除非提及, 忽略 | respondTo.threadReplies: "afterBotReply" 遗产 |
| 助理窗格 | 单独默认的 API | assistant; 不为 respondTo |
| 斜线命令、反应、相互作用 | 明确的触发路径 | 不受控制 respondTo |
// Default routing made explicit.
slack({
botToken,
appToken,
respondTo: {
directMessages: true,
appMentions: { reply: "thread" },
threadReplies: "mentionsOnly",
},
});
// Legacy owned-thread continuation.
slack({
botToken,
appToken,
respondTo: {
threadReplies: "afterBotReply",
},
});
默认只提及线索行为,订阅到 app_mention 财务报告和审定财务报表
message.im 事件。 添加 message.channels 财务报告和审定财务报表 message.groups 只有当你
启用 respondTo.threadReplies: "afterBotReply" 想要Slack提供
纯通道/ 私有频道线索回复 .
它提供的东西
JSX — Block Kit 渲染
renderSlackMessage(ir) 编号 : renderBlockKit(ir) 翻译
@copilotkit/channels-ui block Kit 词汇表 : Message → blocks, (中文(简体) ),
Header → header, (中文(简体) ), Section → section (mrkdwn), (中文(简体) ), Markdown → markdownToMrkdwn, (中文(简体) ),
Field(s) → section.fields, (中文(简体) ), Context → context, (中文(简体) ), Actions → actions, (中文(简体) ),
Button → button (action_id = minted opaque id), (中文(简体) ), Select → static_select, (中文(简体) ),
Input → plain_text_input, (中文(简体) ), Image → image, (中文(简体) ), Divider → divider。 。 。 .
土著Slack JSX
使用 Slack.Block, (中文(简体) ), Slack.Element,以及 Slack.Object 当一个消息需要
Block Kit的功能,即便携式JSX集不曝光. 保留字段名称
斯莱克的JSON外壳。 事件道具变得不透明 action_id 值; 对象
value 道具由JSON编码后在交互上恢复.
import { Slack } from "@copilotkit/channels-slack";
await thread.post(
<Slack.Block.Section
text={<Slack.Object.MarkdownText text="*Deploy ready*" />}
accessory={
<Slack.Element.Button
key="approve"
text={<Slack.Object.PlainText text="Approve" />}
value={{ decision: "approve" }}
onClick={({ action }) => approve(action.value)}
/>
}
/>,
);
原生树拒绝错误的提供者节点, 缺少所需的字段, 无效
顶级元素 和超过Slack的50块限制的信息. Slack.Raw
接受已审查的块 Kit 对象,但不绑定回调。 直接黑
并管理Slack使用相同的序列器和倒回文本规则.
卡片按钮属于 actions的卡片属于 elements。 。 。 .
共享渲染器在直接交付或有管理的交付前先检查外形和
报告带有 JSON 指针的无效字段.
const approve = Slack.Element.Button({
text: <Slack.Object.PlainText text="Approve" />,
});
const card = Slack.Block.Card({
title: <Slack.Object.MarkdownText text="*Deploy ready*" />,
actions: [approve],
});
await thread.post(<Slack.Block.Carousel elements={[card]} />);
生成的 本地目录 列出 20
消息块和所有导出元素和对象。 运行
pnpm audit:channel-native-catalogs 和Slack的现场医生比较.
数据可视化块
Slack.Block.DataVisualization 执行 Slack的全馅饼,酒吧,区域,和
线路图合同。 SDK检查供应商的限制和跨战地规则
在发送消息之前,包括将每个序列点匹配到
命令轴分类,并允许每封信最多有两个图表.
import { createChannel, defineChannelComponent } from "@copilotkit/channels";
import { Slack } from "@copilotkit/channels-slack";
import { z } from "zod";
const WeatherCard = defineChannelComponent({
name: "show_weather",
description: "Show a three-day weather forecast.",
parameters: z.object({
city: z.string(),
monday: z.number(),
tuesday: z.number(),
wednesday: z.number(),
}),
render: ({ city, monday, tuesday, wednesday }) => (
<Slack.Block.DataVisualization
title={`${city} forecast`}
chart={{
type: "line",
series: [
{
name: "Temperature",
data: [
{ label: "Mon", value: monday },
{ label: "Tue", value: tuesday },
{ label: "Wed", value: wednesday },
],
},
],
axis_config: {
categories: ["Mon", "Tue", "Wed"],
y_label: "Temperature (F)",
},
}}
/>
),
});
const bot = createChannel({
// ...existing options
components: [WeatherCard],
});
见斯拉克的 数据可视化块引用 对提供者的字段定义和限制.
经常预算
黑帽每个元素。 成像器会随着流出而降解 /
夹子——它从不默默地降低内容. 限制居住 SLACK_LIMITS数字 :
| 限制 | 数值 | 元素 |
|---|---|---|
blocksPerMessage | 第50条 | 每个消息的块 |
sectionText | 3000个 | 区域字符 |
headerText | 150个 | 页眉字符 |
fieldsPerSection | 10个 | 每节字段 |
fieldText | 联合国 | 字段字符 |
actionsElements | 第25条 | 每个动作行的控制 |
contextElements | 10个 | 每个上下文块的元素 |
buttonText | 第75条 | 按钮标签字符 |
actionId | 255 (英语) | action_id 字符 |
buttonValue | 联合国 | 按钮值字符 |
selectOptions | 100个 | 每个选定的选项 |
彩牌
<Message accent="#RRGGBB"> 制作为带有颜色的黑附件
左栏( Block Kit 块没有本地口音, 所以重音消息是
公布于 attachments: [{ color, blocks }]) (中文(简体) ).
流线
默认情况下,通过Slack的回复流 本地流媒体 API
(单位:千美元)chat.startStream 编号 : appendStream 编号 : stopStream答复目标在何处
是线程——真实的流源 UI 渲染 原始标记 (如此真实的表格和
栅栏式代码是本地化的)。 整个溪流变成 一个 信件: 文本
从每个步骤累积到一个单一的泡沫(黑文档只有12k)
字符限制 每个附件,没有累积的封顶,所以没有多消息
分开). 默认情况下隐藏工具调用进度, 因此最后回复会保留
干净 过 showToolStatus: true 作为原生信息调用
task_update 块( 时间线) Using … → Used … 相反
状态信息。 结构块没有的工作空间
可自动降解到 :wrench: 状态行.
slack({
botToken,
appToken,
showToolStatus: true,
});
平面 DMs( 无线程) 和任何没有流出 API 的工作空间
自动倒回已发运的 chat.update 运输(喉咙编辑,
多信息块,中流括号自动关闭,Markdown → Mrkdwn
翻译). 过 streaming: "legacy" 迫使 chat.update 运输
到处都是 倒计时是透明的—— 选择进去永远打不倒机器人数字 :
首个 startStream 失败标记工作空间遗产并重做流
旧的方式.
反馈按钮( opt- in)
过 feedback 附加 Slack 本地的 AI 反馈行( QQ/ QQ,
context_actions + 键 feedback_buttons每一份最后答复。 点击
直通您的处理器 —— 它们从未到达引擎的交互
发送。 无 feedback,则不显示按钮.
slack({
botToken,
appToken,
feedback: {
onFeedback: ({ sentiment, user, channel, messageTs }) => {
recordFeedback({ sentiment, user, channel, messageTs }); // your telemetry
},
// positiveLabel / negativeLabel are optional
},
});
该行附于 chat.stopStream (唯一接受
blocks),因此它只出现在本土道路上——遗产 chat.update
倒计时省去.
土著"在想..." 地位(每个地方)
代理运行时,机器人显示Slack的 本地语言 装入状态
(单位:千美元)assistant.threads.setStatus:"在想...")在每条线被困扰的答复中——
频道@-mentions, 其拥有的线程, DMs, 以及助理平面. 现在就走
以普通方式接受此方法 chat:write 范围(无) assistant:write
因此它也适用于基于频道的应用程序。 这个
回复流进入时自动清除状态。 工具进度为每平方公尺
仅当表面 showToolStatus: true: 窗格使用活作曲状态
("是用"工具"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" task_update 时间表
(或 :wrench: 旧工作空间的行)。 设定 assistant: false 选择退出
状态(和窗格)全部.
助理面板(代理内设、默认)
当Slack应用程序有 代理 & AI 应用程序 切换( 一个 assistant_view
显示块 + assistant:write 范围和范围 assistant_thread_* 事件,
适配器激活 Slack 的助手面板 零配置数字 :
- 打开窗帘贴出一个问候式+可抓取的快取芯片,以及每个窗帘 对话是它自己的线程(复制人留在线条中).
- 在代理运行时,会显示本地作曲状态(见上文). 打开
与
showToolStatus: true显示“使用工具”每个工具调用. - 窗格线程从第一个消息自动标题.
通过 assistant 选项,或设置 assistant: false 禁用窗格
完全处理。 应用程序 无 切换行为和以前一样
平板机械休眠.
slack({
botToken,
appToken,
assistant: {
greeting: "Hi! I can triage issues, search docs, and more.",
suggestedPrompts: [
{ title: "Triage my open issues", message: "Triage my open issues" },
],
},
});
// Dynamic behavior when a user opens the pane (layers on top of the defaults):
bot.onThreadStarted(async ({ thread, user }) => {
await thread.setSuggestedPrompts(promptsFor(user));
// await thread.setTitle(...) is also available
});
互动(相对第一)
每一个黑 block_actions 点击立即被锁定(在 • 3个
截止日期, ackDeadlineMs = 3000,则 decodeInteraction 提取
不透明薄荷代号( y)ck:…任何细小的 bind() 值,和消息参考,以及
手执一 InteractionEvent 到发动机。 信使只携带不透明
id——没有道具和秘密. 无关的点击解码到 bot 事件
无害的忽略.
人类的跳动
使用 thread.awaitChoice(<Picker .../>) 发布交互式信息
块以待单击解决;已解决的值是单击控件的
数值。 代理中断( E)on_interrupt)被跑道渲染器所捕获并
发往您的 onInterrupt 处理器,它会张贴一个拾取器;单击
通过 thread.resume(value)。 。 。 .
发件人配置解析文件下载( F)
处理器收到 actor导致事件的Slack账户 user, (中文(简体) ),
频道返回的无效应用程序用户 identifyUser 政策.
标准 "platform" 政策名称空间通过提供者和
工作空间。 它不映射bots,apps,系统演员,或未知的演员. 入境
文件可以作为多模式内容组件交付给代理; 工具可以张贴
文件通过 thread.postFile(...)。 。 。 .
情报记忆
内存关闭, 除非特定运行允许:
bot.onMention(async ({ thread }) => {
await thread.runAgent({
memory: { user: "read", project: "read-write" },
});
});
用户内存在代理机启动前失败 identifyUser 返回时 null。 。 。 .
只项目存储器在没有应用程序用户的情况下工作. 恢复用户运行
内存必须选择 subject: "initiator" 或者说 subject: "actor"; 无法调用
通过原始用户身份.
内建
defaultSlackTools- 船舶lookup_slack_user这样,代理可以解决一个 名称/处理/电子邮件给 a<@USERID>提及。 展开到tools。 。 。 .defaultSlackContext标记程序、Markdown-vs-mrkdwn指导,以及 黑线/DM对话模式。 展开到context。 。 。 .
工具上下文
没有Slack特定的工具上下文 。 工具接收单一共享
ChannelToolContext 从 @copilotkit/channels (单位:千美元){ thread, message?, user?, signal?, platform }并且只能通过能力力量获得Slack电源 thread
方法,此适配器的背面:
thread.getMessages()——当前线程的消息(通过conversations.replies),每个aThreadMessage(单位:千美元){ user?, text, ts?, isBot? }) (中文(简体) ).thread.lookupUser(query)- 解决姓名/处理/电子邮件问题ProviderActor。 。 。 .thread.postFile({ bytes, filename, title?, altText? })上传文件 返回到线条中( r)files.uploadV2) (中文(简体) ).
它保持工具的便携性:用 defineChannelTool({...}) 他们
对任何宣传同样能力的适配器的工作.
运行演示
这个包是 图书馆可运行的端到端演示线
相对于真正的工作空间
examples/slack。 。 。 .
斜线命令
适配器将每个斜线命令Slack传送到引擎上
路径到匹配 bot.onCommand 处理器( 并忽略未注册)
, (原始内容存档于2018-09-21). Official website 发动机上的登记处理员——见
@copilotkit/channels数字 :
bot.onCommand({
name: "triage",
description: "Summarize the thread and propose issues.",
async handler({ thread, text, user }) {
await thread.runAgent({ prompt: `Triage: ${text}` });
},
});
您还必须在 Slack 应用程序配置中声明每个命令 ("斜线")
命令 / app Express)同名——Slack不会提供
未注册的命令,甚至超过Socket Mode. 参数作为免费文本到达
(单位:千美元)ctx.text);可选 options 计划是针对有原生水面的
有结构的参数(例如Discord),在Slack上被使用. 适配器没有
执行 registerCommands,所以引擎跳过它(Slack匹配命令)
而不是在前面登记).
OAuth 机器人瞄准镜
以下的机器人符号范围需要或相关,取决于 设置您的应用程序用途 :
| 范围 | 所需经费 |
|---|---|
chat:write | 发送信息、流传信息、电平信息chat.postEphemeral),和打开模式(views.open)——都拥有这个单一的范围. |
reactions:read | 读取反应; 订阅 reaction_added 编号 : reaction_removed 在应用程序中的事件 显示接受它们. |
reactions:write | 增加或去除通过 reactions.add 编号 : reactions.remove。 。 。 . |
assistant:write | 原生溪流 task_update 工具时行块和助手窗格。 ("在思考..."状态与 chat:write 独活. ) |
files:write | 正在通过 thread.postFile()。 。 。 . |
users:read | 通过 : users.info。 。 。 . |
users:read.email | 解决用户电子邮件地址 . |
channels:history | 通过读取频道线索消息 conversations.replies。 。 。 . |
groups:history | 通过读取私有频道线索消息 conversations.replies。 。 。 . |
im:history | 通过读取 DM 线索消息 conversations.replies。 。 。 . |
mpim:history | 通过读取组- DM 线索信件 conversations.replies。 。 。 . |
页:1
- 模块 (单位:千美元)
views.open, (中文(简体) ),view_submission, (中文(简体) ),view_closed处理方式:chat:write- 不需要增加范围. - 电文 (单位:千美元)
chat.postEphemeral: 涵盖范围chat:write。 。 。 . - 反应 (单位:千美元)
reactions:read编号 :reactions:write):仅这些瞄准镜 这还不够,你还必须订阅reaction_added财务报告和审定财务报表reaction_removedslack 应用程序中的事件列表,以便 Slack 交付 事情发生在你的机器人.
V1里没有什么
- OAuth / 多工作空间安装( 仅限单个bot 令牌)
- 持久性( Redis/ DB)
ActionStore仅记录;行动于 重新启动 - 主动贴出( 机器人只回答旋转它的一部分)
出口
slack, (中文(简体) ), SlackAdapter, (中文(简体) ), SlackAdapterOptions, (中文(简体) ), SlackAssistantOptions, (中文(简体) ),
SlackRespondToOptions· ;
createRunRenderer· ; decodeInteraction, (中文(简体) ), conversationKeyOf· ; renderBlockKit, (中文(简体) ),
renderSlackMessage, (中文(简体) ), SLACK_LIMITS· ; defaultSlackTools, (中文(简体) ),
lookupSlackUserTool, (中文(简体) ), defaultSlackContext (+ 个人背景)
条目; markdownToMrkdwn; 和
保存的力学SlackConversationStore, (中文(简体) ), MessageStream, (中文(简体) ),
ChunkedMessageStream, (中文(简体) ), NativeMessageStream, (中文(简体) ), attachSlackListener, (中文(简体) ),
attachAssistant, (中文(简体) ), SanitizingHttpAgent (损耗——频道消毒
默认), buildFileContentParts, (中文(简体) ),
autoCloseOpenMarkdown,以及支持类型).