Messenger Power
在 Desktop 中管理 Bot Account,并把外部会话可靠地路由到 Agent Session
Messenger Power 是 City 持有的渠道运行时。它不属于某个 Agent,也不通过 context.agent.chat 暴露长期状态。
Desktop 使用
打开 Messengers 后,左侧 Sidebar 会列出全部 Bot Account。点击 Sidebar 标题栏中的加号,从下拉菜单选择 Telegram、飞书/Lark 或 QQ 后创建对应的 Bot Account。可以添加多个同平台 Bot Account。选择飞书/Lark 时默认使用扫码创建,不需要手动填写 App ID 与 App Secret。
点击一个 Account 可以管理:
- 启用状态、平台凭据与连接测试
- 新 Conversation 默认绑定的 Agent
- 外部身份的 Access 申请与授权
- 每个 Conversation 的 Agent、Channel Session 与暂停状态
- 达到自动重试上限的 Inbox/Outbox 任务
- 不包含消息正文和密钥的 Activity
在 Desktop 保存 Account 后立即应用,只重启该 Account 的 Connector,不需要重启 Desktop 或 City,其他 Bot 连接不受影响。密钥可以直接在 Settings 中写入;已保存的密钥不会回显,编辑时留空表示保留原值。
Telegram 等平台在部分网络环境下需要代理才能访问。只要在系统或 Desktop 中开启代理,Channel 会自动使用,无需额外配置。
网络与连接
Telegram、飞书与 QQ 的请求都经过 Power 统一出站层,行为一致:
- 每个请求都有整体超时,不会无限挂起。连接失败时 Account 会进入
错误并直接展示原因。 - 代理优先级:Desktop 网络代理设置 → 操作系统系统代理 →
Global / Env中的HTTPS_PROXY等变量。macOS 开启系统代理后 Power 会自动继承,系统例外列表会转换为NO_PROXY。 - 代理变化(包括开系统代理 / 连 VPN)后,Desktop 会在 30 秒内自动重新解析并重连已启用的 Channel,无需重启。
- 只支持
http://或https://代理地址;socks5://会直接报错并提示改用 http 地址。NO_PROXY支持主机名、.example.com、*.example.com与 IPv4 CIDR。 - 连接意外失败后会自动按退避重连(最长 5 分钟一次),成功后退避重置。Account
未连接时 Outbox 只延后发送,不消耗重试次数。
如果 Account 一直停在 连接中,先点一次“测试连接”;仍失败时,界面上的错误文本会给出具体原因(例如代理不可用或目标不可达)。
Account 配置
Account 定义与密钥以 City Power Config 为唯一事实源。示例:
{
"accounts": [
{
"account_id": "support-telegram",
"name": "Support Bot",
"provider": "telegram",
"enabled": true,
"agent_id": "support",
"bot_token": "<telegram-bot-token>"
}
]
}飞书/Lark 使用 app_id、app_secret 和可选 domain;QQ 使用 app_id、app_secret 和可选 sandbox。
在 Desktop 中添加飞书/Lark Channel 时默认走扫码创建:点“扫码创建”,用飞书扫描二维码并在手机上确认,App ID 与 App Secret 会自动写入并立即启动,不需要到开放平台手动复制。确认页会预填应用名称与描述,并勾选本渠道需要的权限点和 im.message.receive_v1 事件。
扫码基于 OAuth 2.0 Device Authorization Grant(RFC 8628),只允许创建新应用,不会覆盖已有应用的配置。二维码有效期以平台返回为准(当前约 1 小时),过期后可以重新生成。无法扫码时(例如企业未开启开发者权限,或需要复用已有应用),在同一页面切换到“手动填写凭据”即可。
消息与 Session
允许访问的外部消息先写入 Inbox,再由 Conversation 路由到独立的 Channel Session(origin.type = "channel")。每个 Bot Account 下的聊天及 Thread 各有一条 Session,同一聊天后续消息复用它。不同聊天的历史彼此独立,也与 Agent 主对话分开。Session Messages 是完整对话的唯一事实源。
IM 只绑定 Agent,不需要选择 Workspace。Desktop 中 Channel Session 与 Agent 主对话默认共享该 Agent 的主 Workspace(agents/<agent_id>/main),具备相同的 Workspace 工具、Power、Agent 自定义工具和 Session 管理工具。对话历史分别保存,文件与 Shell 使用当前 Workspace。可通过 Session 管理工具创建项目 Work Session。SDK 宿主通过 Agent 的 workspace 提供默认主上下文。账号未配置 Agent 时,仅在 City 中 Agent 唯一时自动选用。
切换 Conversation 的 Agent 或重置对话会创建新的 Channel Session,原 Session 保留。升级前的 IM Work Session 也保留,升级后聊天从新建的 Channel Session 继续。附件接收保存到 Messenger 自有目录;发送时可使用该目录及 Session 当前项目目录。
可靠链路为:
Platform → Access → Inbox → Conversation → Channel Session
→ Outbox → PlatformInbox 使用平台消息 ID 去重,并以稳定 request_id 调用 Session。进程在 User Message 落盘后退出,恢复时不会追加第二条用户消息。Agent 结果以稳定 Delivery ID 写入 Outbox,避免恢复时重复建单。
Outbox 提供持久化、lease、有限重试和人工恢复。平台本身不支持幂等发送时,对外语义是 at-least-once:平台已接收但本地尚未记录确认的瞬间退出,恢复后可能再次发送。
Agent Actions
Agent 只看到自己拥有的 Conversation,并使用严格输入的 Action:
context:读取当前 Chat Session 路由list:列出当前 Agent 的 Conversationhistory:读取 Agent Session 的 canonical messagessend:将文本写入可靠 Outboxreact:为 Telegram 消息写入可靠 Reaction 操作
SDK 装配
import { MessengerPower } from "@downcity/powers/messenger";
const city = new City({
powers: [new MessengerPower()],
workspaces: [workspace],
power_host,
});Messenger Power 需要 City 宿主提供 Power Config、生命周期 Storage 和 Agent Session 能力。Bot Connector 在 initialize() 中主动恢复,在 dispose() 中统一关闭。
飞书依赖
启用飞书/Lark Account 的宿主需要安装:
npm install @larksuiteoapi/node-sdk@^1.73.3扫码创建依赖 SDK 的 registerApp,需要 ^1.67.0 及以上版本;低于该版本时扫码入口会提示升级,手动填写凭据仍然可用。