> ## Documentation Index
> Fetch the complete documentation index at: https://docs.myrmagent.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 多渠道

> 将 Agent 连接到 35+ 消息平台，输出自动适配渠道。

# 多渠道集成

从任意消息平台访问 Agent — 35+ 渠道，自动格式适配。

## 支持的渠道

| 类别   | 渠道                                                                | 数量 |
| ---- | ----------------------------------------------------------------- | -- |
| 即时通讯 | Discord、Slack、Telegram、WhatsApp、Signal、Line、Matrix、Mattermost、IRC | 9  |
| 中国生态 | 微信、企业微信、企微 AI Bot、钉钉、飞书、QQ、OneBot、微信公众号                           | 8  |
| 开发者  | GitHub（Webhook + PR 评论）                                           | 1  |
| 企业   | Microsoft Teams、Google Chat                                       | 2  |
| 语音   | Discord Voice（含 DAVE E2E 加密）                                      | 1  |
| 其他   | Email、SMS、iMessage、Webhook、Zalo                                   | 5  |

## 设置

在 GUI **设置 > 渠道** 连接平台。各渠道独立配置面板与连接状态指示。

### 微信（通过 iLink）

一分钟内完成微信个人号扫码绑定：

1. 打开 **设置 > 渠道 > 微信**
2. 点击 **扫码连接** — 弹出二维码弹窗
3. 打开手机微信扫描二维码
4. 在手机上确认 — 弹窗实时更新状态（SSE 流式推送）
5. 完成 — 微信已连接

登录流程提供实时状态反馈：生成二维码 → 等待扫码 → 验证中 → 连接成功。二维码过期后点击 **重试** 即可刷新。

**输入状态指示器可靠性**：iLink typing ticket 在 600 秒后过期。对于长时间运行的 Agent 任务（>10 分钟），系统在 ticket 过期前主动刷新（540 秒阈值，60 秒安全缓冲），使用单调时钟防止系统时钟漂移。确保 Agent 完成后「正在输入...」状态始终正确消失，不会出现输入状态冻结。

### 微信公众号（草稿发布）

**订阅号/服务号**（非个人微信）使用 **AppID + AppSecret**，在 WebUI 确认后将排版好的 HTML 推送到 **草稿箱**。

完整指南：[微信公众号发布](/docs/zh/guides/wechat-official-publishing)。

1. **设置 → 渠道 → 微信公众号** — 填写 AppID、AppSecret、IP 白名单并测试连接。
2. 用 **wechat-article-formatter** 将 vault 内 Markdown 转为 `.wechat.html` 工件。
3. 在对话中预览 → 点击 **推送到公众号草稿**（标题 + 封面；文内首图自动预填）。
4. 在 [mp.weixin.qq.com](https://mp.weixin.qq.com/) 草稿箱中人工预览后群发。

<Note>
  草稿推送 **仅 HITL** — Agent 无 draft 工具（利于 Prompt Cache，避免误群发）。
</Note>

### WhatsApp（通过 Baileys）

1. 打开 **设置 > 渠道 > WhatsApp**
2. 点击 **扫码连接** — 与微信相同的二维码弹窗
3. 打开手机 WhatsApp → **已关联的设备** → 扫描二维码
4. 自动建立连接

微信和 WhatsApp 均使用统一的 `AsyncLoginProtocol`，跨渠道体验一致。

### Telegram

两种方式连接 Telegram，选择适合你的路径：

**路径 A：首次设置向导（推荐新用户）**

首次启动设置向导时，在配置模型和路由偏好后会出现 **Telegram 个人助手** 步骤：

1. 粘贴你的 **Bot Token**（从 [@BotFather](https://t.me/BotFather) 获取）
2. 可选填写 **Webhook URL**（仅 VPS / 云部署且有公网域名时需要）
3. 可选命名你的助手（默认 `Myrm Assistant`）
4. 点击 **激活** — 系统原子化地校验 token、写入凭据、将 DM 策略设为 open、绑定默认 Agent

任何步骤失败都会自动回滚，不会出现半配置状态。向导还能优雅处理并发提交：若有另一请求正在处理，系统自动重试并展示友好提示，不会暴露原始错误。

**路径 B：设置页（后续添加 Telegram）**

1. 进入 **设置 > 渠道 > Telegram**
2. 填写 **Bot Token** 和可选 **Webhook URL**
3. 保存 — Bot 连接并开始接收消息

**Webhook vs 轮询**：不填 Webhook URL 时 Bot 使用长轮询（适合本地/桌面端），填写后 Telegram 主动推送更新到你的服务器（VPS/云部署必须）。

**Rich Message 渲染**：Telegram 通过 Bot API 10.1 支持原生 Rich Message — 表格、LaTeX 公式、嵌套列表均可原生渲染。

### Email（IMAP + SMTP）

1. 打开 **设置 > 渠道 > Email**
2. 配置 IMAP（收件）和 SMTP（发件）服务器地址、端口、凭证
3. 保存后自动开始轮询收件箱

**转发邮件智能解析**：直接把邮件转发给 Agent，系统自动区分你的指令和原始邮件内容。

* 支持 Gmail、Outlook、QQ 邮箱、163 邮箱、Foxmail 等主流客户端的转发格式
* 三层检测策略：Subject 前缀（Fwd:/FW:/转发:/轉發:）→ Body 分隔符 → MIME 附件
* 你只需在转发时写上"帮我报销"或"翻译成英文"，Agent 同时看到你的指令和原邮件全文，精准执行
* 中文邮件客户端完整支持（简体/繁体），charset 自适应（gb2312/GBK/UTF-8）

**邮件内容智能清洗**：当邮件只有 HTML 版本时（如 Amazon 订单、Jira 通知、Outlook 富文本），自动转为干净 Markdown，保留表格、链接和列表等语义格式，内容体积缩减 65–74%（实测），Agent 理解更快更准。

## 消息类型

所有渠道支持：

* 文本（平台适配格式）
* 图片 / 文档 / 音频 / 视频附件（`MediaType`）
* 文件上传与自动类型检测

## 文件双向收发

Agent 产出的文件自动推送到 IM 渠道，无需手动下载。

### 入站（用户 → Agent）

通过 IM 发送文档（PDF、Excel、Word 等），内容自动提取并注入 LLM 上下文。Agent 无需额外调用读文件工具即可理解文件内容。

### 出站（Agent → 用户）

Agent 生成的文件（图表、报表、表格、编译文档等）自动作为媒体附件推送到聊天。支持通过代码执行、文件写入或文档生成工具创建的所有文件。

| 特性   | 详情                               |
| ---- | -------------------------------- |
| 大小限制 | 每文件 5 MB（超限自动跳过）                 |
| 失败处理 | 自动重试 + 媒体剥离降级 — 文本永不丢失           |
| 支持类型 | IMAGE、DOCUMENT、AUDIO、VIDEO（自动识别） |
| 多文件  | 所有产出文件逐个推送                       |

### Artifact 深度链接

对于交互式产出物（HTML 页面、PDF、文档），Agent 自动在 IM 消息中生成可点击的**深度链接按钮**，替代原始文件附件。点击按钮即可在浏览器中直接打开——无需下载。

| 特性   | 详情                                 |
| ---- | ---------------------------------- |
| 触发条件 | 可分享类型（HTML、PDF、Document）自动触发       |
| 安全性  | HMAC 签名、时限、只读共享令牌                  |
| 多产出物 | 每个产出物单独命名按钮（如 "💻 dashboard.html"） |
| 冗余移除 | 深度链接可用时自动移除原始文件附件                  |
| 安全降级 | 无公网 URL、DB 异常或 Token 失败时回退为原始文件    |
| 多语言  | 按钮文案支持中英文                          |

## 渠道感知输出适配

Myrm **三层**架构确保输出既干净又格式正确：

### 出站消息降噪

每个渠道有独立的 `RenderStyle` 配置，控制用户看到的内容：

| 控制项                    | 选项                       | 默认值                                      |
| ---------------------- | ------------------------ | ---------------------------------------- |
| `reasoning_display`    | OFF / COLLAPSED / INLINE | OFF（微信、企微、WhatsApp）或 COLLAPSED（Telegram） |
| `tool_summary_display` | OFF / COMPACT / DETAILED | OFF（微信、企微、WhatsApp）或 COMPACT（飞书、钉钉）      |

默认配置下，IM 用户只收到**进度标签、最终结果和决策提示** — 看不到 tool 调用参数、reasoning token 或 thinking 标签。`strip_thinking_tags()` 函数提供额外安全网，清除任何可能泄露的 LLM 思考块。

进度标签会附带**操作内容摘要**，让你清楚看到 Agent 在做什么：

* `🔍 Searching: AI 编程工具 2025`（而非笼统的 "Searching the web..."）
* `📄 Reading: config/settings.yaml`（而非笼统的 "Reading file..."）
* `⏳ **notion_query** — 搜索会议纪要`（自定义 MCP 工具自动覆盖）

所有工具均被覆盖 — 已注册工具显示具体操作内容，未注册工具（包括你配置的任何 MCP 服务）通过通用 fallback 自动提取输入摘要。更新频率受 2 秒节流保护，避免触发平台 API 频率限制。

### 事前引导（channel\_output\_hints）

Agent 初始化时向系统提示词注入渠道格式提示，生成前告知 LLM 平台能力：

* **Telegram**：表格、LaTeX、嵌套列表通过 Bot API 10.1 Rich Message 原生渲染；仅 Rich 不可用时激活格式提示
* **WhatsApp**：「Markdown 不渲染 — 仅纯文本」
* **Discord**：「超 2000 字符自动拆分」
* **Voice**：「像与人对话一样说话」

28 条渠道提示预配置，KV-Cache 安全（初始化注入一次）。

### IM 行为策略 Persona（自动注入）

对于受限 IM 渠道（不支持消息编辑且不支持 Markdown），系统自动注入行为策略指令：

* **简洁对话风格**：像聊天一样回复，不长篇大论
* **长内容自动转文件**：超过约 200 字符的内容写入工作区文件，IM 中只回复一句话摘要 + Artifact 深链
* **精准追问**：用户意图不明时最多问 1-2 个关键问题

自动触发的渠道：微信 iLink、微信公众号、Signal、iMessage、LINE、SMS、OneBot(QQ)、IRC、Zalo、Voice（共 10 个）。

无需任何配置 — 基于 `ChannelCapabilities` 声明自动判断。支持 Markdown 或消息编辑的渠道（如 Telegram、Discord、Slack）不受影响。

### 事后格式降级（renderer）

即使 LLM 忽略提示，渲染流水线仍降级：

* `supports_tables=false` → 表格转列表
* `supports_latex=false` → LaTeX 剥为纯文本
* IM 渠道 HTML/SVG 代码块换短占位
* 无来源时自动清理孤立引用标记

### 智能消息拆分

长消息在自然边界自动拆分：

* 代码围栏状态机保证跨块正确闭合重开
* 在空白与标点处智能分行
* 可配置溢出容差保语义
* 按渠道长度限制（如 Discord 2000、Telegram 4096 HTML / 32000 Rich Message）

### Telegram Rich Message（Bot API 10.1）

Telegram 渠道支持原生 Rich Message 渲染，配备三层智能降级：

1. **Rich Message** — 表格、LaTeX 公式、嵌套列表原生渲染（32KB 限制）
2. **HTML** — 自动转换，含 ASCII 等宽线框表格降级（4096 UTF-16 限制）
3. **纯文本** — HTML 解析失败时的最终兜底

流式预览采用**无闪烁草稿模式**（`sendRichMessageDraft` → `sendMessageDraft` → `editMessageText`），设 20 字符最小阈值抑制初始 token 闪烁。CJK 内容享受完整 Rich 格式化，无降级无 workaround。

## 群聊特性

### AllowPolicy

三档预设控制群聊何时响应：

| 策略        | 私聊   | 群聊         |
| --------- | ---- | ---------- |
| OPEN      | 全部允许 | 全部允许（无需 @） |
| SELECTIVE | 全部允许 | 需 @        |
| STRICT    | 需 @  | 需 @        |

### GroupTriggerMode

精细控制群聊中 Agent 何时被激活：

| 模式            | 行为                   |
| ------------- | -------------------- |
| ALL           | 群内所有消息都触发 Agent      |
| MENTION\_ONLY | 仅 @Agent 时响应         |
| PREFIX        | 消息以指定前缀开头时响应（前缀自动剥离） |

### Topic Binding

三级粒度将不同 Agent 绑定到不同对话范围：

* **Thread 级**：绑定到某个话题/线程
* **Chat 级**：绑定到某个群/会话
* **Channel 级**：绑定到整个渠道

查找顺序 Thread→Chat→Channel 逐级降级，未绑定时使用默认 Agent。

### Topic 工作区绑定（Vault / Project）

将每个 IM 话题绑定到真实工作区，避免远程消息落入空 JIT 沙箱。

| 方式      | 操作                                                                  |
| ------- | ------------------------------------------------------------------- |
| **GUI** | **设置 → 渠道路由** → 每话题 **Project** 下拉                                  |
| **IM**  | `/bind workspace=project:<uuid>` 或 `/bind workspace=/path/to/vault` |
| **组合**  | `/bind agent=my-agent workspace=project:<uuid>`                     |

每次 Agent 执行前，系统将话题绑定 sync 到 chat SSOT（`project_id` 或 `workspace_dir`），与 WebUI 会话共用 `resolve_effective_chat_workspace` 解析链。解绑会双向清空 chat 工作区字段。Project 或路径不可用时 fail-loud，不会静默进入空沙箱。

**诚实边界**：IM `/status` 仍显示 `project:uuid`（非友好名）。GUI 无路径选择器——GUI 用户绑 Project，路径绑定走 IM。

**测试**：9 项 server pytest（sync、topic\_config 校验、解绑清空、effective\_workspace 链）；FE label helper 3 vitest。

**vs OpenClaw**：OpenClaw 在 Agent 配置级绑定 `workspaceDir`，一个 Agent 一个目录。Myrm 在 Topic 粒度绑定，同一 Agent 可服务指向不同 vault 的不同 Telegram 话题。

### Obsidian Vault 写入保真

话题绑定 Obsidian vault 后，Agent 直接改**真实 vault 文件**（非副本）。Myrm 提供两层代码级保护：

1. **Frontmatter 保留** — LLM 编辑正文时若整段丢掉 `---` YAML 块，写前守卫自动补回 pre-edit frontmatter（`date:`、`tags:`、Dataview 字段不丢）。
2. **vault 笔记不跑 prettier** — FormatObserver 跳过 `.obsidian/` 下 `.md`，避免自动格式化剥离元数据。

**诚实边界**：仅整块 frontmatter 丢失时补回（非 field 级 merge）。双链完整性靠 `obsidian-notes` skill 提示，暂无 vault 全库 backlink 扫描。

**测试**：44 pytest（2026-07-28）：harness guard + server parser + service 集成 + format observer。

### 线程自动跟进

Agent 在线程中回复后，**GroupFollowUpTracker** 自动激活该线程（TTL：10 分钟）。在此窗口内，线程中的后续消息无需 @mention — Agent 自动继续对话，如同真人聊天。

发送 `/mute`、`/shutup`、`闭嘴` 或 `别吵` 即可停止 Agent 在当前线程的响应。再次 @mention 即可重新激活。

### 客模式（Guest Mention）

即使群组未显式启用 Agent，用户也可以 @mention Agent 获得一次性回复（需开启 guest mode）。无需将群组加入白名单即可获得 AI 临时帮助。

### 精确 Bot ID 匹配

每个渠道适配器均执行精确的 bot 身份匹配 — Telegram 匹配 `bot_username`，飞书匹配 `bot_open_id`，Teams 匹配 `app_id`，WhatsApp 匹配 `mentionedJids`。@mention 始终精确路由到正确的 bot，35+ 渠道零误触发。

### GroupContextBuffer

群聊非触发消息累积于 per-group 环形缓冲。@Agent 等触发时排空缓冲注入上下文 — Agent 感知群讨论脉络。

### SessionGate

同会话连发消息防抖（默认 300ms）合并为单次请求，防重复处理。

## Agent 主动通知

Agent 可主动向配置渠道推送 — 无需轮询。

### 流程

1. 在 **Agent 设置 → 通知渠道** 从**当前运行中**的渠道下拉选择（动态 `displayName`，新渠道接入后无需等前端发版），并从已配对联系人下拉选择收件人（或手动输入 ID）
2. Agent 在需告警时调用 `channel_notify_tool`（任务完成、异常、定时报告就绪）
3. 可选附带文件或图片 — 本地路径和 URL 自动解析，精确识别媒体类型
4. 经 `send_tracked` 同步投递并返回成功/失败（与关键渠道消息同一重试策略），避免异步队列静默丢消息

> **与「通知投递」的区别**：本处 **Agent 设置 → 通知渠道** 仅用于智能体主动 `channel_notify_tool`；**设置 → 通知投递** 用于 OAuth 过期、预算、配对等 **系统事件** IM 告警。二者互不替代。

### 安全

| 层          | 防护                                                                     |
| ---------- | ---------------------------------------------------------------------- |
| 白名单        | 仅用户配置目标可达                                                              |
| 限流         | 每会话上限防刷屏（默认 10）                                                        |
| 内容上限       | 超 `max_body_length`（4000 字符）自动截断                                       |
| 附件校验       | 本地路径须落在 Agent workspace（`declared_allowed_roots`）内；URL 文件名安全解析（兼容查询参数） |
| 审计         | 每次通知目标记入会话状态                                                           |
| 子 Agent 隔离 | 子 Agent 默认无法调用 `channel_notify_tool`（harness L1 blocklist）             |
| 失败可见       | sync 投递失败进入 DLQ 并触发 WebUI toast（presync dedupe，重启后 dedupe 不持久）         |
| 实现层        | 业务层 `outbound_notify/`（非 harness 内核），与 ChannelGateway 同层               |

> **测试覆盖（2026-07-07）**：notify 专项 **127 项 pytest + 1 项 live agent-stream E2E（MiniMax-M2.7，RUN\_E2E\_TESTS=1）+ 7 项 vitest + Chrome 真实用户 round42 全流程（源对话 tool 步骤 + 收件箱 UI）** 全绿 — 含 ChatChannel 应用内落库、DLQ/告警链、子 Agent 隔离、附件 path 沙箱、动态 running 渠道下拉。

### 场景示例

* 凌晨 3 点定时任务完成 → 摘要 + 报告 PDF 发 Telegram
* 长跑代码分析结束 → 结果 + 生成的图表推 Slack
* 监控数据异常 → 告警 + 仪表盘截图发配置目标

## Web Push 离线推送

关闭浏览器后仍可收到关键告警 — 无需安装原生 App。

当 PWA 关闭或退到后台时，服务器通过 W3C Web Push 标准（VAPID）发送推送通知。覆盖未配置 IM 渠道或只想用浏览器原生告警的场景。

### 支持的事件类型

| 事件     | 示例                 |
| ------ | ------------------ |
| 审批请求   | Agent 需要权限执行敏感操作   |
| 目标完成   | 后台任务成功结束           |
| 目标失败   | 任务遇到不可恢复错误         |
| 目标验证   | 结果已就绪，待你审查         |
| 健康告警   | 系统检测到服务中断          |
| 预算告警   | 用量接近配置上限           |
| 后台任务完成 | 长时间运行的任务已完成        |
| 系统通知   | 安全事件、配对请求、OAuth 回调 |

### 设置方法

1. 进入 **设置 > 系统 > 推送通知**
2. 开启 **启用** 开关 — 浏览器请求通知权限
3. 完成。即使关闭标签页，通知也会送达。

**测试按钮**可立即验证投递是否正常。

### 平台兼容性

| 平台                           | 支持情况                |
| ---------------------------- | ------------------- |
| 桌面浏览器（Chrome, Firefox, Edge） | ✅ 完全支持              |
| Android（Chrome, Firefox）     | ✅ 完全支持              |
| iOS / iPadOS（Safari 16.4+）   | ✅ 需"添加到主屏幕"（PWA 模式） |
| Tauri 桌面应用                   | 不适用 — 已有原生 OS 通知    |

在 iOS 上，设置卡片会自动检测是否运行在独立 PWA 模式下，并在需要时显示安装引导。

### 安全与维护

* **VAPID 密钥自动生成** — 首次启动时自动创建并持久化密钥，零配置
* **过期订阅自动清理** — 推送失败（410/404）时自动删除过期订阅
* **无第三方依赖** — 推送直达浏览器厂商端点（Google FCM、Apple APNs、Mozilla autopush）
* **Tauri 感知** — 桌面应用构建中自动隐藏此设置卡片（已有原生通知）

### 一键审批深链

点击推送通知会直达对应会话并**弹出审批抽屉**——不是只打开首页。

* **审批请求**跳转到 `/{chat_id}?approval={id}`；WebUI 打开全局 ApprovalDrawer 并剥离 query，保持 URL 干净
* **Service Worker 路由**校验同源路径；若聊天 Tab 已打开，在 query 变化时调用 `navigate()` 而非仅 focus——新审批不会漏开抽屉（OpenClaw 的 SW 只比 pathname，存在此缺陷）
* **Chrome MCP E2E 已验证** — 热 Tab 与冷启动深链双路径（2026-07）

## 后台任务自动回复

通过 `/btw` 在任意 IM 渠道发起后台任务后，任务完成时结果会自动推送回你的原始会话：

* **线程精准投递** — 回复精确到你发起任务的那个线程
* **多语言通知** — 消息自动匹配你的语言偏好（中文、英文等）
* **失败告警** — 任务失败时收到错误摘要，而非石沉大海
* **可靠投递** — 与所有渠道消息共享同一套重试基础设施
* **互不干扰** — 独立于通知设置运行；这是直接回复，不是广播

在 Discord 发起任务，去做别的事，回来时结果已在你的线程中等候。

## 长任务心跳（原地编辑）

当 Agent 执行复杂任务且长时间未产生输出时，系统会自动发送心跳消息，让你知道它仍在工作中——且不会用多条消息刷屏你的聊天。

### 工作原理

1. 后台并行监控器持续追踪距上次活动（发送消息、进度更新等）的时间
2. 静默超过 2 分钟后，向发起任务的 IM 渠道发送心跳消息
3. 后续心跳**原地编辑同一条消息**，更新已用时间、步骤数和阶段——不会产生新消息
4. 如果渠道不支持消息编辑，仅发送一条消息（不刷屏）
5. 每个任务最多 3 次心跳周期
6. 使用 NORMAL 优先级——心跳静默到达，不会触发手机推送通知

### 消息示例

> ⏳ 工作中 — 3 分钟（12 步, 数据分析）

消息会随任务进展原地更新：

> ⏳ 工作中 — 5 分钟（18 步, 代码生成）

### 智能静默检测

与简单的定时器不同，监控器会在 Agent 产生任何输出时**自动重置计时**。如果 Agent 在第 1 分钟发送了进度更新，2 分钟静默窗口会从该时间点重新开始。这避免了 Agent 正在活跃沟通时发送不必要的提醒。

### 渠道自适应

心跳系统会自动检测渠道是否支持消息编辑（`ChannelCapabilities.edit`）。Telegram、Discord 等渠道支持原地编辑；不支持的渠道仅收到一条心跳消息，避免刷屏。

如果编辑操作失败（如消息过旧无法编辑），系统会优雅降级为发送新消息。

### 详细参数

| 参数     | 行为                                             |
| ------ | ---------------------------------------------- |
| 静默阈值   | 120 秒（可通过 `_SILENCE_REASSURANCE_THRESHOLD` 配置） |
| 最大心跳次数 | 每任务 3 次（可通过 `_MAX_REASSURANCE_COUNT` 配置）       |
| 更新模式   | 原地编辑（不支持编辑的渠道自动降级为仅发一条）                        |
| 优先级    | NORMAL — 静默投递，不触发推送通知                          |
| 语言     | 完全国际化（中文简体、繁体、英文、日文，可通过 `.ftl` 文件扩展）           |
| 输入指示   | 并行运行——静默期间"正在输入..."持续显示                        |
| 提示词缓存  | 零影响——心跳仅为出站方向，不修改系统提示词                         |
| 错误处理   | 发送/编辑失败静默记录日志，主任务不受影响                          |

## 端内智能体切换

在任意 IM 渠道中直接切换 Agent，无需打开 WebUI 或编辑配置文件。

### Telegram（`/agent` 命令）

1. 在对话中发送 `/agent`
2. 弹出 InlineKeyboard 列表，展示所有可用 Agent — 当前绑定的 Agent 前有 ✅ 标记
3. 点选目标 Agent → picker 消息被替换为确认文本（"已切换至：XXX"）
4. 后续消息自动使用新 Agent（独立系统提示词、模型、工具、记忆）

### 快捷切换命令

Agent 配置中定义了 `command_bindings` 的会注册快捷命令（如 `/claude`、`/gpt`）。

**双模式路由：**

* `/cc fix this bug` — **一次性路由**：本条消息用 Claude 处理，但不改变当前绑定（下条消息仍用原 Agent）
* `/cc`（无参数）— **持久绑定**：将默认 Agent 切换为 Claude

这种设计消除了临时借用其他 Agent 时频繁切换回来的摩擦。

### Topic 绑定粒度

Agent 绑定遵循**三级解析**层级：

| 级别      | 作用域         | 示例                   |
| ------- | ----------- | -------------------- |
| Thread  | 群组内的单个回复线程  | 不同线程绑定不同 Agent       |
| Chat    | 一个私聊或整个群    | 大多数场景的默认粒度           |
| Channel | 某个渠道来源的所有对话 | 无 thread/chat 绑定时的兜底 |

### 多语言支持

所有 picker 和确认消息完全国际化。系统自动识别用户语言偏好（当前支持中英文，通过 `.ftl` 翻译文件可扩展）。

## 跨设备任务同步

所有后台任务存储在服务端，任何已连接的客户端均可访问 —— 桌面端、WebUI 或手机浏览器：

* **单一数据源** — 任务状态存储在服务端 Kanban 系统中，不依赖任何单一设备
* **全端实时更新** — SSE 事件将状态变更（完成、失败、进度）同步推送到每个已连接的客户端
* **一致体验** — 桌面端（Tauri）内嵌同一套 Web UI 前端，跨平台体验完全一致
* **IM 渠道联动** — BtwTaskNotifier 在 UI 更新的同时，将结果推送到 IM 渠道
* **IM 看板管理** — 在 Telegram、Discord、Slack 等渠道中直接使用 `/kanban`（或 `/kb`）命令创建、列表、编辑、完成、阻塞、归档任务，无需离开聊天窗口。零 LLM 消耗 — 命令完全绕过 Agent 管线

在桌面端发起任务，手机上查看进度，在 Telegram 中用 `/kanban` 管理任务，在 Slack 收到完成通知 —— 无需任何配置。

## 跨平台交接

在不丢失上下文的情况下，将对话从一个平台无缝转移到另一个平台。

**两种入口：**

* **Web UI** — 在侧边栏右键点击任意对话 → 「转移到...」→ 弹出 Dialog 自动列出所有已连接渠道（含图标和连接状态指示灯）→ 选择目标一键转移
* **IM 命令** — 在任意 IM 渠道（Telegram、Discord、Slack 等）中输入 `/handoff <目标渠道>`

**工作原理：** 交接通过单次原子化 DB 更新完成 session key 重绑定 —— 毫秒级延迟、零数据拷贝、完整保留 Prompt Cache。若目标 key 已被其他会话占用，系统自动解绑旧会话避免冲突。

**会话策略：** 三种模式控制转移后的会话行为 — `persistent`（永不重置）、`daily`（在配置的时刻重置）、`idle`（空闲超时后重置）。Agent 身份（`agent_id`）在转移过程中完整保留，同一个 Agent 的人格、工具和记忆在新渠道上无缝延续。

**测试覆盖：** 17 项单元测试 + 7 项 API 集成测试 = 24 项测试覆盖所有边界场景（冲突解决、同渠道拒绝、未配对、Agent 保留、策略模式等）。

### 自动「在浏览器继续」按钮

Agent 在 IM 渠道的每条回复底部自动附带\*\*「在浏览器继续」\*\*按钮。点击即可一键跳转到 WebUI 完整会话页面，查看工具调用步骤、代码差异和文件操作历史。

* **精确路由** — 按钮链接到 `/{chatUUID}`（数据库 Chat UUID），始终打开正确的会话
* **后台任务通知** — `/btw` 后台任务完成后的 IM 通知也包含跳转按钮
* **优雅降级** — 不支持按钮的渠道（如微信）自动降级为文本链接；无公网 URL 时静默省略，不阻塞回复
* **WebUI 过滤** — Web 渠道的消息不会显示冗余的自跳转按钮

**测试覆盖：** 22 项测试（11 单元 + 8 集成 + 3 回归），覆盖 URL 构建、DB UUID 解析、渠道过滤、错误处理和优雅降级。

## IM 撤销、重试与文件还原

在任意 IM 渠道发送 `/undo` 或 `/retry` 即可回滚 Agent 上一轮操作 — **包括自动恢复被修改的文件**。

| 命令       | 效果                                      |
| -------- | --------------------------------------- |
| `/undo`  | 删除上一轮用户 + 助手消息，**并还原该轮 Agent 修改过的所有文件** |
| `/retry` | 删除上一条助手回复并还原文件修改，**然后重新发送原始问题获取新回答**    |

**原理：** Agent 处理消息时，从 SnapshotStore 到数据库全链路使用同一 `message_id`。`/undo` 时系统取回被删除消息的 ID，查找对应的文件快照并恢复。用户看到本地化确认（如「↩ 已撤销：移除了 2 条消息。↩ 已还原 3 个文件。」）。

**竞品对比：** OpenClaw/Hermes/DeerFlow 仅在桌面 GUI 或 CLI 支持文件还原，**没有任何竞品在 IM 渠道实现撤销/重试联动文件 revert**。这意味着你可以放心地通过手机让 Agent 编辑文件 — 出了问题一条 `/undo` 命令全部恢复。

## GitHub Channel 与 CI/CD 集成

**GitHub Channel** 将 Agent 转化为自动化代码审查员，监听仓库事件并自动回复 PR 评论。

### 支持的事件

| 事件                    | 触发条件         | Agent 行为    |
| --------------------- | ------------ | ----------- |
| `pull_request`        | PR 创建/更新     | 自动代码审查 + 评论 |
| `issues`              | Issue 创建/更新  | 分类、标记、回复    |
| `issue_comment`       | Issue/PR 新评论 | 上下文回复       |
| `push`                | 代码推送         | 变更分析        |
| `pull_request_review` | 提交审查         | 跟进讨论        |

### 设置步骤

1. 进入 **设置 > 渠道 > GitHub**
2. 填写 **Personal Access Token**（需 `repo` 权限用于发布评论）
3. 填写 **Webhook Secret**（用于验证签名）
4. 在 GitHub 仓库设置中添加 Webhook URL（`https://your-server/channels/github/webhook`）

### 安全机制

所有 Webhook 请求通过 **X-Hub-Signature-256**（HMAC-SHA256）验证。无效签名直接返回 401。

### CI/CD 流水线集成

除 GitHub 外，任何 CI/CD 平台（Jenkins、GitLab CI、云效、CodePipeline）均可通过 REST API 触发 Agent：

```bash theme={null}
curl -X POST https://your-server/api/chats/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message": "Review the latest commit on branch feature/xyz"}'
```

**Webhook Channel** 可将结果以结构化 JSON POST 到你指定的任意 URL，用于对接 CI/CD 结果通知。

## 远程审批（HITL）

通过 IM 渠道远程控制 Agent 时，高危工具调用（文件编辑、Shell 命令）会触发**渠道内审批提示** —— 行业唯一的 IM 原生 HITL 系统。

### 工作流程

1. Agent 遇到高危工具调用
2. 审批消息（含批准/拒绝按钮）发送到 IM 渠道
3. 你可以批准、拒绝或使用批量命令
4. Agent 根据你的决策继续或停止

### 审批方式

| 方式     | 示例                                   |
| ------ | ------------------------------------ |
| 斜杠命令   | `/approve`、`/deny`、`/approve-always` |
| 拒绝并附原因 | `/deny <原因>` — Agent 会根据你的原因调整策略     |
| 快捷输入   | `1`（批准）、`2`（拒绝）、`y`、`n`              |
| 表情回应   | 👍（一次）、♾️（永久）、👎（拒绝）                 |
| 批量     | `/batch a,d,a`（批准、拒绝、批准）             |
| 中文     | `同意`、`拒绝`、`是`、`不`                    |

### 交互式按钮（ActionButton）

在支持交互元素的渠道（Telegram InlineKeyboard、Slack Block Kit、Discord 按钮、飞书卡片、MS Teams Adaptive Cards）中，审批提示包含原生 **批准 / 拒绝按钮**。点击按钮后：

1. 在数据库中解决审批（仅 PENDING 状态可操作 —— 重复点击安全忽略）
2. 编辑原始消息显示结果（如"已由 alice 批准"）
3. 自动恢复中断的 Agent

此机制与 WebUI 审批并行工作 —— 两条路径指向同一持久化记录。

### 安全机制

* **群聊保护**：仅原始请求者或已配置的协同审批人可操作
* **幂等保护**：已解决的审批不可被再次解决或状态翻转（DB 层 PENDING 检查）
* **超时守卫**：未响应的审批自动拒绝（可配置）
* **持久化白名单**：「永久允许」决策跨重启有效
* **防重试**：累计 3 次拒绝后 Agent 停止重试

## 出站 HITL（草稿审核）

企业销售和客服场景中，AI 生成的回复发送前可能需要人工审核。Myrm 的 **Outbound HITL** 会拦截 Agent 回复作为草稿，需要明确审批后才能发送。

### 配置

每个话题可在**设置 → 渠道路由**中独立配置：

| 设置   | 选项          | 说明                   |
| ---- | ----------- | -------------------- |
| 回复模式 | 自动发送 / 草稿审核 | 自动模式直接发送；草稿审核模式需人工确认 |
| 超时时间 | 1 分钟 – 1 小时 | 等待审核的最长时间            |
| 超时策略 | 自动丢弃 / 自动发送 | 超时未审核时的处理方式          |

### 工作流程

1. IM 渠道收到消息 → Agent 生成回复
2. 回复被拦截为 `ApprovalRecord`（不直接发送）
3. 审核人在 WebUI 审批抽屉或 IM ActionButton 中查看草稿
4. **批准** → 消息发送到渠道
5. **拒绝** → 消息被丢弃
6. **超时** → 按配置自动发送或自动丢弃

### 审核通道

* **WebUI 审批抽屉**：展示原始客户消息、AI 生成的回复草稿、渠道/话题信息
* **IM ActionButton**：审批通知中的批准/拒绝按钮

### 使用场景

| 场景      | 为什么需要草稿审核    |
| ------- | ------------ |
| 客户报价/定价 | 错误价格可能产生法律责任 |
| 合同条款    | AI 可能生成非标准条款 |
| 合规行业    | 金融/医疗通信需要审核  |
| 品牌敏感沟通  | 语气和准确性至关重要   |

## 智能静默过滤

当你在 Agent 的 System Prompt 中配置"无异常时回复 `[SILENT]`"等指令后，Myrm 会在投递前自动检测并过滤静默回复：

* **群聊场景**：Agent 被 @ 后判断无需回复 → 不发送任何消息（零噪音）
* **定时任务**：每 30 分钟巡检正常 → 自动静默，异常时立即推送
* **Placeholder 清理**：已显示的"正在处理"占位消息被静默删除

### 识别规则

| 格式                 |  是否静默  |
| ------------------ | :----: |
| `[SILENT]`         |    ✅   |
| 带空白 `  [SILENT]  ` |    ✅   |
| Markdown 代码块包裹     |    ✅   |
| `[SILENT] 没啥异常`    | ❌ 正常投递 |
| 包含其他文字             | ❌ 正常投递 |

这确保了"按需打扰"——Agent 只在有实质性信息时才发送消息到 IM 渠道。

## 飞书深度集成

Myrm 对飞书的支持远超基础消息收发——通过内置 SDK 深度集成 6 大能力模块，可直接在对话中操作飞书文档、表格、Wiki 和评论。

### 支持的能力

| 模块          | 能力            | 使用场景                   |
| ----------- | ------------- | ---------------------- |
| Drive Meta  | 文件列表、元数据、权限查询 | "列出共享文件夹中的所有文档"        |
| Docx Blocks | 文档内容块级读写      | "读取会议纪要并提取待办事项"        |
| Comments    | 批量查询、创建、回复评论  | "@AI 在文档评论中提问，AI 自动回复" |
| Wiki        | 知识库节点检索       | "从 Wiki 中查找部署流程文档"     |
| Bitable     | 多维表格记录 CRUD   | "将分析结果写入项目跟踪表"         |
| CardKit     | 卡片消息流式更新      | "发送进度卡片并实时更新状态"        |

### 典型工作流

**场景：读取会议纪要 → 提取待办 → 写入表格**

```
用户：请读取上周项目会议的纪要，提取所有待办事项，写入项目追踪 Bitable
```

Agent 自动执行：

1. 通过 Drive Meta 定位目标文档
2. 使用 Docx Blocks 读取文档全文
3. LLM 分析提取结构化待办（负责人、截止日期、优先级）
4. 通过 Bitable 写入项目追踪表

**场景：文档评论驱动的问答**

当用户在飞书文档中 @AI 评论时：

1. 飞书 WebSocket 实时推送评论事件
2. Agent 读取评论内容 + 文档上下文
3. 生成回复并自动发布到评论区

### 设置方法

1. 进入 **设置 > 渠道 > 飞书**
2. 填写 App ID 和 App Secret
3. 启用 **WebSocket 长连接**（无需公网 IP）
4. 按需开启飞书应用权限：
   * `drive:drive` — 文档读取
   * `wiki:wiki` — Wiki 访问
   * `bitable:bitable` — 表格操作
   * `im:message` — 消息收发
   * `contact:user.id:readonly` — 用户标识

### 企业微信双通道

企业微信提供两种接入方式：

| 模式         | 适用场景   | 特点                    |
| ---------- | ------ | --------------------- |
| 标准 Webhook | 企业自建应用 | 加密验签 + 被动回复 + 主动推送    |
| AI Bot     | 智能客服场景 | 企微官方 AI Bot 协议 + 流式回复 |

两种模式均支持：

* XML 消息加密/解密（AES-CBC）
* 回调签名验证（防伪造）
* 消息去重（防重复处理）

### 微信个人双通道

| 模式    | 协议     | 特点                     |
| ----- | ------ | ---------------------- |
| iLink | 第三方协议层 | 个人号消息收发 + 群聊           |
| 公众号   | 官方 API | 被动回复 + 模板消息 + 草稿箱 HITL |
