# 即时消息桥接

<cite>
**本文档引用的文件**
- [bridge-manager.ts](file://src/lib/im/bridge-manager.ts)
- [channel-router.ts](file://src/lib/im/channel-router.ts)
- [commands.ts](file://src/lib/im/commands.ts)
- [delivery.ts](file://src/lib/im/delivery.ts)
- [conversation-engine.ts](file://src/lib/im/conversation-engine.ts)
- [permission-broker.ts](file://src/lib/im/permission-broker.ts)
- [policy.ts](file://src/lib/im/policy.ts)
- [streaming-state.ts](file://src/lib/im/streaming-state.ts)
- [markdown-ir.ts](file://src/lib/im/markdown-ir.ts)
- [adapters/base.ts](file://src/lib/im/adapters/base.ts)
- [adapters/registry.ts](file://src/lib/im/adapters/registry.ts)
- [adapters/telegram.ts](file://src/lib/im/adapters/telegram.ts)
- [adapters/feishu.ts](file://src/lib/im/adapters/feishu.ts)
- [adapters/discord.ts](file://src/lib/im/adapters/discord.ts)
- [types.ts](file://src/lib/im/types.ts)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排除指南](#故障排除指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本文件为 Forge 的即时消息桥接系统提供综合性技术文档。系统通过“适配器-桥接管理器-路由-对话引擎-投递层”的五层架构，实现对 Telegram、飞书（含 Lark）、Discord 等多平台的统一接入与消息桥接。文档涵盖：
- 多平台适配器实现与差异点
- 桥接管理器的生命周期、重连、并发与流式预览机制
- 会话路由与频道绑定策略
- 命令系统与权限控制
- 消息格式转换、媒体文件处理与速率限制
- 连接测试与故障排除建议
- 扩展新平台的指导

## 项目结构
IM 桥接相关代码集中在 src/lib/im 目录，按层次划分清晰：
- 适配器层（L1）：各平台适配器与注册表
- 桥接管理层（L2）：桥接管理器负责生命周期、轮询、重连、并发与流式状态机
- 路由层（L3）：频道到会话的映射与绑定
- 对话引擎（L4）：调用 SDK 生成回复，消费流并触发回调
- 投递层（L5）：平台特定渲染、分片、去重、速率限制与审计日志

```mermaid
graph TB
subgraph "适配器层(L1)"
A1["TelegramAdapter"]
A2["FeishuAdapter"]
A3["DiscordAdapter"]
AR["AdapterRegistry"]
end
subgraph "桥接管理层(L2)"
BM["BridgeManager"]
PS["PolicyChecker"]
SB["StreamingState"]
PB["PermissionBroker"]
end
subgraph "路由层(L3)"
CR["ChannelRouter"]
end
subgraph "对话引擎(L4)"
CE["ConversationEngine"]
end
subgraph "投递层(L5)"
DL["DeliveryLayer"]
MD["MarkdownIR"]
end
A1 --> BM
A2 --> BM
A3 --> BM
AR --> BM
BM --> CR
BM --> CE
BM --> DL
BM --> PS
BM --> PB
BM --> SB
CE --> DL
DL --> MD
```

图表来源
- [bridge-manager.ts:45-635](file://src/lib/im/bridge-manager.ts#L45-L635)
- [adapters/telegram.ts:44-470](file://src/lib/im/adapters/telegram.ts#L44-L470)
- [adapters/feishu.ts:16-743](file://src/lib/im/adapters/feishu.ts#L16-L743)
- [adapters/discord.ts:29-555](file://src/lib/im/adapters/discord.ts#L29-L555)
- [adapters/registry.ts:11-31](file://src/lib/im/adapters/registry.ts#L11-L31)
- [channel-router.ts:19-232](file://src/lib/im/channel-router.ts#L19-L232)
- [conversation-engine.ts:30-459](file://src/lib/im/conversation-engine.ts#L30-L459)
- [delivery.ts:68-336](file://src/lib/im/delivery.ts#L68-L336)
- [policy.ts:20-89](file://src/lib/im/policy.ts#L20-L89)
- [streaming-state.ts:12-75](file://src/lib/im/streaming-state.ts#L12-L75)
- [permission-broker.ts:25-117](file://src/lib/im/permission-broker.ts#L25-L117)
- [markdown-ir.ts:132-286](file://src/lib/im/markdown-ir.ts#L132-L286)

章节来源
- [bridge-manager.ts:1-635](file://src/lib/im/bridge-manager.ts#L1-L635)
- [adapters/telegram.ts:1-470](file://src/lib/im/adapters/telegram.ts#L1-L470)
- [adapters/feishu.ts:1-743](file://src/lib/im/adapters/feishu.ts#L1-L743)
- [adapters/discord.ts:1-555](file://src/lib/im/adapters/discord.ts#L1-L555)
- [adapters/registry.ts:1-31](file://src/lib/im/adapters/registry.ts#L1-L31)
- [channel-router.ts:1-232](file://src/lib/im/channel-router.ts#L1-L232)
- [conversation-engine.ts:1-459](file://src/lib/im/conversation-engine.ts#L1-L459)
- [delivery.ts:1-336](file://src/lib/im/delivery.ts#L1-L336)
- [policy.ts:1-89](file://src/lib/im/policy.ts#L1-L89)
- [streaming-state.ts:1-75](file://src/lib/im/streaming-state.ts#L1-L75)
- [permission-broker.ts:1-117](file://src/lib/im/permission-broker.ts#L1-L117)
- [markdown-ir.ts:1-286](file://src/lib/im/markdown-ir.ts#L1-L286)
- [types.ts:1-140](file://src/lib/im/types.ts#L1-L140)

## 核心组件
- 桥接管理器（BridgeManager）
  - 统一管理适配器生命周期、轮询循环、重连与指数退避、电路保护
  - 实现并发控制（SDK 调用并发上限）、会话锁、流式预览状态机
  - 触发策略检查、命令解析、会话路由、权限请求、投递与审计
- 通道路由器（ChannelRouter）
  - 将 (channelType, chatId) 映射到会话 ID，支持自动绑定、显式绑定、解绑与会话迁移
  - 提供默认工作区与模型选择逻辑
- 对话引擎（ConversationEngine）
  - 构造 SDK 查询，消费流式响应，触发 onTyping/onDraft/onFinal 回调
  - 支持工具权限决策、附件检测与持久化
- 投递层（DeliveryLayer）
  - 平台特定渲染（MarkdownIR）、消息分片、速率限制（令牌桶）、去重、审计日志
  - 支持编辑、删除、图片/文件投递
- 权限代理（PermissionBroker）
  - 统一发起与回收权限请求，支持超时与跨适配器匹配
- 策略检查（Policy）
  - 基于频道配置的 DM/群组策略、触发模式与白名单控制
- 流式状态机（StreamingState）
  - 控制 typing → draft → final 的流式预览阶段与节流
- Markdown 中间表示（MarkdownIR）
  - 解析与渲染，针对 Telegram/Feishu/ Discord 的格式差异进行保守转换

章节来源
- [bridge-manager.ts:45-635](file://src/lib/im/bridge-manager.ts#L45-L635)
- [channel-router.ts:19-232](file://src/lib/im/channel-router.ts#L19-L232)
- [conversation-engine.ts:30-459](file://src/lib/im/conversation-engine.ts#L30-L459)
- [delivery.ts:68-336](file://src/lib/im/delivery.ts#L68-L336)
- [permission-broker.ts:25-117](file://src/lib/im/permission-broker.ts#L25-L117)
- [policy.ts:20-89](file://src/lib/im/policy.ts#L20-L89)
- [streaming-state.ts:12-75](file://src/lib/im/streaming-state.ts#L12-L75)
- [markdown-ir.ts:132-286](file://src/lib/im/markdown-ir.ts#L132-L286)
- [types.ts:1-140](file://src/lib/im/types.ts#L1-L140)

## 架构总览
下图展示从平台消息到最终投递的完整链路，以及各层之间的交互。

```mermaid
sequenceDiagram
participant Plat as "平台(任一)"
participant Adp as "适配器(L1)"
participant BM as "桥接管理器(L2)"
participant Pol as "策略(L2)"
participant Cmd as "命令解析(L3)"
participant CR as "路由(L3)"
participant Lock as "会话锁(L2)"
participant CE as "对话引擎(L4)"
participant DL as "投递层(L5)"
Plat->>Adp : "推送消息事件"
Adp-->>BM : "consumeOne() 返回消息"
BM->>Pol : "checkPolicy()"
Pol-->>BM : "允许/拒绝"
alt 允许
BM->>Cmd : "parseImCommand()"
alt 是命令
Cmd-->>DL : "deliver() 命令响应"
else 非命令
BM->>CR : "resolveSession()"
CR-->>BM : "sessionId, workspace"
BM->>Lock : "acquire(sessionKey)"
Lock-->>BM : "获取锁"
BM->>CE : "processMessage(...回调...)"
CE-->>BM : "onTyping/onDraft/onFinal"
BM->>DL : "deliver()/deliverImage()/deliverFile()"
DL-->>Plat : "平台消息/附件"
BM->>Lock : "release()"
end
else 拒绝
BM-->>Plat : "忽略"
end
```

图表来源
- [bridge-manager.ts:337-529](file://src/lib/im/bridge-manager.ts#L337-L529)
- [policy.ts:20-89](file://src/lib/im/policy.ts#L20-L89)
- [commands.ts:277-373](file://src/lib/im/commands.ts#L277-L373)
- [channel-router.ts:31-74](file://src/lib/im/channel-router.ts#L31-L74)
- [conversation-engine.ts:40-231](file://src/lib/im/conversation-engine.ts#L40-L231)
- [delivery.ts:78-169](file://src/lib/im/delivery.ts#L78-L169)

## 详细组件分析

### 桥接管理器（BridgeManager）
- 生命周期管理
  - startAdapter：拉取数据库配置、校验、实例化适配器、注册权限回调、启动轮询
  - stopAdapter：停止轮询、关闭适配器、清理权限请求与重连状态
  - autoReconnect：应用启动时并行重连启用的频道
- 轮询与重连
  - runPollLoop：基于适配器 consumeOne 的阻塞等待；异常或断开时进入 handleReconnect
  - handleReconnect：指数退避 + 抖动，连续失败触发电路保护（5 分钟内不再尝试）
- 并发与流式
  - withSdkBackpressure：限制 SDK 并发调用数量
  - StreamingState：typing → draft → final 的流式状态机，避免重复编辑与过度刷新
- 消息处理管线
  - 策略检查 → 命令解析 → 会话解析 → 会话锁 → 对话引擎 → 投递层 → 权限代理 → 审计事件

```mermaid
flowchart TD
S["开始(startAdapter)"] --> V["校验配置(validateConfig)"]
V --> |通过| R["adapter.start()"]
V --> |失败| E1["setState(error)"]
R --> P["启动轮询(runPollLoop)"]
P --> C["consumeOne() 获取消息"]
C --> |null且适配器停止| RC["handleReconnect()"]
C --> |消息| F["策略检查(checkPolicy)"]
F --> |拒绝| X["丢弃"]
F --> |允许| CMD["命令解析(parseImCommand)"]
CMD --> |是命令| D1["executeImCommand()"]
D1 --> DL1["DeliveryLayer.deliver()"]
CMD --> |非命令| SR["resolveSession()"]
SR --> LK["acquire(sessionKey)"]
LK --> CE["ConversationEngine.processMessage()"]
CE --> ST["StreamingState 更新(typing/draft/final)"]
ST --> DL2["DeliveryLayer.deliver()/附件"]
DL2 --> END["释放锁并记录事件"]
```

图表来源
- [bridge-manager.ts:78-144](file://src/lib/im/bridge-manager.ts#L78-L144)
- [bridge-manager.ts:288-328](file://src/lib/im/bridge-manager.ts#L288-L328)
- [bridge-manager.ts:337-529](file://src/lib/im/bridge-manager.ts#L337-L529)
- [streaming-state.ts:12-75](file://src/lib/im/streaming-state.ts#L12-L75)
- [conversation-engine.ts:237-317](file://src/lib/im/conversation-engine.ts#L237-L317)
- [delivery.ts:78-169](file://src/lib/im/delivery.ts#L78-L169)

章节来源
- [bridge-manager.ts:45-635](file://src/lib/im/bridge-manager.ts#L45-L635)

### 通道路由器（ChannelRouter）
- 会话解析优先级
  - 已绑定且会话存在 → 复用
  - 已绑定但会话被删除 → 在同一工作区新建会话并回填
  - 无绑定 → 自动创建并绑定
- 绑定管理
  - bindSession / unbindSession / createNewSession
  - getBindingInfo 用于命令/status 展示
- 默认策略
  - 默认工作区：bridge_default_work_dir → 最近打开工作区
  - 默认模型：bridge_default_model → 未配置则使用默认值

章节来源
- [channel-router.ts:19-232](file://src/lib/im/channel-router.ts#L19-L232)

### 对话引擎（ConversationEngine）
- 输入处理
  - 将图片/文件保存至上传目录，构建消息块（含附件），持久化用户消息
- SDK 调用
  - createForgeQuery 构建查询，支持模型、工作区、权限模式、续聊、中止信号、跳过 MCP 服务器
  - 流式消费：首次事件触发 onTyping，周期性 onDraft，完整响应触发 onFinal
- 附件检测
  - 解析 MEDIA: 协议行与工具使用痕迹（Write/Bash/Read）提取文件路径，去重后回调 onAttachments
- 输出处理
  - 持久化助手消息，更新会话标题与时间戳，后台触发记忆归档与刷新

章节来源
- [conversation-engine.ts:30-459](file://src/lib/im/conversation-engine.ts#L30-L459)

### 投递层（DeliveryLayer）
- 渲染与分片
  - renderForPlatform：Telegram/ Discord/ Feishu 的平台特定渲染
  - chunkMessage：按平台最大长度切分文本
- 速率限制
  - 令牌桶：每聊天每分钟最多 20 条，突发 5
- 去重与审计
  - 基于内容哈希的去重窗口（5 分钟）
  - 审计日志记录发送/编辑/删除/图片/文件等操作
- 二进制投递
  - deliverImage/deliverFile：下载后上传并发送，失败回退为文本提示

章节来源
- [delivery.ts:68-336](file://src/lib/im/delivery.ts#L68-L336)
- [markdown-ir.ts:132-286](file://src/lib/im/markdown-ir.ts#L132-L286)

### 权限代理（PermissionBroker）
- 请求流程
  - requestPermission：发送平台权限 UI，120 秒超时自动拒绝
  - resolvePermission：精确匹配或前缀匹配（适配 Feishu 简短 ID）
- 清理策略
  - cleanupChannel/cleanup：断开适配器或整体关闭时清理挂起请求

章节来源
- [permission-broker.ts:25-117](file://src/lib/im/permission-broker.ts#L25-L117)

### 策略检查（Policy）
- DM 策略
  - disabled：禁用
  - open：开放
  - allowlist/pairing：白名单/配对（当前按白名单处理）
- 群组策略
  - disabled：禁用
  - open：开放
  - allowlist：群组白名单
- 触发模式
  - mention：仅 @ 机器人时处理
- 白名单
  - sender_whitelist/group_whitelist 为 JSON 数组字符串

章节来源
- [policy.ts:20-89](file://src/lib/im/policy.ts#L20-L89)

### 流式状态机（StreamingState）
- 阶段转换：idle → typing → draft → final
- 节流：最小 800ms 更新一次草稿
- 去重：若草稿内容未变化则跳过编辑，避免平台拒绝导致重复发送

章节来源
- [streaming-state.ts:12-75](file://src/lib/im/streaming-state.ts#L12-L75)

### Markdown 中间表示（MarkdownIR）
- 解析：代码块、行内代码、粗体、斜体、链接、标题、换行
- 渲染：
  - Telegram：保留标准 Markdown
  - Discord：原生支持
  - Feishu：简化为纯文本，保留代码块与链接文本

章节来源
- [markdown-ir.ts:132-286](file://src/lib/im/markdown-ir.ts#L132-L286)

### 适配器层（L1）
- 抽象基类（ChannelAdapter）
  - 生命周期：start/stop/isRunning
  - 消费：consumeOne（拉模型，带 AbortSignal）
  - 发送：send/sendImage/sendFile/sendTypingIndicator
  - 权限：sendPermissionPrompt/onPermissionResponse
  - 校验：validateConfig
- 注册表（AdapterRegistry）
  - registerAdapter/createAdapter/getRegisteredTypes
- 平台适配器
  - Telegram：长轮询 getUpdates，支持权限按钮回调、提及识别、媒体下载
  - Feishu：WSClient，mention 匹配（多 ID 类型），简单权限响应，资源下载
  - Discord：Gateway v10，心跳、识别、交互按钮验证（用户匹配）

```mermaid
classDiagram
class ChannelAdapter {
+channelType
+start(config)
+stop()
+isRunning()
+consumeOne(signal)
+send(msg)
+sendImage(chatId,image,caption)
+sendFile(chatId,file,name,caption)
+sendTypingIndicator(chatId)
+sendPermissionPrompt(req)
+onPermissionResponse(cb)
+validateConfig(config)
}
class TelegramAdapter
class FeishuAdapter
class DiscordAdapter
class Registry {
+registerAdapter(type,ctor)
+createAdapter(type)
+getRegisteredTypes()
}
ChannelAdapter <|-- TelegramAdapter
ChannelAdapter <|-- FeishuAdapter
ChannelAdapter <|-- DiscordAdapter
Registry --> TelegramAdapter : "注册"
Registry --> FeishuAdapter : "注册"
Registry --> DiscordAdapter : "注册"
```

图表来源
- [adapters/base.ts:16-101](file://src/lib/im/adapters/base.ts#L16-L101)
- [adapters/telegram.ts:44-470](file://src/lib/im/adapters/telegram.ts#L44-L470)
- [adapters/feishu.ts:16-743](file://src/lib/im/adapters/feishu.ts#L16-L743)
- [adapters/discord.ts:29-555](file://src/lib/im/adapters/discord.ts#L29-L555)
- [adapters/registry.ts:11-31](file://src/lib/im/adapters/registry.ts#L11-L31)

章节来源
- [adapters/base.ts:1-102](file://src/lib/im/adapters/base.ts#L1-L102)
- [adapters/registry.ts:1-31](file://src/lib/im/adapters/registry.ts#L1-L31)
- [adapters/telegram.ts:1-470](file://src/lib/im/adapters/telegram.ts#L1-L470)
- [adapters/feishu.ts:1-743](file://src/lib/im/adapters/feishu.ts#L1-L743)
- [adapters/discord.ts:1-555](file://src/lib/im/adapters/discord.ts#L1-L555)

## 依赖关系分析
- 组件耦合
  - BridgeManager 与各层强耦合：适配器、路由、引擎、投递、策略、权限、流式状态
  - 适配器之间低耦合，通过抽象接口与注册表解耦
- 外部依赖
  - 平台 SDK/HTTP：Telegram API、Feishu SDK、Discord Gateway
  - 数据库：频道、会话、绑定、设置、审计、去重表
- 循环依赖
  - 通过模块导入顺序避免：适配器自注册，桥接管理器按需引入

```mermaid
graph LR
BM["BridgeManager"] --> ADP["适配器集合"]
BM --> CR["ChannelRouter"]
BM --> CE["ConversationEngine"]
BM --> DL["DeliveryLayer"]
BM --> PS["Policy"]
BM --> PB["PermissionBroker"]
BM --> SS["StreamingState"]
CE --> DL
DL --> MD["MarkdownIR"]
```

图表来源
- [bridge-manager.ts:18-35](file://src/lib/im/bridge-manager.ts#L18-L35)
- [conversation-engine.ts:16-26](file://src/lib/im/conversation-engine.ts#L16-L26)
- [delivery.ts:13-17](file://src/lib/im/delivery.ts#L13-L17)
- [markdown-ir.ts:11-17](file://src/lib/im/markdown-ir.ts#L11-L17)

章节来源
- [bridge-manager.ts:1-635](file://src/lib/im/bridge-manager.ts#L1-L635)
- [conversation-engine.ts:1-459](file://src/lib/im/conversation-engine.ts#L1-L459)
- [delivery.ts:1-336](file://src/lib/im/delivery.ts#L1-L336)
- [markdown-ir.ts:1-286](file://src/lib/im/markdown-ir.ts#L1-L286)

## 性能考量
- 并发控制
  - SDK 并发上限：限制同时进行的外部 SDK 调用，避免平台限流与资源争用
- 流式预览节流
  - 草稿最小间隔 800ms，避免频繁编辑导致平台拒绝
- 速率限制
  - 每聊天每分钟最多 20 条，突发 5，定期清理无用桶
- 去重窗口
  - 内容哈希去重，5 分钟 TTL，降低重复消息
- 缓存与降级
  - 适配器内部队列与健康检查（如 Feishu 5 分钟静默判定断开）
- I/O 优化
  - 附件先落盘再复用，减少重复读取
  - 二进制上传失败回退为文本提示，保证消息可达

## 故障排除指南
- 无法连接/频繁断开
  - 检查凭证有效性（validateConfig），查看适配器错误日志
  - 关注桥接管理器的重连日志与电路保护触发
- 消息重复
  - 检查去重表与哈希计算，确认是否为平台重发
  - Feishu/Telegram/Discord 的事件重试机制
- 权限请求无响应
  - 确认权限 UI 是否成功发送，超时（120s）后自动拒绝
  - Feishu 的简单权限响应需匹配发起者 ID
- 编辑失败导致重复消息
  - 平台可能拒绝相同内容的编辑，系统会回退为新消息并清理旧草稿
- 速率受限
  - 检查令牌桶是否耗尽，适当降低发送频率或合并消息
- 命令无效
  - 使用 /help 查看可用命令，注意大小写与参数格式

章节来源
- [bridge-manager.ts:555-601](file://src/lib/im/bridge-manager.ts#L555-L601)
- [delivery.ts:246-276](file://src/lib/im/delivery.ts#L246-L276)
- [permission-broker.ts:66-85](file://src/lib/im/permission-broker.ts#L66-L85)
- [adapters/feishu.ts:674-698](file://src/lib/im/adapters/feishu.ts#L674-L698)
- [adapters/telegram.ts:320-382](file://src/lib/im/adapters/telegram.ts#L320-L382)
- [adapters/discord.ts:461-513](file://src/lib/im/adapters/discord.ts#L461-L513)

## 结论
Forge 的即时消息桥接系统通过清晰的五层架构实现了多平台统一接入与高可靠的消息流转。桥接管理器承担中枢协调职责，结合策略、路由、权限与流式状态机，确保在复杂场景下的稳定性与可扩展性。投递层的平台适配与去重、速率限制保障了用户体验与平台合规。开发者可基于适配器抽象快速扩展新平台，遵循现有模式即可无缝融入整体流程。

## 附录

### 配置与使用要点
- 频道配置
  - 通过数据库表 im_channels 存储 type、credentials、enabled 等字段
  - credentials 为键值字符串，适配器自行解析
- 策略配置
  - dm_policy、group_policy、trigger_mode、group_whitelist、sender_whitelist
- 默认行为
  - bridge_default_work_dir、bridge_default_model、im_permission_mode
- 命令参考
  - /new、/bind、/sessions、/clear、/compact、/projects、/switch、/newproject、/model、/mode、/status、/stop、/help

章节来源
- [types.ts:13-91](file://src/lib/im/types.ts#L13-L91)
- [policy.ts:20-89](file://src/lib/im/policy.ts#L20-L89)
- [channel-router.ts:193-221](file://src/lib/im/channel-router.ts#L193-L221)
- [commands.ts:30-36](file://src/lib/im/commands.ts#L30-L36)

### 平台适配器差异速览
- Telegram
  - 长轮询，支持权限按钮、提及识别、媒体下载
- Feishu
  - WSClient，mention 匹配多 ID，简单权限响应，资源下载
- Discord
  - Gateway v10，心跳与识别，交互按钮验证用户身份

章节来源
- [adapters/telegram.ts:66-98](file://src/lib/im/adapters/telegram.ts#L66-L98)
- [adapters/feishu.ts:53-98](file://src/lib/im/adapters/feishu.ts#L53-L98)
- [adapters/discord.ts:56-70](file://src/lib/im/adapters/discord.ts#L56-L70)