@jun133/athlete 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +146 -0
  2. package/dist/cli.js +22731 -0
  3. package/dist/cli.js.map +1 -0
  4. package/package.json +72 -0
  5. package/scripts/postinstall-playwright.mjs +79 -0
  6. package/spec/README.md +56 -0
  7. package/spec/adr/ADR-0001-/345/215/225/346/250/241/345/274/217/345/205/250/346/235/203/351/231/220.md +16 -0
  8. package/spec/adr/ADR-0002-/345/215/225agent/350/265/267/346/255/245/345/271/266/351/242/204/347/225/231/345/244/232agent/350/276/271/347/225/214.md +19 -0
  9. package/spec/adr/ADR-0003-openai-compatible/344/274/230/345/205/210.md +16 -0
  10. package/spec/architecture//346/200/273/344/275/223/346/236/266/346/236/204.md +111 -0
  11. package/spec/architecture//347/212/266/346/200/201/344/270/216/347/234/237/347/233/270/346/272/220.md +117 -0
  12. package/spec/architecture//350/277/220/350/241/214/346/227/266/345/276/252/347/216/257.md +82 -0
  13. package/spec/implementation/README.md +17 -0
  14. package/spec/implementation//346/250/241/345/235/227/347/272/247/345/274/200/345/217/221/344/273/273/345/212/241/345/215/225.md +55 -0
  15. package/spec/implementation//347/233/256/345/275/225/347/273/223/346/236/204/345/210/260/344/273/243/347/240/201/346/226/207/344/273/266/346/230/240/345/260/204/350/241/250.md +101 -0
  16. package/spec/interfaces/InteractionShell.md +85 -0
  17. package/spec/interfaces/ProviderAdapter.md +23 -0
  18. package/spec/interfaces/README.md +17 -0
  19. package/spec/interfaces/RuntimeLoop.md +28 -0
  20. package/spec/interfaces/SessionStore.md +22 -0
  21. package/spec/interfaces/ToolRegistry.md +21 -0
  22. package/spec/modules/config-system.md +51 -0
  23. package/spec/modules/interactive-terminal.md +112 -0
  24. package/spec/modules/lightweight-context-runtime.md +63 -0
  25. package/spec/modules/provider-adapter.md +20 -0
  26. package/spec/modules/runtime-metrics.md +132 -0
  27. package/spec/modules/runtime-rules.md +33 -0
  28. package/spec/modules/session-resume-compact.md +49 -0
  29. package/spec/modules/task-state.md +34 -0
  30. package/spec/modules/telegram-private-chat.md +290 -0
  31. package/spec/modules/tool-registry.md +79 -0
  32. package/spec/modules/weixin-private-chat.md +291 -0
  33. package/spec/modules/workspace-isolation.md +24 -0
  34. package/spec/modules//346/211/251/345/261/225/346/234/272/345/210/266.md +105 -0
  35. package/spec/overview/v0/350/214/203/345/233/264.md +54 -0
  36. package/spec/overview//344/272/247/345/223/201/345/256/232/344/271/211.md +59 -0
  37. package/spec/principles/P01-/344/270/200/344/270/252/345/276/252/347/216/257/344/270/200/344/270/252/346/231/272/350/203/275/344/275/223.md +31 -0
  38. package/spec/principles/P02-/345/212/240/344/270/200/344/270/252/345/267/245/345/205/267/345/217/252/345/212/240/344/270/200/344/270/252/345/244/204/347/220/206/345/231/250.md +28 -0
  39. package/spec/principles/P03-/345/205/210/350/256/241/345/210/222/345/206/215/345/212/250/346/211/213.md +25 -0
  40. package/spec/principles/P04-/345/244/247/344/273/273/345/212/241/346/213/206/347/273/231/345/255/220/346/231/272/350/203/275/344/275/223.md +26 -0
  41. package/spec/principles/P05-/347/237/245/350/257/206/346/214/211/351/234/200/345/212/240/350/275/275.md +29 -0
  42. package/spec/principles/P06-/344/270/212/344/270/213/346/226/207/350/246/201/350/203/275/345/216/213/347/274/251.md +23 -0
  43. package/spec/principles/P07-/344/273/273/345/212/241/345/233/276/350/246/201/350/220/275/347/233/230.md +20 -0
  44. package/spec/principles/P08-/346/205/242/346/223/215/344/275/234/346/224/276/345/220/216/345/217/260.md +23 -0
  45. package/spec/principles/P09-/344/273/273/345/212/241/345/244/252/345/244/247/345/260/261/345/210/206/347/273/231/351/230/237/345/217/213.md +21 -0
  46. package/spec/principles/P10-/351/230/237/345/217/213/344/271/213/351/227/264/350/246/201/346/234/211/347/273/237/344/270/200/345/215/217/350/256/256.md +23 -0
  47. package/spec/principles/P11-/351/230/237/345/217/213/350/207/252/345/267/261/350/256/244/351/242/206/344/273/273/345/212/241.md +25 -0
  48. package/spec/principles/P12-/345/267/245/344/275/234/345/214/272/345/222/214/344/273/273/345/212/241/350/246/201/351/232/224/347/246/273.md +20 -0
  49. package/spec/principles/P13-session/346/230/257/344/273/273/345/212/241/347/216/260/345/234/272.md +30 -0
  50. package/spec/principles/P14-/346/211/247/350/241/214/347/272/246/346/235/237/344/270/215/346/230/257/345/256/211/345/205/250/347/255/226/347/225/245.md +27 -0
  51. package/spec/principles/P15-provider/345/277/205/351/241/273/345/217/257/346/233/277/346/215/242.md +22 -0
  52. package/spec/principles/P16-/351/205/215/347/275/256/345/217/252/350/203/275/346/234/211/344/270/200/344/270/252/345/205/245/345/217/243.md +22 -0
  53. package/spec/principles/P17-/346/211/251/345/261/225/351/235/240/344/272/213/344/273/266/347/224/237/351/225/277.md +32 -0
  54. package/spec/principles/P18-/344/270/273/345/276/252/347/216/257/345/222/214/346/226/207/344/273/266/351/203/275/344/270/215/350/203/275/351/225/277/350/203/226.md +36 -0
  55. package/spec/principles/P19-/345/205/210/345/206/231/345/244/261/350/264/245/346/265/213/350/257/225/345/206/215/345/206/231/345/256/236/347/216/260.md +29 -0
  56. package/spec/principles/README.md +39 -0
  57. package/spec/repo//345/274/200/345/217/221/350/247/204/345/210/231.md +39 -0
  58. package/spec/repo//346/234/254/345/234/260/345/221/275/344/273/244/344/270/216/346/265/201/347/250/213.md +32 -0
  59. package/spec/testing/fail-first-/347/254/254/344/270/200/346/211/271/346/265/213/350/257/225/345/210/227/350/241/250.md +11 -0
  60. package/spec/testing/fixtures-/350/247/204/350/214/203.md +20 -0
  61. package/spec/testing//346/265/213/350/257/225/347/255/226/347/225/245.md +97 -0
@@ -0,0 +1,33 @@
1
+ # runtime rules
2
+
3
+ ## 作用
4
+
5
+ 运行时规则是 Athlete 的机器约束层。
6
+
7
+ ## 当前包含
8
+
9
+ - 计划先行
10
+ - inbox 注入
11
+ - verification 状态机
12
+ - finalize / closeout gating
13
+ - continuation / compression
14
+ - tool error recovery
15
+
16
+ ## 不该放进来的东西
17
+
18
+ - 具体任务拆分算法
19
+ - 具体 skill 内容
20
+ - 某个单一工具的内部实现
21
+
22
+ ## 当前与收口直接相关的规则
23
+
24
+ - 变更型动作默认要求先 `todo_write`
25
+ - 文件改动和 mutating shell 会把 session 推进到 verification required
26
+ - 轻量交付物允许用定向 `read_file` / auto-readback 完成轻量验证
27
+ - continuation 后仍然读取持久化的 `pendingPaths`,不会因为 slice 切换就忘记“还有哪些输出待验”
28
+ - 当收口条件已满足时,task board closeout 工具会被隐藏,避免 `task_list` / `task_get` / `task_update` 无意义循环
29
+ - 当 todo 已全部完成时,runtime 不再继续鼓励补写 `todo_write`
30
+
31
+ ## 下一阶段要求
32
+
33
+ 总指挥层可以提出“下一步做什么”,但运行时规则仍决定“现在允不允许这样做”。
@@ -0,0 +1,49 @@
1
+ # session / resume / compact
2
+
3
+ ## 作用
4
+
5
+ 这一层负责保护 Athlete 的“长任务可继续”能力。
6
+
7
+ ## 当前能力
8
+
9
+ - session 持久化
10
+ - resume 继续最近任务现场
11
+ - request context 压缩
12
+ - continuation 自动续跑
13
+ - todo / taskState / verificationState 跨 slice 持续生效
14
+
15
+ ## 当前边界
16
+
17
+ Athlete 当前的记忆重点是:
18
+
19
+ - 当前项目
20
+ - 当前任务
21
+ - 当前 turn 相关状态
22
+ - 当前待验证输出 `pendingPaths`
23
+ - 最近一次 verification 结果
24
+
25
+ 它不是跨项目的人格记忆。
26
+
27
+ ## 当前实现约束
28
+
29
+ - continuation 会复用已有 session,而不是重新发明 todo / verification 状态。
30
+ - compact 只压缩请求上下文,不抹掉任务板、todo、verification 这些真相源。
31
+ - 收口判断可以依赖持久化的 `verificationState.pendingPaths`,不能只看当前 slice 的临时 `changedPaths`。
32
+
33
+ ## Resume / Reset Contract
34
+
35
+ - `resume` 的语义是继续现有任务现场。
36
+ - `quit` 只是退出当前聊天窗口,不主动清空项目运行时状态。
37
+ - 显式 `reset` 会清空当前项目 `.athlete/` 下的运行时状态,并删除当前项目相关的持久化 session。
38
+ - 一旦 `reset` 成功,`resume` 不应恢复已经 reset 掉的运行时。
39
+ - 如果 objective 明确变化,checkpoint 进度必须重置,避免旧任务进度污染新任务。
40
+ - externalized tool-result references 和 verification pending paths 仍然是优先的可恢复锚点,但 reset 会主动销毁这一层锚点。
41
+
42
+ ## 下一阶段要求
43
+
44
+ 未来可以增加更强的恢复能力,但必须遵守:
45
+
46
+ 1. 项目事实优先于抽象记忆。
47
+ 2. 记忆是辅助,不是第二真相源。
48
+ 3. 不能破坏现有 continuation / compact / resume 的稳定边界。
49
+ 4. destructive reset 必须保持显式、可理解、不可与普通 quit 混淆。
@@ -0,0 +1,34 @@
1
+ # task state
2
+
3
+ ## 作用
4
+
5
+ 任务状态是 Athlete 控制面的核心。
6
+
7
+ ## 当前字段重点
8
+
9
+ - `status`
10
+ - `blockedBy`
11
+ - `blocks`
12
+ - `assignee`
13
+ - `owner`
14
+ - `checklist`
15
+ - `worktree`
16
+
17
+ ## 当前规则
18
+
19
+ 1. `assignee` 表示应该谁做。
20
+ 2. `owner` 表示现在谁正在做。
21
+ 3. 被阻塞任务不能启动。
22
+ 4. 已完成任务不能随意重开。
23
+
24
+ ## 下一阶段演进方向
25
+
26
+ 任务系统要支持总指挥层,优先考虑增加:
27
+
28
+ - 优先级
29
+ - 父子任务
30
+ - 重试次数
31
+ - 产物引用
32
+ - review / verify 要求
33
+
34
+ 这些演进必须建立在现有持久化任务板上,而不是另起一套任务宇宙。
@@ -0,0 +1,290 @@
1
+ # Telegram 私聊接入
2
+
3
+ ## 范围
4
+
5
+ - 只支持 Telegram 私聊
6
+ - 不支持群聊、超级群、频道
7
+ - 不做 Webhook 平台化,不做按钮系统,不做多平台网关
8
+ - 只做 Telegram 通道层能力增强,不重写 Athlete 核心 runtime
9
+
10
+ ## 宪法对齐
11
+
12
+ 这块实现必须遵守 `spec/principles/` 里的几条核心原则:
13
+
14
+ - `P01 一个循环一个智能体`
15
+ Telegram 只是把私聊消息接到现有 lead turn,不重写 agent loop
16
+ - `P02 加一个工具只加一个处理器`
17
+ Telegram 文件回传能力通过独立工具处理器接入,不把平台分支塞进核心循环
18
+ - `P16 配置只能有一个入口`
19
+ Telegram 配置统一走 `src/config/store.ts` 和 `.athlete/.env`
20
+ - `P17 扩展靠事件生长`
21
+ Telegram 通道通过边界模块、turn display、tool registry、store 扩展,不靠在主循环里硬塞平台细节
22
+ - `P18 主循环和文件都不能长胖`
23
+ Telegram 服务编排、turn 执行、附件处理、日志和命令语义要按职责拆模块,避免一个大文件继续膨胀
24
+
25
+ ## 模块边界
26
+
27
+ Telegram 相关实现集中在 `src/telegram/`:
28
+
29
+ - `types.ts`
30
+ Telegram update/message 的规范化类型
31
+ - `config.ts`
32
+ Telegram 配置默认值、归一化、运行时目录解析
33
+ - `botApiClient.ts`
34
+ Telegram Bot API HTTP 客户端
35
+ - `polling.ts`
36
+ long polling 和 offset 提交
37
+ - `offsetStore.ts`
38
+ update offset 持久化
39
+ - `sessionMapStore.ts`
40
+ Telegram peer 到 Athlete session 的绑定
41
+ - `attachmentStore.ts`
42
+ Telegram 入站附件元数据持久化
43
+ - `deliveryQueue.ts`
44
+ 文本/文件投递队列、重试、恢复
45
+ - `messageChunking.ts`
46
+ 长文本分片
47
+ - `localCommands.ts`
48
+ Telegram 端命令语义适配
49
+ - `turnDisplay.ts`
50
+ Telegram 过程输出适配
51
+ - `turnRunner.ts`
52
+ 单个 Telegram turn 的运行编排
53
+ - `service.ts`
54
+ Telegram 服务总控、拉取、分发、stop、恢复
55
+ - `logger.ts`
56
+ 终端高层日志
57
+ - `sendFileTool.ts`
58
+ Telegram 文件回传工具
59
+ - `processLock.ts`
60
+ Telegram 服务单实例锁
61
+ - `proxy.ts`
62
+ Telegram 代理环境接线
63
+
64
+ CLI 只负责注册命令和注入依赖,仍然放在:
65
+
66
+ - `src/telegram/cli.ts`
67
+ - `src/cli.ts`
68
+
69
+ ## 启动方式
70
+
71
+ 命令:
72
+
73
+ ```powershell
74
+ athlete telegram serve
75
+ ```
76
+
77
+ 行为:
78
+
79
+ 1. 读取统一配置入口 `src/config/store.ts`
80
+ 2. 解析 Telegram runtime 配置
81
+ 3. 获取 Telegram 单实例锁
82
+ 4. 启动 long polling
83
+ 5. 把私聊消息接入现有 Athlete session / turn 体系
84
+ 6. 把文本和文件回复先落盘到 delivery queue,再尝试发送
85
+
86
+ 默认交互模式不会被劫持;只有显式执行 `athlete telegram serve` 才会启动 Telegram 服务。
87
+
88
+ ## 配置
89
+
90
+ Telegram 配置统一并入 `AppConfig.telegram` / `RuntimeConfig.telegram`。
91
+
92
+ 推荐通过 `.athlete/.env` 配置:
93
+
94
+ ```text
95
+ ATHLETE_TELEGRAM_TOKEN=replace-with-your-bot-token
96
+ ATHLETE_TELEGRAM_ALLOWED_USER_IDS=123456789
97
+ ATHLETE_TELEGRAM_API_BASE_URL=https://api.telegram.org
98
+ ATHLETE_TELEGRAM_PROXY_URL=http://127.0.0.1:7897
99
+ ATHLETE_TELEGRAM_POLLING_TIMEOUT_SECONDS=50
100
+ ATHLETE_TELEGRAM_POLLING_LIMIT=100
101
+ ATHLETE_TELEGRAM_POLLING_RETRY_BACKOFF_MS=1000
102
+ ATHLETE_TELEGRAM_MESSAGE_CHUNK_CHARS=3500
103
+ ATHLETE_TELEGRAM_TYPING_INTERVAL_MS=4000
104
+ ATHLETE_TELEGRAM_DELIVERY_MAX_RETRIES=6
105
+ ATHLETE_TELEGRAM_DELIVERY_BASE_DELAY_MS=1000
106
+ ATHLETE_TELEGRAM_DELIVERY_MAX_DELAY_MS=30000
107
+ ```
108
+
109
+ 说明:
110
+
111
+ - `ATHLETE_TELEGRAM_ALLOWED_USER_IDS` 必须显式配置;空白名单等于任何人都不能控制 bot
112
+ - `ATHLETE_TELEGRAM_PROXY_URL` 是 Telegram 专用代理入口,例如 Clash Verge 的 `mixed-port`
113
+ - Telegram 配置仍然只走同一套配置入口,不另起平行配置系统
114
+
115
+ ## 什么是本地代理入口
116
+
117
+ 当用户使用 Clash Verge、Clash Meta、mihomo 这类代理工具时,常见情况是:
118
+
119
+ - Telegram 域名会被 fake-ip 机制映射成 `198.18.x.x`
120
+ - 应用程序自己不能直接拿这个 fake-ip 去直连
121
+ - 应用程序应该把请求交给本地代理软件去转发
122
+
123
+ 这里的“本地代理入口”就是:
124
+
125
+ - 代理软件跑在用户自己的电脑上
126
+ - 它会打开一个本地地址
127
+ - 例如 `http://127.0.0.1:7897`
128
+
129
+ 对于 Telegram 服务来说,真正稳定要配置的是这个本地入口,而不是 Telegram 最后被解析成的 fake-ip。
130
+
131
+ ## 单实例语义
132
+
133
+ Telegram 服务必须是单实例:
134
+
135
+ - 同一个项目状态目录下,只允许一个 `telegram serve`
136
+ - 如果已经有一个存活实例,第二个实例直接拒绝启动
137
+ - 如果只剩下陈旧 `service.pid`,新实例会识别为 stale lock 并自动覆盖
138
+
139
+ 这样可以避免:
140
+
141
+ - 同一条消息被两个实例重复消费
142
+ - 同一条最终回复被重复发送
143
+ - 用户关掉一个窗口后,误以为服务还神秘存活
144
+
145
+ ## 会话与恢复
146
+
147
+ Telegram 状态目录位于:
148
+
149
+ ```text
150
+ <project-state-root>/.athlete/telegram/
151
+ ```
152
+
153
+ 持久化内容包括:
154
+
155
+ - `offset.json`
156
+ 下一个待消费的 Telegram update offset
157
+ - `session-map.json`
158
+ `telegram:private:<chatId>` 到 Athlete session 的映射
159
+ - `attachments.json`
160
+ 入站文件元数据和本地落盘路径
161
+ - `delivery.json`
162
+ 待发送文本/文件、重试次数和下次重试时间
163
+ - `service.pid`
164
+ Telegram 单实例锁文件
165
+
166
+ 恢复语义:
167
+
168
+ 1. 重启后先读 `offset.json`,从上次提交之后继续拉取
169
+ 2. `session-map.json` 恢复同一 Telegram 私聊到同一个 Athlete session
170
+ 3. `delivery.json` 在启动和轮询前后都会扫描并补发
171
+ 4. `attachments.json` 让“刚发的文件”这类语义可继续工作
172
+ 5. `service.pid` 如果是失效旧 pid,会被新实例覆盖
173
+
174
+ ## 文件能力
175
+
176
+ ### 入站文件
177
+
178
+ - 用户可以在 Telegram 私聊直接发文件
179
+ - Bot API 会下载文件到项目状态目录下的 Telegram 文件目录
180
+ - 附件元数据会持久化
181
+ - 当前 turn 会拿到这份文件的本地路径和上下文说明
182
+ - 用户可以继续说“分析我刚发的文件”
183
+
184
+ ### 出站文件
185
+
186
+ - 用户可以要求 Athlete 查找本地文件并发回 Telegram
187
+ - 用户可以要求 Athlete 生成文件并发回 Telegram
188
+ - 回复形式必须是真实 Telegram document
189
+ - 不允许只发本地路径或文本链接糊弄
190
+
191
+ ### 恢复与边界
192
+
193
+ - 文本和文件都先进入 delivery queue,再尝试发送
194
+ - 失败后按指数退避重试
195
+ - 服务重启后继续恢复待发送文本和文件
196
+ - 文件大小要做边界校验
197
+
198
+ ## `/stop`
199
+
200
+ Telegram 端只保留一个停止命令:
201
+
202
+ ```text
203
+ /stop
204
+ ```
205
+
206
+ 语义:
207
+
208
+ - 只停止“当前这个 Telegram 用户当前正在执行的任务”
209
+ - bot 服务继续在线
210
+ - 不停止整个 Telegram 服务
211
+ - 不影响其他白名单用户
212
+ - 停止后当前用户还能继续发下一条任务
213
+
214
+ ## Telegram 端命令语义
215
+
216
+ Telegram 端命令语义与本地 CLI 有明确边界:
217
+
218
+ - `/session`、`/config`、`/runtime` 等查看类命令继续复用现有本地命令层
219
+ - `/multi` 明确拒绝,并提示直接发送完整消息
220
+ - `quit` / `reset` 不再作为 Telegram 主命令暴露
221
+ - Telegram 端收到 `quit` / `reset` 时,只做提示,不执行本地终端语义
222
+
223
+ ## 过程输出
224
+
225
+ Telegram 过程输出要更接近终端工作感知,但遵守“可见段按事件逐条镜像”的单一语义,不能刷底层噪音。
226
+
227
+ ### Telegram 聊天框里的可见消息
228
+
229
+ 过程消息按实际事件顺序发送,不做机械固定轮换,也不做最终汇总:
230
+
231
+ - `onToolCall` 一次,就发一条 tool call 消息
232
+ - `todo_write` 对应的可见 preview 一次,就发一条 todo preview 消息
233
+ - `onAssistantDelta` 只作为阶段内缓冲信号,不直接发聊天消息
234
+ - `onAssistantText` 表示拿到了完整 assistant 文本时,发一条 assistant 消息
235
+ - `onAssistantDone` 带文本且当前 assistant 阶段尚未发出时,发一条最终 assistant 消息
236
+ - 不合并多段 assistant
237
+ - 不把 tool / todo / assistant 混成一条
238
+
239
+ 不发送的内容:
240
+
241
+ - 工具输出正文
242
+ - 大段文件原文
243
+ - 底层噪音日志
244
+ - reasoning
245
+ - `onStatus` 一类非可见噪音
246
+
247
+ 格式约束:
248
+
249
+ - 不额外加抬头
250
+ - 过程消息保持聊天式、顺序式输出,更接近终端高层过程感知
251
+
252
+ ### 终端日志
253
+
254
+ 终端持续输出高层过程日志,包括:
255
+
256
+ - 收到哪个 Telegram 用户的消息
257
+ - 当前进入哪个 session
258
+ - 当前在哪个阶段
259
+ - 当前调用了哪个工具
260
+ - 当前是否停止、失败、成功
261
+ - 当前是否发送了文本或文件
262
+
263
+ 显式信号与可靠性约束:
264
+
265
+ - Weixin / Telegram 共享同一层可见事件判定与 durable turn display
266
+ - durable outbound 只按事件顺序发送,不按文本去重
267
+ - 如果要防重复,只能基于 event id / delivery state,不能基于文本内容
268
+ - `runOnce` 必须等当前 turn 的可见输出 durable 完成后再 commit 输入
269
+ - `serve` 主循环通过显式 pending-commit 队列继续轮询和处理 `/stop`,不靠时序猜测
270
+ - 可见消息 durable enqueue 失败不能 silent swallow,必须继续上抛
271
+
272
+ ## 串行与隔离
273
+
274
+ - 同一 Telegram peer 使用 `PerPeerCommandQueue` 串行执行
275
+ - 不同 peer 之间允许并发
276
+ - `/stop` 与 per-peer 串行队列兼容
277
+ - 同一个 peer 的 turn 不能并发破坏同一个 session
278
+
279
+ ## 安全与约束
280
+
281
+ - 只接受 `allowedUserIds` 白名单内的私聊用户
282
+ - 非白名单用户不会进入 Athlete turn
283
+ - 群聊/频道消息不会进入私聊 session
284
+ - Telegram 端仍然遵守 Athlete 当前 runtime 的 `mode`、`allowedRoots` 和执行约束
285
+
286
+ ## 维护约束
287
+
288
+ - Telegram 平台细节不能下沉到 `src/agent/`、`src/tools/`、`src/ui/`
289
+ - 只允许薄接线进入核心 runtime
290
+ - 新增能力优先继续生长在 `src/telegram/`
@@ -0,0 +1,79 @@
1
+ # tool registry
2
+
3
+ ## 作用
4
+
5
+ Tool registry 负责向模型公开动作集合,并统一管理本地工具与 MCP 动态工具。
6
+
7
+ ## 当前组成
8
+
9
+ - 本地内建工具
10
+ - mode 过滤后的工具集
11
+ - MCP 动态收集到的工具
12
+
13
+ ## 当前规则
14
+
15
+ 1. 新工具先注册,再暴露给模型。
16
+ 2. tool handler 只做动作,不做控制面真相发明。
17
+ 3. skill 不是工具替代品;skill 提供 workflow,tool 提供动作。
18
+ 4. MCP 工具也必须经过统一 registry,不走旁路。
19
+
20
+ ## 工具层职责
21
+
22
+ `src/tools/` 当前负责:
23
+
24
+ - 参数解析
25
+ - 权限和状态校验
26
+ - 调用下层 store / worker / utils
27
+ - 把结果序列化返回给模型
28
+
29
+ 不负责:
30
+
31
+ - provider 请求
32
+ - session 存储
33
+ - 发明新的持久化真相
34
+
35
+ ## 当前分组
36
+
37
+ - `src/tools/files/`
38
+ - `src/tools/documents/`
39
+ - `src/tools/tasks/`
40
+ - `src/tools/team/`
41
+ - `src/tools/worktrees/`
42
+ - `src/tools/background/`
43
+ - `src/tools/shell/`
44
+ - `src/tools/skills/`
45
+
46
+ 共享层仍在 `src/tools/` 根目录:
47
+
48
+ - `registry.ts`
49
+ - `runtimeRegistry.ts`
50
+ - `shared.ts`
51
+ - `types.ts`
52
+ - `changeTracking.ts`
53
+
54
+ ## Playwright MCP 当前事实
55
+
56
+ 当前 Playwright 浏览器工具通过 runtime registry 暴露为:
57
+
58
+ - `mcp_playwright_browser_navigate`
59
+ - `mcp_playwright_browser_snapshot`
60
+ - `mcp_playwright_browser_click`
61
+ - `mcp_playwright_browser_type`
62
+ - `mcp_playwright_browser_take_screenshot`
63
+ - 以及其他 `mcp_playwright_browser_*`
64
+
65
+ 当前优先级策略:
66
+
67
+ - runtime registry 会把 Playwright 浏览器工具排到本地文件工具和 shell 工具前面
68
+ - request 级 tool priority 会在 web research / browser automation 场景继续把浏览器工具前置
69
+ - `run_shell` 的网页抓取只应作为 fallback
70
+
71
+ ## 当前约束
72
+
73
+ 如果某个动作:
74
+
75
+ - 需要明确输入输出
76
+ - 不适合塞进 prompt
77
+ - 不该让模型自己拼 shell
78
+
79
+ 就应该做成工具,而不是继续加提示词。