chenbhao Claude Big Pickle commited on
Commit
762b1c8
·
1 Parent(s): 9004edd

chore: docs v1.2 — add debug system, feishu integration; update swarm, tavily, provider auth

Browse files

New docs:
- docs/cli/debug-system.md — /debug v2.0 DEBUG PROBE workflow, session debug logging
- docs/services/feishu.md — Feishu/Lark bot architecture, access control, TTS

Updated docs:
- docs/coordinator/multi-agent.md — Agent Teams (Swarm topology), Fork Subagent
- docs/tools/overview.md — WebSearch dual-backend (Tavily vs SearXNG)
- docs/architecture/provider-auth.md — OpenCode Zen free models, NVIDIA sidecar
- docs/friend/voice-vad.md — noise suppression, FriendService stricter threshold
- docs/services/overview.md — condensed feishu section to point to new doc
- docs/README.md — index updated with all new entries

Co-Authored-By: Claude Big Pickle <noreply@anthropic.com>

docs/README.md CHANGED
@@ -20,7 +20,8 @@
20
  |------|------|
21
  | [CLI 命令系统](cli/overview.md) | 命令注册、Slash 命令大全 (~75+)、Skill/工作流系统 |
22
  | [构建系统与功能标记](cli/build-system.md) | 676 行 | Bun 构建管道、48 个 feature flag、死代码消除、命令可用性门控 |
23
- | [AI 工具系统](tools/overview.md) | buildTool 框架、执行权限系统、关键工具详解 |
 
24
  | [工具参考大全](tools/tool-reference.md) | 所有 ~60+ AI 工具的完整参考表 |
25
 
26
  ### Friend VRM 伴侣
@@ -53,13 +54,14 @@
53
  | 文档 | 说明 |
54
  |------|------|
55
  | [服务总览](services/overview.md) | MCP、上下文压缩、Auto Dream、飞书/Telegram |
 
56
  | [上下文压缩深度解析](services/compact-deep-dive.md) | 906 行 | 5 层压缩管线、Budget Reduction、Snip、Microcompact、Context Collapse、Auto-compact |
57
 
58
  ### 协调与自动化
59
  | 文档 | 说明 |
60
  |------|------|
61
  | [目标与自动模式](coordinator/goals-auto-mode.md) | Goal 系统、Auto Mode、查询循环、Task 系统 |
62
- | [多代理协调](coordinator/multi-agent.md) | Coordinator 模式、Worker 派发、并行策略 |
63
 
64
  ### 远程桥接
65
  | 文档 | 说明 |
 
20
  |------|------|
21
  | [CLI 命令系统](cli/overview.md) | 命令注册、Slash 命令大全 (~75+)、Skill/工作流系统 |
22
  | [构建系统与功能标记](cli/build-system.md) | 676 行 | Bun 构建管道、48 个 feature flag、死代码消除、命令可用性门控 |
23
+ | [调试系统](cli/debug-system.md) | `/debug` v2.0 DEBUG PROBE 工作流、会话调试日志 |
24
+ | [AI 工具系统](tools/overview.md) | buildTool 框架、执行流程、权限系统、关键工具详解(含 Tavily/SearXNG) |
25
  | [工具参考大全](tools/tool-reference.md) | 所有 ~60+ AI 工具的完整参考表 |
26
 
27
  ### Friend VRM 伴侣
 
54
  | 文档 | 说明 |
55
  |------|------|
56
  | [服务总览](services/overview.md) | MCP、上下文压缩、Auto Dream、飞书/Telegram |
57
+ | [飞书集成](services/feishu.md) | 飞书/Lark 机器人架构、访问控制、语音回复、配置 |
58
  | [上下文压缩深度解析](services/compact-deep-dive.md) | 906 行 | 5 层压缩管线、Budget Reduction、Snip、Microcompact、Context Collapse、Auto-compact |
59
 
60
  ### 协调与自动化
61
  | 文档 | 说明 |
62
  |------|------|
63
  | [目标与自动模式](coordinator/goals-auto-mode.md) | Goal 系统、Auto Mode、查询循环、Task 系统 |
64
+ | [多代理协调](coordinator/multi-agent.md) | Coordinator 模式、Worker 派发、Agent Teams Swarm、Fork Subagent |
65
 
66
  ### 远程桥接
67
  | 文档 | 说明 |
docs/architecture/provider-auth.md CHANGED
@@ -313,20 +313,23 @@ function shouldUseDeepSeekReasoningCompat(baseUrl: string): boolean {
313
  - **端点**: `{baseUrl}/v1/chat/completions` (默认 `https://integrate.api.nvidia.com/v1`)
314
  - **Model 列表**: 从 `/v1/models` 动态拉取,缓存于 `cachedNvidiaModels` 模块变量
315
  - **默认 Model**: `nvidia/llama-3.1-nemotron-70b-instruct` (可通过 `NVIDIA_MODEL` 环境变量覆盖)
 
316
 
317
  ### 4.2 OpenCode Zen
318
 
319
  **文件**: `src/services/api/opencodeClient.ts`
320
 
321
  - **认证**: 支持 API Key 和匿名免费使用
322
- - **免费模式**: 当 `apiKey` 为 `undefined` 或 `'public'` 时,注入 billing 特征码 (x-anthropic-billing-header)
323
  - **端点**: `https://opencode.ai/zen/v1/chat/completions`
324
  - **Model 发现**:
325
- - 从 `https://models.dev/api.json` 动态获取模型元数据 (云端成本策略)
326
  - 从 `https://api.github.com/repos/anomalyco/opencode/releases/latest` 获取版本信息
327
  - 缓存于 `cachedModels` 模块变量
 
328
  - **动态 UA**: 根据版本和运行时自动构建 `User-Agent`
329
  - **推理内容**: 支持 `reasoning_content` 到 `thinking` block 的转换
 
330
 
331
  ### 4.3 OpenAI / Codex Official
332
 
 
313
  - **端点**: `{baseUrl}/v1/chat/completions` (默认 `https://integrate.api.nvidia.com/v1`)
314
  - **Model 列表**: 从 `/v1/models` 动态拉取,缓存于 `cachedNvidiaModels` 模块变量
315
  - **默认 Model**: `nvidia/llama-3.1-nemotron-70b-instruct` (可通过 `NVIDIA_MODEL` 环境变量覆盖)
316
+ - **网络架构**: 通过 Sidecar 代理转发(`/api/proxy/nvidia`),适用于需要特殊头或 CORS 处理的 Provider。与之对比,OpenCode/OpenRouter 使用直接 Fetch Override 模式。
317
 
318
  ### 4.2 OpenCode Zen
319
 
320
  **文件**: `src/services/api/opencodeClient.ts`
321
 
322
  - **认证**: 支持 API Key 和匿名免费使用
323
+ - **免费模式**: 当 `apiKey` 为 `undefined` 或 `'public'` 时,注入 billing 特征码 (`x-anthropic-billing-header: cc_version=2.1.0-dev...`),标记请求来源用于服务端路由
324
  - **端点**: `https://opencode.ai/zen/v1/chat/completions`
325
  - **Model 发现**:
326
+ - 从 `https://models.dev/api.json` 动态获取模型元数据云端成本策略
327
  - 从 `https://api.github.com/repos/anomalyco/opencode/releases/latest` 获取版本信息
328
  - 缓存于 `cachedModels` 模块变量
329
+ - 支持免费模型列表过滤(life-free models)
330
  - **动态 UA**: 根据版本和运行时自动构建 `User-Agent`
331
  - **推理内容**: 支持 `reasoning_content` 到 `thinking` block 的转换
332
+ - **网络架构**: 直连模式(Direct Fetch Override),无需 Sidecar 代理
333
 
334
  ### 4.3 OpenAI / Codex Official
335
 
docs/cli/debug-system.md ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 调试系统
2
+
3
+ ## 概述
4
+
5
+ VersperClaw 提供两层调试能力:
6
+
7
+ 1. **会话级调试日志** — 基于 `logForDebugging()` 的持久化日志系统,用于内部诊断
8
+ 2. **`/debug` 交互式调试** — 基于 DEBUG PROBE 的主动式调试工作流(v2.0)
9
+
10
+ ---
11
+
12
+ ## 1. 会话调试日志
13
+
14
+ ### 基础用法
15
+
16
+ 通过 CLI 标志启用:
17
+
18
+ ```bash
19
+ claude --debug # 启用调试日志
20
+ claude --debug=api,hooks # 按分类过滤
21
+ claude -d # 简写
22
+ claude --debug-file=/tmp/debug.log # 自定义日志路径
23
+ claude --debug-to-stderr # 输出到 stderr
24
+ ```
25
+
26
+ 环境变量:
27
+
28
+ | 变量 | 说明 |
29
+ |------|------|
30
+ | `DEBUG` / `DEBUG_SDK` | 启用调试模式 |
31
+ | `CLAUDE_CODE_DEBUG_LOG_LEVEL` | 最低级别:`verbose`, `debug`, `info`, `warn`, `error` |
32
+ | `CLAUDE_CODE_DEBUG_LOGS_DIR` | 自定义日志目录 |
33
+
34
+ ### 日志位置
35
+
36
+ 默认路径:`~/.claude/debug/<sessionId>.txt`
37
+
38
+ `latest` 符号链接总是指向最新会话的日志文件。
39
+
40
+ ### 核心文件
41
+
42
+ | 文件 | 职责 |
43
+ |------|------|
44
+ | `src/utils/debug.ts` | `logForDebugging()`, `isDebugMode()`, `enableDebugLogging()`, `getDebugLogPath()` |
45
+ | `src/utils/debugFilter.ts` | 分类过滤:`parseDebugFilter()`, `shouldShowDebugMessage()` |
46
+ | `src/utils/bufferedWriter.ts` | 缓冲写入器,批量写入日志 |
47
+
48
+ `logForDebugging()` 在代码库中 250+ 个文件中使用。
49
+
50
+ ---
51
+
52
+ ## 2. `/debug` 交互式调试(v2.0)
53
+
54
+ ### 架构
55
+
56
+ ```
57
+ 用户输入 /debug <bug描述>
58
+
59
+
60
+ debug.ts (bundled skill)
61
+
62
+
63
+ 8 步 CHECKPOINT 工作流注入模型上下文
64
+
65
+
66
+ 模型自动执行:分析 → 插探针 → 复现 → 分析日志 → 修复 → 验证 → 清理
67
+
68
+
69
+ DebugSessionTool — 管理 .versperclaw-debug/ 目录
70
+ ```
71
+
72
+ ### 与 v1 的区别
73
+
74
+ | 方面 | v1(旧) | v2.0(当前) |
75
+ |------|---------|-------------|
76
+ | 方式 | 被动读取调试日志 | 主动插入探针 |
77
+ | 数据源 | `~/.claude/debug/*.txt` | `.versperclaw-debug/debug.log` |
78
+ | 模型角色 | 分析已有日志 | 插桩 → 复现 → 分析 → 修复 |
79
+ | 工作流 | 无结构化步骤 | 8 步 CHECKPOINT |
80
+
81
+ ### 8 步 CHECKPOINT 工作流
82
+
83
+ | 步骤 | 操作 |
84
+ |------|------|
85
+ | **Step 0: Triage** | 确认 bug 报告完整(预期/实际/复现步骤/一致性/错误) |
86
+ | **Step 1: Plan Probes** | 阅读代码,形成 2-3 个假设,输出探针插入计划表 |
87
+ | **Step 2: Init Session** | 调用 `DebugSession({ action: "init" })` 创建 `.versperclaw-debug/` |
88
+ | **Step 3: Insert Probes** | 用 Edit 插入 `DEBUG PROBE [N]` / `DEBUG PROBE END [N]` 代码块 |
89
+ | **Step 4: Reproduce & Log** | 调用 `DebugSession begin_run`,运行复现命令,通过 `read_log` 收集 |
90
+ | **Step 5: Analyze** | 引用日志行,定位根因 |
91
+ | **Step 6: Fix & Verify** | 修复后调用 `begin_verify`,重跑,对比日志 |
92
+ | **Step 7: Cleanup** | 删除所有探针,Grep 确认清理,调用 `DebugSession cleanup` |
93
+ | **Final** | 总结根因、证据、修复、验证、清理 |
94
+
95
+ ### DEBUG PROBE 格式
96
+
97
+ ```typescript
98
+ // DEBUG PROBE [1] <label>
99
+ try {
100
+ require('fs').appendFileSync('.versperclaw-debug/debug.log',
101
+ `[${new Date().toISOString()}] [js] file.ts:42 | label | value=${JSON.stringify(value)}\n`)
102
+ } catch {}
103
+ // DEBUG PROBE END [1]
104
+ ```
105
+
106
+ 规则:
107
+ - 探针必须是**只观察不修改**的
108
+ - 每个探针有唯一编号 `[N]` 和匹配的 START/END 标记
109
+ - 每种语言的探针模板不同(JS/TS、Python、Go、Rust)
110
+ - 最多 3 轮探针迭代
111
+ - 必须在最终回复前完全清理
112
+
113
+ ### DebugSession 工具
114
+
115
+ 工具名:`DebugSession`
116
+
117
+ 可用动作:
118
+
119
+ | 动作 | 说明 |
120
+ |------|------|
121
+ | `init` | 创建 `.versperclaw-debug/` 目录、`debug.log`、`state` 文件 |
122
+ | `begin_run` | 追加 `RUN #N` 分隔符,递增运行计数器 |
123
+ | `begin_verify` | 追加 `VERIFY` 分隔符 |
124
+ | `read_log` | 读取 `debug.log` 尾部内容 |
125
+ | `cleanup` | 删除 `.versperclaw-debug/` 目录 |
126
+
127
+ ### 目录结构
128
+
129
+ ```
130
+ .versperclaw-debug/
131
+ debug.log -- 探针写入 + RUN/VERIFY 分隔符
132
+ state -- JSON: { "runCount": 3 }
133
+ ```
134
+
135
+ ### 核心文件
136
+
137
+ | 文件 | 职责 |
138
+ |------|------|
139
+ | `src/skills/bundled/debug.ts` | `/debug` skill 定义,8 步工作流提示词,探针模板 |
140
+ | `src/tools/DebugSessionTool.ts` | DebugSession 工具实现 |
141
+ | `src/utils/debug.ts` | 通用调试日志基础设施 |
142
+ | `src/commands/debug-tool-call/index.js` | 遗留桩命令(`isEnabled: false`) |
docs/coordinator/multi-agent.md CHANGED
@@ -203,3 +203,141 @@ AgentTool({ prompt: "Based on your findings, implement the fix" }) // 错误:
203
  ### 停止 Worker
204
 
205
  使用 `TaskStopTool` 停止方向错误的 Worker。已停止的 Worker 可通过 `SendMessageTool` 继续。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  ### 停止 Worker
204
 
205
  使用 `TaskStopTool` 停止方向错误的 Worker。已停止的 Worker 可通过 `SendMessageTool` 继续。
206
+
207
+ ---
208
+
209
+ ## Agent Teams(Swarm 拓扑)
210
+
211
+ ### 概述
212
+
213
+ Agent Teams(Swarm 模式)是 VersperClaw 的多 Agent 拓扑模型,通过 `feature('AGENT_SWARMS')` 编译期标记门控。与 Coordinator/Worker 模式不同,Teams 采用**文件系统邮箱通信**,每个 Agent 在独立进程中运行(tmux split-pane / in-process)。
214
+
215
+ ### 激活方式
216
+
217
+ ```bash
218
+ export CLAUDE_CODE_AGENT_SWARMS=1
219
+ ```
220
+
221
+ ### 核心架构
222
+
223
+ ```
224
+ Team Lead (AgentTool team_name="my-team" name="lead")
225
+
226
+ ├── AgentTool(name="researcher", team_name="my-team") → tmux pane / in-process
227
+ │ └── 邮箱: ~/.claude/teams/my-team/mailbox/researcher/
228
+
229
+ ├── AgentTool(name="coder", team_name="my-team") → tmux pane / in-process
230
+ │ └── 邮箱: ~/.claude/teams/my-team/mailbox/coder/
231
+
232
+ └── AgentTool(name="reviewer", team_name="my-team") → tmux pane / in-process
233
+ └── 邮箱: ~/.claude/teams/my-team/mailbox/reviewer/
234
+ ```
235
+
236
+ ### 与 Coordinator/Worker 的区别
237
+
238
+ | 维度 | Coordinator/Worker | Agent Teams (Swarm) |
239
+ |------|-------------------|---------------------|
240
+ | 通信 | `<task-notification>` XML 消息 | 文件系统邮箱(mailbox) |
241
+ | 进程 | 同进程 | 独立 OS 进程(tmux / in-process) |
242
+ | 生命周期 | 单次任务 | 持久化团队 |
243
+ | 隔离度 | 共享上下文 | AsyncLocalStorage(in-process)或完全隔离 |
244
+ | 工具白名单 | 统一限制 | 可配置 agent_type → 自定义工具集 |
245
+ | 嵌套 | Coordinator 可 spawn worker | **禁止**团队成员 spawn 子代(仅 team lead 可) |
246
+
247
+ ### 团队创建流程
248
+
249
+ 1. **创建团队**: `TeamCreateTool({ name: "my-team" })` → 生成 `~/.claude/teams/my-team/config.json`
250
+ 2. **设置 Leader**: 当前会话自动成为 team-lead
251
+ 3. **派发成员**: `AgentTool({ name: "researcher", team_name: "my-team", prompt: "..." })`
252
+ 4. **后台抉择**:
253
+ - In-process(启用时)→ 同一进程 AsyncLocalStorage 隔离
254
+ - tmux split-pane(默认)→ 新 tmux 窗格
255
+ - tmux separate-window → 新 tmux 窗口
256
+ - iTerm2 native → macOS 原生分屏
257
+ 5. **通信**: 成员写入 `mailbox/{agent-name}/`,lead 轮询读取
258
+
259
+ ### 邮箱通信格式
260
+
261
+ ```json
262
+ {
263
+ "from": "researcher",
264
+ "text": "研究发现...",
265
+ "timestamp": 1712345678000
266
+ }
267
+ ```
268
+
269
+ ### 团队成员配置
270
+
271
+ 自定义 Agent 定义(`~/.claude/agents/`):
272
+
273
+ ```json
274
+ {
275
+ "name": "researcher",
276
+ "tools": ["BashTool", "ReadTool", "GrepTool", "GlobTool"],
277
+ "model": "claude-sonnet-4-20250514"
278
+ }
279
+ ```
280
+
281
+ ### 关键文件
282
+
283
+ | 文件 | 职责 |
284
+ |------|------|
285
+ | `src/tools/AgentTool/AgentTool.tsx` | 统一调度入口(Line 262-316 为团队路径) |
286
+ | `src/tools/shared/spawnMultiAgent.ts` | 三种 spawn 后端实现(1105 行) |
287
+ | `src/tools/TeamCreateTool/TeamCreateTool.ts` | 团队创建 + 任务列表重置 |
288
+ | `src/tools/TeamDeleteTool/TeamDeleteTool.ts` | 团队清理 + 活跃成员验证 |
289
+ | `src/utils/swarm/teamHelpers.ts` | TeamFile 类型、文件锁、清理 |
290
+ | `src/utils/swarm/inProcessRunner.ts` | 同进程 teammate 生命周期(1553 行) |
291
+ | `src/utils/swarm/teammateInit.ts` | Stop hook、路径白名单 |
292
+ | `src/utils/swarm/constants.ts` | `TEAM_LEAD_NAME`, `SWARM_SESSION_NAME` |
293
+
294
+ ### Spawn 后端对比
295
+
296
+ | 后端 | 隔离 | 优点 | 缺点 |
297
+ |------|------|------|------|
298
+ | tmux split-pane | 完整进程隔离 | 可视化管理,可独立 kill | 需要 tmux |
299
+ | tmux separate-window | 完整进程隔离 | 传统方式 | UI 不够紧凑 |
300
+ | iTerm2 native | 完整进程隔离 | macOS 原生集成 | 仅 macOS |
301
+ | In-process | AsyncLocalStorage | 无需终端,快速 | 共享进程,有限隔离 |
302
+
303
+ ### 清理机制
304
+
305
+ - `cleanupSessionTeams()` 在 SIGINT/SIGTERM 时自动执行
306
+ - 终止所有团队成员窗格
307
+ - 清理团队目录和任务目录
308
+ - 文件锁防止并发竞争
309
+
310
+ ### Forbidden 规则
311
+
312
+ Agent 工具过滤(`filterToolsForAgent()`):
313
+
314
+ 1. MCP 工具(`mcp__*`)始终保留
315
+ 2. `ALL_AGENT_DISALLOWED_TOOLS` 从所有 Agent 移除
316
+ 3. `CUSTOM_AGENT_DISALLOWED_TOOLS` 额外从非内置 Agent 移除
317
+ 4. `ASYNC_AGENT_ALLOWED_TOOLS` 异步 Agent 仅允许白名单工具
318
+
319
+ ---
320
+
321
+ ## Fork Subagent(实验性)
322
+
323
+ ### 概述
324
+
325
+ 通过 `feature('FORK_SUBAGENT')` 门控,提供另一种 Agent 拓扑:子 Agent **继承父会话的全部上下文**。
326
+
327
+ ### 关键特性
328
+
329
+ - **上下文继承**: 子 Agent 从父会话的完整历史开始
330
+ - **字节级缓存优化**: 所有 fork 共享相同 API 前缀(字节一致),提高 prompt 缓存命中
331
+ - **权限冒泡**: `permissionMode: 'bubble'` — 权限提示冒泡到父终端
332
+ - **强制异步**: 所有 fork spawn 必须异步执行
333
+
334
+ ### 适用场景
335
+
336
+ - 需要子 Agent 拥有完整对话上下文时
337
+ - 希望复用父会话的 prompt 缓存
338
+
339
+ ### 核心文件
340
+
341
+ | 文件 | 职责 |
342
+ |------|------|
343
+ | `src/tools/AgentTool/forkSubagent.ts` | `buildForkedMessages()` 构建字节相同前缀 |
docs/friend/voice-vad.md CHANGED
@@ -223,9 +223,9 @@ this.opts = {
223
  };
224
  ```
225
 
226
- ### 3.4 RMS 能量预过滤
227
 
228
- 在运行 ONNX 推理之前,先计算帧的 RMS 能量:
229
 
230
  ```typescript
231
  let sumSq = 0;
@@ -244,9 +244,11 @@ if (rms < this.opts.rmsThreshold) {
244
 
245
  作用:
246
  - 节省 CPU 资源(大量帧无语音信号)
247
- - 过滤机械噪声/麦克风碰撞/环境静音
248
  - 降低误触发率
249
 
 
 
250
  ### 3.5 状态机详解
251
 
252
  ```
 
223
  };
224
  ```
225
 
226
+ ### 3.4 RMS 能量预过滤(噪声抑制)
227
 
228
+ RMS 预过滤是 VAD 的**第一道噪声防线**。在运行 ONNX 推理之前,先计算帧的 RMS 能量:
229
 
230
  ```typescript
231
  let sumSq = 0;
 
244
 
245
  作用:
246
  - 节省 CPU 资源(大量帧无语音信号)
247
+ - 过滤机械噪声/麦克风碰撞/环境静音(噪声抑制)
248
  - 降低误触发率
249
 
250
+ 注:FriendService 中使用更严格的阈值 `0.01`(-40dBFS)而非 SileroVAD 的默认 `0.004`,以减少非语音噪音造成的误触发。
251
+
252
  ### 3.5 状态机详解
253
 
254
  ```
docs/services/feishu.md ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 飞书(Feishu/Lark)机器人集成
2
+
3
+ ## 概述
4
+
5
+ VersperClaw 内置飞书(国内版)和 Lark(国际版)机器人集成,允许用户在即时通讯中与 AI CLI 进行对话。机器人通过 `@larksuite/channel` SDK 建立长连接 WebSocket,支持私聊、群聊、语音回复、引用回复等功能。
6
+
7
+ ---
8
+
9
+ ## 架构
10
+
11
+ ```
12
+ Feishu WebSocket (LarkChannel)
13
+
14
+
15
+ FeishuService (singleton)
16
+ ├── PendingQueue (600ms 去抖)
17
+ ├── Access Control (DM/Group 策略)
18
+ ├── Slash Command Router (/stop, /reset, /status, /help)
19
+ ├── Quoted Context Fetcher
20
+ └── TTS Engine (Edge TTS / VoxCPM)
21
+
22
+
23
+ messageQueueManager.enqueue()
24
+ └── origin: { kind: 'channel', server: 'feishu' }
25
+
26
+
27
+ useFeishuBridge (React hook)
28
+ ├── 收集 AI 回复
29
+ └── sendMarkdown() / sendVoice() 返回飞书
30
+ ```
31
+
32
+ ---
33
+
34
+ ## 连接方式
35
+
36
+ 采用 **WebSocket 长连接**(非 Webhook),基于 `@larksuite/channel` 包:
37
+
38
+ - **国内版**: `https://open.feishu.cn`
39
+ - **国际版 (Lark)**: `https://open.larksuite.com`
40
+ - 通过配置中的 `tenant` 字段选择端点(`'lark'` 使用国际版)
41
+
42
+ ### Channel 配置
43
+
44
+ | 参数 | 默认值 | 说明 |
45
+ |------|--------|------|
46
+ | `respectProxyEnv` | `true` | 遵循 `HTTP_PROXY`/`HTTPS_PROXY` |
47
+ | `pingTimeout` | `3` | SDK ping 看门狗 |
48
+ | `handshakeTimeoutMs` | `8000` | 连接握手超时 |
49
+ | `httpTimeoutMs` | `30000` | API 调用超时 |
50
+ | `policy.dmMode` | `'open'` | SDK 级 DM 策略(上层另有自定义) |
51
+ | `safety.chatQueue.enabled` | `false` | 禁用 SDK 内部队列,使用自定义 PendingQueue |
52
+
53
+ ### 生命周期事件
54
+
55
+ - `message` — 收到消息
56
+ - `error` — 连接错误
57
+ - `reconnecting` — 重连中
58
+ - `reconnected` — 重连成功
59
+
60
+ ---
61
+
62
+ ## 消息处理流水线
63
+
64
+ ```
65
+ Feishu WS → NormalizedMessage → PendingQueue → Access Control → Slash Router → Inbound Listeners → enqueue()
66
+ ```
67
+
68
+ ### PendingQueue(去抖队列)
69
+
70
+ 文件:`vendor/bot/pending-queue.ts`
71
+
72
+ - 每个 `chatId` 独立队列
73
+ - 消息静默 600ms 后批量提交
74
+ - 支持 `block(scope)` / `unblock(scope)` — AI 回复期间阻塞新消息
75
+ - 以 `/` 开头的命令跳过队列立即处理
76
+
77
+ ### Access Control(访问控制)
78
+
79
+ 文件:`FeishuService.ts`
80
+
81
+ **DM 权限**(`canUseDm`):
82
+ - 机器人拥有者(Owner)— 始终允许
83
+ - 管理员(`admins[]`)— 始终允许
84
+ - `allowedUsers[]` 为空(默认)— 所有人可 DM
85
+ - `allowedUsers[]` 有值 — 仅白名单用户可 DM
86
+
87
+ **群聊权限**(`canUseGroup`):
88
+ - 拥有者和管理员始终允许
89
+ - 仅 `allowedChats[]` 中的群被允许
90
+
91
+ **@ 提及策略**:
92
+ - `requireMentionInGroup` 默认为 `true` — 群聊需要 @bot
93
+ - 可配置为 `false` 响应所有群消息
94
+
95
+ ### 内置命令
96
+
97
+ | 命令 | 说明 |
98
+ |------|------|
99
+ | `/stop` | 停止当前处理 |
100
+ | `/reset` | 重置会话 |
101
+ | `/status` | 显示机器人状态、App ID、Owner、策略 |
102
+ | `/help` | 显示帮助信息 |
103
+
104
+ 未知命令自动传递给 AI 处理。
105
+
106
+ ---
107
+
108
+ ## 引用回复
109
+
110
+ 当用户回复某条历史消息时,`fetchQuotedContext()`(`vendor/bot/quote.ts`)会通过 `channel.fetchRawMessage()` 获取原文,包装为 XML 注入 AI 上下文:
111
+
112
+ ```xml
113
+ <quoted_message id="..." sender_id="..." sender_name="..." type="text">
114
+ Original message content here
115
+ </quoted_message>
116
+ ```
117
+
118
+ 支持类型:纯文本、合并转发、交互式卡片(CardKit v1 和 v2)。
119
+
120
+ ---
121
+
122
+ ## 消息格式输出
123
+
124
+ ### 文本
125
+
126
+ `sendText(chatId, text)` — 发送纯文本。
127
+
128
+ ### Markdown(主要方式)
129
+
130
+ `sendMarkdown(chatId, markdown)` — 发送前通过 `feishuMarkdown.ts` 优化:
131
+
132
+ - **标题降级**: H1→H4, H2-H6→H5(飞书卡片 H1-H3 渲染有 bug)
133
+ - **Schema 2.0 间距**: 在连续标题、表格前后、代码块周围插入 `<br>`
134
+ - **图片过滤**: 非 `img_*` 图片移除(防 CardKit 200570 错误)
135
+ - **表格限制**: 超过 3 个表格降级为代码块(防 230099/11310 错误)
136
+
137
+ ### 语音
138
+
139
+ `sendVoice(chatId, text)` — 启用 TTS 时自动调用。
140
+
141
+ ---
142
+
143
+ ## 语音(TTS)系统
144
+
145
+ 飞书语音为**单向输出**(AI 回复 → 语音),用户始终通过文字输入。
146
+
147
+ ### Edge TTS(默认)
148
+
149
+ - 使用 `edge-tts` CLI 工具
150
+ - 默认语音:`zh-CN-XiaoxiaoNeural`
151
+ - 输出转码为 OGG (Opus) 后发送
152
+
153
+ ### VoxCPM(自定义语音克隆)
154
+
155
+ - 使用 `.venv/bin/voxcpm` CLI
156
+ - 需要 `ttsReferenceAudio`(WAV/MP3 参考音频)
157
+ - 长文本按 ~150 字在句边界分块
158
+ - 每块独立合成,WAV→OGG 转码,ffmpeg concat 合并
159
+
160
+ ### TTS 配置
161
+
162
+ | 字段 | 类型 | 说明 |
163
+ |------|------|------|
164
+ | `ttsEnabled` | boolean | 主开关 |
165
+ | `ttsProvider` | `'edge' \| 'voxcpm'` | 引擎选择 |
166
+ | `ttsVoice` | string | Edge TTS 语音名称 |
167
+ | `ttsReferenceAudio` | string | VoxCPM 参考音频路径 |
168
+
169
+ ---
170
+
171
+ ## QR 码注册向导
172
+
173
+ 支持一键创建飞书应用,无需手动在开发者��台操作:
174
+
175
+ 1. 调用 `@larksuite/channel` 的 `registerApp({ source: 'versperclaw' })`
176
+ 2. 返回 QR 码 URL,终端用 ASCII 渲染
177
+ 3. 用户使用飞书手机端扫码授权
178
+ 4. `client_id` 和 `client_secret` 自动保存到配置
179
+ 5. 机器人立即启动
180
+
181
+ ---
182
+
183
+ ## 配置
184
+
185
+ 文件路径: `~/.claude/adapters.json`(`feishu` 键下)
186
+
187
+ | 字段 | 类型 | 必需 | 说明 |
188
+ |------|------|------|------|
189
+ | `appId` | string | ✅ | 飞书开放平台 App ID |
190
+ | `appSecret` | string | ✅ | 飞书开放平台 App Secret |
191
+ | `tenant` | `'feishu' \| 'lark'` | ❌ | API 端点选择 |
192
+ | `encryptKey` | string | ❌ | 事件加密 |
193
+ | `verificationToken` | string | ❌ | 事件 URL 验证 |
194
+ | `allowedUsers` | string[] | ❌ | DM 白名单(空=开放) |
195
+ | `admins` | string[] | ❌ | 管理员 open_id |
196
+ | `allowedChats` | string[] | ❌ | 群聊白名单 |
197
+ | `requireMentionInGroup` | boolean | ❌ | 默认 true |
198
+ | `ttsEnabled` | boolean | ❌ | 语音回复开关 |
199
+ | `ttsProvider` | `'edge' \| 'voxcpm'` | ❌ | TTS 引擎 |
200
+ | `ttsVoice` | string | ❌ | Edge TTS 语音 |
201
+ | `ttsReferenceAudio` | string | ❌ | VoxCPM 参考音频 |
202
+
203
+ ---
204
+
205
+ ## Keepalive(保活机制)
206
+
207
+ 文件:`vendor/bot/keepalive.ts`
208
+
209
+ 独立于 SDK 内部 ping 的防御性看门狗:
210
+
211
+ - **间隔**: 每 15 秒
212
+ - **防风暴**: 5 秒内跳过重复 tick
213
+ - **睡眠检测**: 距上次 tick 超过 30 秒重置计数器
214
+ - **HTTP 探针**: 重连前 HEAD 请求检测网络可达性
215
+ - **死连接阈值**: 连续 3 个 tick 确认 WS 断开才强制重连
216
+
217
+ ---
218
+
219
+ ## 桥接 Hook
220
+
221
+ `useFeishuBridge`(`src/hooks/useFeishuBridge.ts`)
222
+
223
+ React hook,负责:
224
+
225
+ 1. 订阅 FeishuService 的入站事件
226
+ 2. 监听 `messages` 数组,识别飞书来源的消息(`origin.kind === 'channel' && origin.server === 'feishu'`)
227
+ 3. 收集后续 AI 回复
228
+ 4. 在 `isLoading` 从 true→false 时:
229
+ - 主: `sendMarkdown()` 发送完整回复
230
+ - 次: `sendVoice()` 发送 TTS 语音
231
+
232
+ ---
233
+
234
+ ## 与 FriendService 的对比
235
+
236
+ | 方面 | FeishuService | FriendService |
237
+ |------|--------------|---------------|
238
+ | 通信方式 | WebSocket (`@larksuite/channel`) | 同进程 HTTP + SSE |
239
+ | 消息输入 | 文字(飞书 IM) | 文字 / 语音(VAD + STT) |
240
+ | 语音方向 | 仅输出(TTS) | 双向(VAD → STT → AI → TTS) |
241
+ | TTS 引擎 | Edge TTS, VoxCPM | Edge TTS, Qwen TTS |
242
+ | 配置存储 | `~/.claude/adapters.json` | `getPrefs()` |
243
+ | 服务位置 | `src/services/feishu/` | `src/friend/` |
docs/services/overview.md CHANGED
@@ -117,24 +117,19 @@ Auto Dream 是一个后台记忆整合系统,在对话间期自动运行,将
117
 
118
  **目录**: `src/services/feishu/`
119
 
120
- 飞书机器人集成,基于 `@larksuite/channel` SDK。
121
 
122
- ### 核心
123
 
124
- | 文件 | 描述 |
125
- |------|------|
126
- | `FeishuService.ts` | 飞书机器人服务 — 创建 LarkChannel、注册应用、处理消息事件、管理聊天模式、引用回复、保活机制 |
127
- | `feishuConfig.ts` | 配置管理 — 读写 `~/.claude/adapters.json` 中的飞书配置段;管理已配对用户、授权用户白名单、Group 模式设置 |
128
- | `vendor/` | 自包含的第三方实现模块(核心日志、机器人 pending 队列、保活、引用回复、访问策略) |
129
-
130
- ### 功能
131
 
132
- - 应用注册与事件处理
133
- - DM 私聊白名单
134
- - Group 群聊模式
135
  - 引用上下文回复
136
- - 管理员权限控制
137
- - 自动保活Keepalive
 
138
 
139
  ---
140
 
 
117
 
118
  **目录**: `src/services/feishu/`
119
 
120
+ 飞书(Feishu/Lark)机器人集成,基于 `@larksuite/channel` SDK 的 WebSocket 长连接机器人
121
 
122
+ 详见 [飞书集成档](feishu.md)。
123
 
124
+ ### 功能速览
 
 
 
 
 
 
125
 
126
+ - 应用注册(支持 QR 码一键创建)
127
+ - DM 私聊 / Group 群聊模式
128
+ - 访问控制(白名单 / 管理员 / 拥有者)
129
  - 引用上下文回复
130
+ - Markdown 格式化输出
131
+ - 语音回复Edge TTS / VoxCPM 语音克隆
132
+ - Keepalive 自动保活
133
 
134
  ---
135
 
docs/tools/overview.md CHANGED
@@ -244,8 +244,23 @@ LLM 请求工具调用
244
 
245
  ### WebSearch / WebFetch
246
 
247
- - **WebSearchTool**: 使用 Tavily API 或本地 SearXNG 进行网络搜索
248
- - **WebFetchTool**: 抓取 URL 内容并应用 prompt 处理(提取、总结)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
 
250
  相关文件:
251
  - `/home/yuki/Code/Agent/VersperClaw/src/Tool.ts` — Tool 类型与 buildTool 框架
 
244
 
245
  ### WebSearch / WebFetch
246
 
247
+ #### 双后端架构
248
+
249
+ WebSearchTool 支持两个搜索后端:
250
+
251
+ | 后端 | 类型 | 配置 | 特点 |
252
+ |------|------|------|------|
253
+ | **Tavily** | 云 API | `TAVILY_API_KEY` 环境变量 | 稳定、无需自托管 |
254
+ | **SearXNG** | 自托管 | Docker 运行 `verspersearch` | 完全隐私、无 API 成本 |
255
+
256
+ 后端自动选择:若配置了 `TAVILY_API_KEY` 则使用 Tavily,否则回退到本地 SearXNG。
257
+
258
+ #### WebFetch
259
+
260
+ 抓取 URL 内容并应用 prompt 处理(提取、总结)。支持将结果渲染为 Markdown 格式,包含图片链接。
261
+
262
+ 配置项:
263
+ - `JINA_API_KEY` — 可选的 Jina AI API 密钥,用于增强型内容提取
264
 
265
  相关文件:
266
  - `/home/yuki/Code/Agent/VersperClaw/src/Tool.ts` — Tool 类型与 buildTool 框架