# 桥接架构设计

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

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

## 引言
本文件系统化阐述即时消息桥接架构的设计与实现，重点围绕 BridgeManager 的核心模式：适配器生命周期管理、轮询循环机制、并发控制策略；消息处理流水线从适配器消费消息到最终交付的完整流程；会话锁管理、背压控制与重连机制的技术细节。文档同时给出架构决策权衡、性能优化策略与可扩展性设计建议，并通过多种图示帮助开发者快速理解整体设计。

## 项目结构
即时消息桥接采用五层架构，自下而上分别为：
- L1 适配器层：负责平台特定的连接、消息收发与权限 UI 渲染
- L2 桥接管理层：统一编排、状态管理、轮询循环、并发与背压控制、重连
- L3 路由层：会话解析与绑定，支持自动创建与持久化
- L4 对话引擎：调用 SDK 进行流式对话，回调驱动预览与附件投递
- L5 投递层：速率限制、分片、去重、重试、审计日志与二进制附件投递

```mermaid
graph TB
subgraph "L1 适配器层"
A1["DiscordAdapter<br/>TelegramAdapter<br/>FeishuAdapter"]
end
subgraph "L2 桥接管理层"
B1["BridgeManager<br/>会话锁管理<br/>背压控制<br/>重连策略"]
end
subgraph "L3 路由层"
C1["ChannelRouter<br/>会话解析/绑定"]
end
subgraph "L4 对话引擎"
D1["ConversationEngine<br/>SDK查询/流式消费"]
end
subgraph "L5 投递层"
E1["DeliveryLayer<br/>速率限制/分片/去重/重试"]
end
A1 --> B1
B1 --> C1
C1 --> D1
D1 --> E1
```

**图表来源**
- [bridge-manager.ts:45-611](file://src/lib/im/bridge-manager.ts#L45-L611)
- [base.ts:16-101](file://src/lib/im/adapters/base.ts#L16-L101)
- [discord.ts:29-555](file://src/lib/im/adapters/discord.ts#L29-L555)
- [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)

**章节来源**
- [bridge-manager.ts:1-635](file://src/lib/im/bridge-manager.ts#L1-L635)
- [types.ts:1-140](file://src/lib/im/types.ts#L1-L140)

## 核心组件
- BridgeManager：L2 中枢，负责适配器生命周期、轮询循环、会话锁、背压、重连、事件派发与状态管理
- ChannelAdapter 抽象：L1 平台适配器基类，定义统一的启动/停止、消息消费、发送、权限 UI 接口
- ChannelRouter：L3 会话解析与绑定，支持自动创建、升级旧绑定、持久化
- ConversationEngine：L4 对话引擎，封装 SDK 查询、流式消费、权限请求、结果落库与标题更新
- DeliveryLayer：L5 投递层，实现速率限制、消息分片、去重、重试、审计日志与二进制附件投递
- SessionLockManager：L2 会话级互斥锁，保证同一聊天的串行处理
- PermissionBroker：跨层权限协调，统一弹窗、超时与响应解析
- StreamingState：L2 流式预览状态机，管理 typing/draft/final 生命周期
- Policy：L3 策略检查，支持 DM/群组策略、触发模式与白名单

**章节来源**
- [bridge-manager.ts:45-611](file://src/lib/im/bridge-manager.ts#L45-L611)
- [base.ts:16-101](file://src/lib/im/adapters/base.ts#L16-L101)
- [channel-router.ts:19-232](file://src/lib/im/channel-router.ts#L19-L232)
- [concurrency.ts:8-61](file://src/lib/im/concurrency.ts#L8-L61)
- [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)
- [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)
- [policy.ts:20-89](file://src/lib/im/policy.ts#L20-L89)

## 架构总览
桥接架构采用“拉取式轮询 + 分层职责”的设计，确保各层边界清晰、解耦良好。BridgeManager 作为 L2 协调者，串联 L1-L5 各层，形成稳定的消息处理流水线。

```mermaid
sequenceDiagram
participant A as "适配器(L1)"
participant M as "桥接管理器(L2)"
participant R as "路由(L3)"
participant E as "对话引擎(L4)"
participant D as "投递层(L5)"
A->>M : "consumeOne() 返回消息"
M->>M : "策略检查/命令解析"
alt "是命令"
M->>D : "直接投递命令结果"
else "普通消息"
M->>R : "解析会话"
M->>M : "获取会话锁"
M->>E : "processMessage(回调)"
E-->>M : "onTyping/onDraft/onFinal"
M->>D : "按阶段投递/编辑/删除占位"
M->>M : "释放会话锁"
end
```

**图表来源**
- [bridge-manager.ts:288-529](file://src/lib/im/bridge-manager.ts#L288-L529)
- [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：应用启动时并行重连已启用通道
- 轮询循环
  - startPollLoop：为每个通道创建 AbortController，后台运行 runPollLoop
  - runPollLoop：循环调用 adapter.consumeOne(signal)，处理断开重连、重复消息过滤、异步处理消息
- 重复消息去重
  - 使用 Set 记录最近 5 分钟内的消息 ID，配合定时清理，避免 SDK 重发导致的重复处理
- 会话锁与背压
  - 会话锁：同一 chat 的消息串行处理，避免并发冲突
  - 背压：限制 SDK 调用并发数（默认 3），保护下游服务
- 重连机制
  - 指数退避 + 抖动，最多 60 秒延迟
  - 连续失败超过阈值触发“保险丝”（5 分钟内不再尝试）
  - 针对认证失败等不可恢复错误立即触发保险丝
- 任务取消
  - /stop 命令通过 AbortController 取消当前会话任务，结合超时（5 分钟）保障资源回收

```mermaid
flowchart TD
Start(["开始轮询"]) --> Consume["adapter.consumeOne()"]
Consume --> HasMsg{"收到消息?"}
HasMsg --> |否且适配器停止| Reconnect["handleReconnect()"]
HasMsg --> |否且适配器运行| Loop["继续等待"]
HasMsg --> |是| Dedup{"重复消息?"}
Dedup --> |是| Loop
Dedup --> |否| Process["processMessage()"]
Process --> Done(["完成一轮"])
Reconnect --> Done
```

**图表来源**
- [bridge-manager.ts:278-328](file://src/lib/im/bridge-manager.ts#L278-L328)

**章节来源**
- [bridge-manager.ts:78-183](file://src/lib/im/bridge-manager.ts#L78-L183)
- [bridge-manager.ts:257-328](file://src/lib/im/bridge-manager.ts#L257-L328)
- [bridge-manager.ts:555-601](file://src/lib/im/bridge-manager.ts#L555-L601)

### 适配器抽象与 Discord 实现
- 抽象接口
  - 生命周期：start/stop/isRunning
  - 拉取式消息：consumeOne(signal)
  - 发送能力：send/sendImage/sendFile/sendTypingIndicator
  - 权限 UI：sendPermissionPrompt/onPermissionResponse
  - 配置校验：validateConfig
- Discord 适配器实现要点
  - WebSocket 网关连接、心跳、IDENTIFY/RESUME
  - 内部消息队列与等待器，支持 AbortSignal 中断
  - 权限按钮交互校验（防止他人点击）
  - 附件下载与分类（图片/文件），失败回退纯文本
  - 断线后清理等待器，避免死锁

```mermaid
classDiagram
class ChannelAdapter {
+channelType
+start(config)
+stop()
+isRunning() bool
+consumeOne(signal) IncomingMessage|null
+send(msg) string?
+sendImage(chatId, buffer, caption)
+sendFile(chatId, buffer, filename, caption)
+sendTypingIndicator(chatId)
+sendPermissionPrompt(req)
+onPermissionResponse(cb)
+validateConfig(config) {valid,error?}
}
class DiscordAdapter {
+start(config)
+stop()
+isRunning() bool
+consumeOne(signal) IncomingMessage|null
+send(msg) string?
+sendImage(...)
+sendFile(...)
+sendTypingIndicator(...)
+sendPermissionPrompt(req)
+onPermissionResponse(cb)
+validateConfig(config)
-connectWs(url)
-identify()
-startHeartbeat()
+tryResume() bool
}
ChannelAdapter <|-- DiscordAdapter
```

**图表来源**
- [base.ts:16-101](file://src/lib/im/adapters/base.ts#L16-L101)
- [discord.ts:29-555](file://src/lib/im/adapters/discord.ts#L29-L555)

**章节来源**
- [base.ts:16-101](file://src/lib/im/adapters/base.ts#L16-L101)
- [discord.ts:56-363](file://src/lib/im/adapters/discord.ts#L56-L363)

### 会话路由与绑定
- 优先级策略：已有会话绑定 > 旧版工作区绑定 > 自动创建
- 绑定升级：从仅工作区升级为会话绑定，保证会话持久性
- 默认工作区与模型：支持从设置读取默认工作区与模型
- 命令支持：/new、/bind、/sessions、/status 等

```mermaid
flowchart TD
A["输入消息"] --> B{"是否存在会话绑定?"}
B --> |是| C{"绑定会话仍存在?"}
C --> |是| D["复用会话"]
C --> |否| E["在原工作区创建新会话并升级绑定"]
B --> |否| F["自动创建绑定并创建新会话"]
```

**图表来源**
- [channel-router.ts:31-74](file://src/lib/im/channel-router.ts#L31-L74)

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

### 会话锁管理与并发控制
- 会话锁：以 “channelType:chatId” 为键，使用 Promise 链避免竞态，确保同一聊天串行处理
- 背压：限制 SDK 调用并发数（默认 3），等待队列唤醒策略，避免下游过载

```mermaid
sequenceDiagram
participant M as "BridgeManager"
participant L as "SessionLockManager"
participant E as "ConversationEngine"
M->>L : "acquire(key)"
L-->>M : "返回release()"
M->>E : "processMessage(...)"
E-->>M : "回调 : onTyping/onDraft/onFinal"
M->>L : "release()"
```

**图表来源**
- [concurrency.ts:21-49](file://src/lib/im/concurrency.ts#L21-L49)
- [bridge-manager.ts:390-410](file://src/lib/im/bridge-manager.ts#L390-L410)

**章节来源**
- [concurrency.ts:8-61](file://src/lib/im/concurrency.ts#L8-L61)
- [bridge-manager.ts:390-410](file://src/lib/im/bridge-manager.ts#L390-L410)

### 对话引擎与流式处理
- SDK 查询：构建 createForgeQuery，支持跳过 MCP 服务器减少启动开销
- 流式消费：首次事件触发打字指示，周期性回调草稿文本，最终回调完整文本
- 附件检测：解析 MEDIA: 协议与工具使用痕迹，合并去重后投递
- 权限模式：支持 confirm（需要确认）与 full（自动放行），动态注入 canUseTool 回调
- 会话冲突处理：若 SDK 报告会话 ID 已占用，自动重试并生成新 SDK 会话

```mermaid
sequenceDiagram
participant M as "BridgeManager"
participant E as "ConversationEngine"
participant S as "SDK"
participant D as "DeliveryLayer"
M->>E : "processMessage(msg, sessionId, workspace, callbacks)"
E->>S : "createForgeQuery(...)"
S-->>E : "stream events"
E-->>M : "onTyping()"
M->>D : "投递打字指示/占位"
E-->>M : "onDraft(text)"
M->>D : "编辑草稿/发送草稿"
E-->>M : "onFinal(text)"
M->>D : "编辑/发送最终文本"
E-->>M : "onAttachments(files)"
M->>D : "投递图片/文件"
```

**图表来源**
- [conversation-engine.ts:40-231](file://src/lib/im/conversation-engine.ts#L40-L231)
- [bridge-manager.ts:407-492](file://src/lib/im/bridge-manager.ts#L407-L492)
- [delivery.ts:78-169](file://src/lib/im/delivery.ts#L78-L169)

**章节来源**
- [conversation-engine.ts:30-459](file://src/lib/im/conversation-engine.ts#L30-L459)
- [bridge-manager.ts:407-492](file://src/lib/im/bridge-manager.ts#L407-L492)

### 投递层：速率限制、分片、去重与重试
- 令牌桶：每通道每平台 20 条/分钟，突发 5，定期清理过期桶
- 平台分片：按最大长度切分，优先在换行处分割
- 去重：基于内容哈希（SHA-256 截断）+ TTL（5 分钟）
- 重试：指数退避（最多 3 次），失败记录审计日志
- 审计：记录发送/编辑/删除/发送图片/发送文件等操作
- 二进制：图片/文件专用投递方法，失败回退文本描述

```mermaid
flowchart TD
A["待投递文本"] --> B["渲染平台 Markdown"]
B --> C{"是否编辑?"}
C --> |是| D["尝试编辑"]
D --> |失败| E["发送新消息"]
D --> |成功| F["记录审计"]
C --> |否| E
E --> G["分片(按平台最大长度)"]
G --> H["逐片去重检查"]
H --> I["令牌桶获取"]
I --> J["重试发送(指数退避)"]
J --> K["记录审计/跟踪引用"]
```

**图表来源**
- [delivery.ts:78-327](file://src/lib/im/delivery.ts#L78-L327)

**章节来源**
- [delivery.ts:68-336](file://src/lib/im/delivery.ts#L68-L336)

### 权限协调与安全
- PermissionBroker：集中管理权限请求，超时自动拒绝，支持精确匹配与前缀匹配（适配飞书短 ID）
- 适配器回调：当用户点击允许/拒绝时，适配器回调 BridgeManager，再由 Broker 解析并恢复对应 Promise
- 安全增强：Discord 侧校验按钮点击者与原始消息发送者一致，防止越权

**章节来源**
- [permission-broker.ts:25-117](file://src/lib/im/permission-broker.ts#L25-L117)
- [discord.ts:461-513](file://src/lib/im/adapters/discord.ts#L461-L513)

### 策略与命令
- 策略检查：支持 DM/群组策略、触发模式（提及）、白名单
- 命令解析：/new、/bind、/sessions、/clear、/compact、/projects、/switch、/newproject、/model、/mode、/status、/stop、/help
- 未知命令提示：智能拼写建议，引导用户使用 /help

**章节来源**
- [policy.ts:20-89](file://src/lib/im/policy.ts#L20-L89)
- [commands.ts:277-373](file://src/lib/im/commands.ts#L277-L373)

## 依赖关系分析
- 组件耦合
  - BridgeManager 依赖 L1/L3/L4/L5 的接口契约，通过类型与回调解耦
  - 会话锁与背压在 L2 内聚，避免扩散到其他层
  - 投递层对平台差异进行封装，向上暴露统一接口
- 外部依赖
  - 数据库：通道状态、会话绑定、审计日志、去重表、设置项
  - SDK：Claude Agent SDK，流式消费与工具调用
  - 文件系统：上传目录用于附件缓存与投递

```mermaid
graph LR
BM["BridgeManager"] --> AD["Adapter(多实现)"]
BM --> CR["ChannelRouter"]
BM --> CE["ConversationEngine"]
BM --> DL["DeliveryLayer"]
CE --> SDK["Forge SDK"]
DL --> DB["数据库"]
CE --> FS["文件系统"]
```

**图表来源**
- [bridge-manager.ts:51-56](file://src/lib/im/bridge-manager.ts#L51-L56)
- [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)

**章节来源**
- [bridge-manager.ts:51-56](file://src/lib/im/bridge-manager.ts#L51-L56)
- [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)

## 性能考量
- 并发控制
  - 会话锁：避免同一聊天并发处理，降低数据竞争风险
  - SDK 背压：限制并发调用，防止下游过载
- 轮询与 I/O
  - 拉取式轮询 + AbortSignal 支持中断，避免阻塞
  - 适配器内部队列 + 等待器，提升吞吐
- 缓存与去重
  - 重复消息 ID 去重 + 定时清理，减少重复处理
  - 投递去重基于内容哈希，避免重复发送
- 速率限制
  - 令牌桶按通道/平台限速，避免平台限流
- I/O 优化
  - 投递前分片，减少单次发送大小
  - 附件落地一次，后续复用路径，避免重复写入

[本节为通用性能指导，无需特定文件引用]

## 故障排查指南
- 适配器断线
  - 现象：轮询循环捕获异常并触发重连
  - 排查：检查网络、凭证有效性、平台限流
  - 处理：指数退避 + 保险丝（连续失败 5 次以上暂停 5 分钟）
- 会话锁堆积
  - 现象：消息处理延迟增大
  - 排查：确认是否有长时间运行的任务未释放锁
  - 处理：使用 /stop 命令取消任务，或等待超时（5 分钟）
- 权限请求超时
  - 现象：120 秒后自动拒绝
  - 排查：适配器是否正确回调 resolvePermission
  - 处理：检查平台按钮交互与回调链路
- 投递失败
  - 现象：编辑失败回退为新消息，或发送失败重试
  - 排查：平台限流、内容长度、去重冲突
  - 处理：查看审计日志与重试记录

**章节来源**
- [bridge-manager.ts:555-601](file://src/lib/im/bridge-manager.ts#L555-L601)
- [permission-broker.ts:66-85](file://src/lib/im/permission-broker.ts#L66-L85)
- [delivery.ts:223-240](file://src/lib/im/delivery.ts#L223-L240)

## 结论
该桥接架构通过清晰的分层与严格的职责划分，实现了高可靠、可扩展的即时消息处理体系。BridgeManager 作为中枢，有效平衡了并发、背压与重连等复杂性；L3/L4/L5 层分别承担会话语义、对话逻辑与交付细节，既保证了业务灵活性，也确保了平台兼容性与用户体验。通过策略、权限与审计等横切能力的模块化设计，系统在安全性与可观测性方面同样具备良好基础。