@renxqoo/renx-code 0.0.9 → 0.0.10

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 (286) hide show
  1. package/README.md +14 -0
  2. package/bin/renx.cjs +79 -42
  3. package/bin/renx.exe +0 -0
  4. package/package.json +10 -28
  5. package/src/App.tsx +0 -297
  6. package/src/agent/runtime/event-format.ts +0 -258
  7. package/src/agent/runtime/model-types.ts +0 -13
  8. package/src/agent/runtime/runtime.context-usage.test.ts +0 -192
  9. package/src/agent/runtime/runtime.error-handling.test.ts +0 -235
  10. package/src/agent/runtime/runtime.simple.test.ts +0 -16
  11. package/src/agent/runtime/runtime.test.ts +0 -296
  12. package/src/agent/runtime/runtime.ts +0 -875
  13. package/src/agent/runtime/runtime.usage-forwarding.test.ts +0 -228
  14. package/src/agent/runtime/source-modules.test.ts +0 -38
  15. package/src/agent/runtime/source-modules.ts +0 -370
  16. package/src/agent/runtime/tool-call-buffer.test.ts +0 -65
  17. package/src/agent/runtime/tool-call-buffer.ts +0 -60
  18. package/src/agent/runtime/tool-confirmation.test.ts +0 -56
  19. package/src/agent/runtime/tool-confirmation.ts +0 -15
  20. package/src/agent/runtime/types.ts +0 -99
  21. package/src/commands/slash-commands.test.ts +0 -216
  22. package/src/commands/slash-commands.ts +0 -64
  23. package/src/components/chat/assistant-reply.test.tsx +0 -47
  24. package/src/components/chat/assistant-reply.tsx +0 -136
  25. package/src/components/chat/assistant-segment.test.ts +0 -99
  26. package/src/components/chat/assistant-segment.tsx +0 -125
  27. package/src/components/chat/assistant-tool-group.tsx +0 -900
  28. package/src/components/chat/code-block.test.tsx +0 -206
  29. package/src/components/chat/code-block.tsx +0 -313
  30. package/src/components/chat/prompt-card.tsx +0 -81
  31. package/src/components/chat/segment-groups.test.ts +0 -52
  32. package/src/components/chat/segment-groups.ts +0 -106
  33. package/src/components/chat/turn-item.tsx +0 -39
  34. package/src/components/conversation-panel.tsx +0 -43
  35. package/src/components/file-mention-menu.tsx +0 -77
  36. package/src/components/file-picker-dialog.tsx +0 -206
  37. package/src/components/footer-hints.tsx +0 -75
  38. package/src/components/model-picker-dialog.tsx +0 -248
  39. package/src/components/prompt.tsx +0 -233
  40. package/src/components/slash-command-menu.tsx +0 -65
  41. package/src/components/tool-confirm-dialog-content.test.ts +0 -103
  42. package/src/components/tool-confirm-dialog-content.ts +0 -186
  43. package/src/components/tool-confirm-dialog.tsx +0 -187
  44. package/src/components/tool-display-config.ts +0 -119
  45. package/src/context-usage-regressions.test.ts +0 -26
  46. package/src/files/attachment-capabilities.test.ts +0 -30
  47. package/src/files/attachment-capabilities.ts +0 -50
  48. package/src/files/attachment-content.ts +0 -153
  49. package/src/files/file-mention-query.test.ts +0 -34
  50. package/src/files/file-mention-query.ts +0 -32
  51. package/src/files/prompt-display.ts +0 -13
  52. package/src/files/types.ts +0 -5
  53. package/src/files/workspace-files.ts +0 -61
  54. package/src/hooks/agent-event-handlers.test.ts +0 -207
  55. package/src/hooks/agent-event-handlers.ts +0 -196
  56. package/src/hooks/chat-local-replies.fixed.test.ts +0 -119
  57. package/src/hooks/chat-local-replies.test.ts +0 -153
  58. package/src/hooks/chat-local-replies.ts +0 -63
  59. package/src/hooks/turn-updater.test.ts +0 -70
  60. package/src/hooks/turn-updater.ts +0 -166
  61. package/src/hooks/use-agent-chat.context.test.ts +0 -10
  62. package/src/hooks/use-agent-chat.status.test.ts +0 -14
  63. package/src/hooks/use-agent-chat.test.ts +0 -80
  64. package/src/hooks/use-agent-chat.ts +0 -621
  65. package/src/hooks/use-file-mention-menu.ts +0 -196
  66. package/src/hooks/use-file-picker.ts +0 -185
  67. package/src/hooks/use-model-picker.ts +0 -196
  68. package/src/hooks/use-slash-command-menu.ts +0 -154
  69. package/src/index.tsx +0 -55
  70. package/src/runtime/clipboard.test.ts +0 -43
  71. package/src/runtime/clipboard.ts +0 -89
  72. package/src/runtime/exit.test.ts +0 -177
  73. package/src/runtime/exit.ts +0 -98
  74. package/src/runtime/runtime-support.test.ts +0 -31
  75. package/src/runtime/terminal-theme.test.ts +0 -55
  76. package/src/runtime/terminal-theme.ts +0 -196
  77. package/src/types/chat.ts +0 -32
  78. package/src/types/message-content.ts +0 -48
  79. package/src/ui/open-code-theme.ts +0 -176
  80. package/src/ui/opencode-markdown.ts +0 -211
  81. package/src/ui/theme.simple.test.ts +0 -52
  82. package/src/ui/theme.test.ts +0 -151
  83. package/src/ui/theme.ts +0 -152
  84. package/src/utils/time.test.ts +0 -144
  85. package/src/utils/time.ts +0 -7
  86. package/tsconfig.json +0 -30
  87. package/vendor/agent-root/src/agent/ENTERPRISE_ACCEPTANCE_CHECKLIST.md +0 -95
  88. package/vendor/agent-root/src/agent/ENTERPRISE_REALTIME.html +0 -1345
  89. package/vendor/agent-root/src/agent/ENTERPRISE_REALTIME.md +0 -1353
  90. package/vendor/agent-root/src/agent/ERROR_CONTRACT.md +0 -60
  91. package/vendor/agent-root/src/agent/TEST_COVERAGE_ANALYSIS.md +0 -278
  92. package/vendor/agent-root/src/agent/__test__/error-contract.test.ts +0 -72
  93. package/vendor/agent-root/src/agent/__test__/types.test.ts +0 -137
  94. package/vendor/agent-root/src/agent/agent/__test__/abort-runtime.test.ts +0 -83
  95. package/vendor/agent-root/src/agent/agent/__test__/callback-safety.test.ts +0 -34
  96. package/vendor/agent-root/src/agent/agent/__test__/compaction.test.ts +0 -323
  97. package/vendor/agent-root/src/agent/agent/__test__/concurrency.test.ts +0 -290
  98. package/vendor/agent-root/src/agent/agent/__test__/error-normalizer.test.ts +0 -377
  99. package/vendor/agent-root/src/agent/agent/__test__/error.test.ts +0 -212
  100. package/vendor/agent-root/src/agent/agent/__test__/fault-injection.test.ts +0 -295
  101. package/vendor/agent-root/src/agent/agent/__test__/index.test.ts +0 -3607
  102. package/vendor/agent-root/src/agent/agent/__test__/logger.test.ts +0 -35
  103. package/vendor/agent-root/src/agent/agent/__test__/message-utils.test.ts +0 -517
  104. package/vendor/agent-root/src/agent/agent/__test__/telemetry.test.ts +0 -97
  105. package/vendor/agent-root/src/agent/agent/__test__/timeout-budget.test.ts +0 -479
  106. package/vendor/agent-root/src/agent/agent/__test__/tool-call-merge.test.ts +0 -80
  107. package/vendor/agent-root/src/agent/agent/__test__/tool-execution-ledger.test.ts +0 -76
  108. package/vendor/agent-root/src/agent/agent/__test__/write-buffer.test.ts +0 -173
  109. package/vendor/agent-root/src/agent/agent/__test__/write-file-session.test.ts +0 -109
  110. package/vendor/agent-root/src/agent/agent/abort-runtime.ts +0 -71
  111. package/vendor/agent-root/src/agent/agent/callback-safety.ts +0 -33
  112. package/vendor/agent-root/src/agent/agent/compaction.ts +0 -291
  113. package/vendor/agent-root/src/agent/agent/concurrency.ts +0 -103
  114. package/vendor/agent-root/src/agent/agent/error-normalizer.ts +0 -190
  115. package/vendor/agent-root/src/agent/agent/error.ts +0 -198
  116. package/vendor/agent-root/src/agent/agent/index.ts +0 -1772
  117. package/vendor/agent-root/src/agent/agent/logger.ts +0 -65
  118. package/vendor/agent-root/src/agent/agent/message-utils.ts +0 -101
  119. package/vendor/agent-root/src/agent/agent/stream-events.ts +0 -61
  120. package/vendor/agent-root/src/agent/agent/telemetry.ts +0 -123
  121. package/vendor/agent-root/src/agent/agent/timeout-budget.ts +0 -227
  122. package/vendor/agent-root/src/agent/agent/tool-call-merge.ts +0 -111
  123. package/vendor/agent-root/src/agent/agent/tool-execution-ledger.ts +0 -164
  124. package/vendor/agent-root/src/agent/agent/write-buffer.ts +0 -188
  125. package/vendor/agent-root/src/agent/agent/write-file-session.ts +0 -238
  126. package/vendor/agent-root/src/agent/app/__test__/agent-app-service.test.ts +0 -1053
  127. package/vendor/agent-root/src/agent/app/__test__/minimal-agent-application.test.ts +0 -158
  128. package/vendor/agent-root/src/agent/app/__test__/sqlite-agent-app-store.test.ts +0 -437
  129. package/vendor/agent-root/src/agent/app/agent-app-service.ts +0 -748
  130. package/vendor/agent-root/src/agent/app/contracts.ts +0 -109
  131. package/vendor/agent-root/src/agent/app/index.ts +0 -5
  132. package/vendor/agent-root/src/agent/app/minimal-agent-application.ts +0 -151
  133. package/vendor/agent-root/src/agent/app/ports.ts +0 -72
  134. package/vendor/agent-root/src/agent/app/sqlite-agent-app-store.ts +0 -1182
  135. package/vendor/agent-root/src/agent/app/sqlite-client.ts +0 -177
  136. package/vendor/agent-root/src/agent/docs/cli-app-layer/00-README.md +0 -36
  137. package/vendor/agent-root/src/agent/docs/cli-app-layer/01-scope-and-goals.md +0 -33
  138. package/vendor/agent-root/src/agent/docs/cli-app-layer/02-architecture-overview.md +0 -40
  139. package/vendor/agent-root/src/agent/docs/cli-app-layer/03-domain-model-and-contracts.md +0 -91
  140. package/vendor/agent-root/src/agent/docs/cli-app-layer/04-ports-and-interfaces.md +0 -116
  141. package/vendor/agent-root/src/agent/docs/cli-app-layer/05-run-orchestration-and-state-machine.md +0 -52
  142. package/vendor/agent-root/src/agent/docs/cli-app-layer/06-cli-commands-and-ux.md +0 -53
  143. package/vendor/agent-root/src/agent/docs/cli-app-layer/07-storage-design-local.md +0 -52
  144. package/vendor/agent-root/src/agent/docs/cli-app-layer/08-error-and-observability.md +0 -40
  145. package/vendor/agent-root/src/agent/docs/cli-app-layer/09-security-and-policy-boundary.md +0 -19
  146. package/vendor/agent-root/src/agent/docs/cli-app-layer/10-test-plan-and-acceptance.md +0 -28
  147. package/vendor/agent-root/src/agent/docs/cli-app-layer/11-implementation-phases.md +0 -26
  148. package/vendor/agent-root/src/agent/docs/cli-app-layer/12-open-questions-and-risks.md +0 -30
  149. package/vendor/agent-root/src/agent/docs/cli-app-layer/13-sqlite-schema-fields-and-rationale.md +0 -567
  150. package/vendor/agent-root/src/agent/docs/cli-app-layer/14-project-flow-mermaid.md +0 -583
  151. package/vendor/agent-root/src/agent/docs/cli-app-layer/15-openclaw-style-project-blueprint.md +0 -972
  152. package/vendor/agent-root/src/agent/error-contract.ts +0 -154
  153. package/vendor/agent-root/src/agent/prompts/system.ts +0 -246
  154. package/vendor/agent-root/src/agent/prompts/system1.ts +0 -208
  155. package/vendor/agent-root/src/agent/storage/__test__/file-history-store.test.ts +0 -98
  156. package/vendor/agent-root/src/agent/storage/file-history-store.ts +0 -313
  157. package/vendor/agent-root/src/agent/storage/file-storage-config.ts +0 -94
  158. package/vendor/agent-root/src/agent/storage/file-system.ts +0 -31
  159. package/vendor/agent-root/src/agent/storage/file-write-service.ts +0 -21
  160. package/vendor/agent-root/src/agent/tool/__test__/base-tool.test.ts +0 -413
  161. package/vendor/agent-root/src/agent/tool/__test__/bash-policy.test.ts +0 -356
  162. package/vendor/agent-root/src/agent/tool/__test__/bash.mocked-coverage.test.ts +0 -375
  163. package/vendor/agent-root/src/agent/tool/__test__/bash.test.ts +0 -372
  164. package/vendor/agent-root/src/agent/tool/__test__/error.test.ts +0 -108
  165. package/vendor/agent-root/src/agent/tool/__test__/file-edit-tool.test.ts +0 -258
  166. package/vendor/agent-root/src/agent/tool/__test__/file-history-tools.test.ts +0 -121
  167. package/vendor/agent-root/src/agent/tool/__test__/file-read-tool.test.ts +0 -210
  168. package/vendor/agent-root/src/agent/tool/__test__/glob.test.ts +0 -139
  169. package/vendor/agent-root/src/agent/tool/__test__/grep.mocked-coverage.test.ts +0 -456
  170. package/vendor/agent-root/src/agent/tool/__test__/grep.test.ts +0 -192
  171. package/vendor/agent-root/src/agent/tool/__test__/lsp.test.ts +0 -300
  172. package/vendor/agent-root/src/agent/tool/__test__/outside-workspace-confirmation.test.ts +0 -214
  173. package/vendor/agent-root/src/agent/tool/__test__/path-security.test.ts +0 -336
  174. package/vendor/agent-root/src/agent/tool/__test__/skill-loader.test.ts +0 -494
  175. package/vendor/agent-root/src/agent/tool/__test__/skill-parser.test.ts +0 -543
  176. package/vendor/agent-root/src/agent/tool/__test__/skill-tool.test.ts +0 -172
  177. package/vendor/agent-root/src/agent/tool/__test__/task-concurrency-and-version.test.ts +0 -116
  178. package/vendor/agent-root/src/agent/tool/__test__/task-create-get-list-update.test.ts +0 -267
  179. package/vendor/agent-root/src/agent/tool/__test__/task-create.test.ts +0 -519
  180. package/vendor/agent-root/src/agent/tool/__test__/task-errors.test.ts +0 -225
  181. package/vendor/agent-root/src/agent/tool/__test__/task-output-blocking.test.ts +0 -223
  182. package/vendor/agent-root/src/agent/tool/__test__/task-output.test.ts +0 -184
  183. package/vendor/agent-root/src/agent/tool/__test__/task-parent-abort.test.ts +0 -287
  184. package/vendor/agent-root/src/agent/tool/__test__/task-real-runner-adapter.test.ts +0 -190
  185. package/vendor/agent-root/src/agent/tool/__test__/task-run-lifecycle.test.ts +0 -352
  186. package/vendor/agent-root/src/agent/tool/__test__/task-store-runner-branches.test.ts +0 -395
  187. package/vendor/agent-root/src/agent/tool/__test__/task-store.test.ts +0 -391
  188. package/vendor/agent-root/src/agent/tool/__test__/task-subagent-config-integration.test.ts +0 -176
  189. package/vendor/agent-root/src/agent/tool/__test__/task-subagent-config.test.ts +0 -68
  190. package/vendor/agent-root/src/agent/tool/__test__/task-tools-core-edges.test.ts +0 -630
  191. package/vendor/agent-root/src/agent/tool/__test__/task-tools-runtime-edges.test.ts +0 -732
  192. package/vendor/agent-root/src/agent/tool/__test__/task-types.test.ts +0 -494
  193. package/vendor/agent-root/src/agent/tool/__test__/task-utils-branches.test.ts +0 -175
  194. package/vendor/agent-root/src/agent/tool/__test__/tool-manager.test.ts +0 -505
  195. package/vendor/agent-root/src/agent/tool/__test__/types.test.ts +0 -55
  196. package/vendor/agent-root/src/agent/tool/__test__/web-fetch.test.ts +0 -244
  197. package/vendor/agent-root/src/agent/tool/__test__/web-search.test.ts +0 -290
  198. package/vendor/agent-root/src/agent/tool/__test__/write-file.test.ts +0 -368
  199. package/vendor/agent-root/src/agent/tool/base-tool.ts +0 -345
  200. package/vendor/agent-root/src/agent/tool/bash-policy.ts +0 -636
  201. package/vendor/agent-root/src/agent/tool/bash.ts +0 -688
  202. package/vendor/agent-root/src/agent/tool/error.ts +0 -131
  203. package/vendor/agent-root/src/agent/tool/file-edit-tool.ts +0 -264
  204. package/vendor/agent-root/src/agent/tool/file-history-list.ts +0 -103
  205. package/vendor/agent-root/src/agent/tool/file-history-restore.ts +0 -149
  206. package/vendor/agent-root/src/agent/tool/file-read-tool.ts +0 -211
  207. package/vendor/agent-root/src/agent/tool/glob.ts +0 -171
  208. package/vendor/agent-root/src/agent/tool/grep.ts +0 -496
  209. package/vendor/agent-root/src/agent/tool/lsp.ts +0 -481
  210. package/vendor/agent-root/src/agent/tool/path-security.ts +0 -117
  211. package/vendor/agent-root/src/agent/tool/search/common.ts +0 -153
  212. package/vendor/agent-root/src/agent/tool/skill/index.ts +0 -13
  213. package/vendor/agent-root/src/agent/tool/skill/loader.ts +0 -229
  214. package/vendor/agent-root/src/agent/tool/skill/parser.ts +0 -124
  215. package/vendor/agent-root/src/agent/tool/skill/types.ts +0 -27
  216. package/vendor/agent-root/src/agent/tool/skill-tool.ts +0 -143
  217. package/vendor/agent-root/src/agent/tool/task-create.ts +0 -186
  218. package/vendor/agent-root/src/agent/tool/task-errors.ts +0 -42
  219. package/vendor/agent-root/src/agent/tool/task-get.ts +0 -116
  220. package/vendor/agent-root/src/agent/tool/task-graph.ts +0 -78
  221. package/vendor/agent-root/src/agent/tool/task-list.ts +0 -141
  222. package/vendor/agent-root/src/agent/tool/task-mock-runner-adapter.ts +0 -232
  223. package/vendor/agent-root/src/agent/tool/task-output.ts +0 -223
  224. package/vendor/agent-root/src/agent/tool/task-parent-abort.ts +0 -115
  225. package/vendor/agent-root/src/agent/tool/task-real-runner-adapter.ts +0 -336
  226. package/vendor/agent-root/src/agent/tool/task-runner-adapter.ts +0 -55
  227. package/vendor/agent-root/src/agent/tool/task-stop.ts +0 -187
  228. package/vendor/agent-root/src/agent/tool/task-store.ts +0 -217
  229. package/vendor/agent-root/src/agent/tool/task-subagent-config.ts +0 -149
  230. package/vendor/agent-root/src/agent/tool/task-types.ts +0 -264
  231. package/vendor/agent-root/src/agent/tool/task-update.ts +0 -315
  232. package/vendor/agent-root/src/agent/tool/task.ts +0 -209
  233. package/vendor/agent-root/src/agent/tool/tool-manager.ts +0 -361
  234. package/vendor/agent-root/src/agent/tool/tool-prompts.ts +0 -242
  235. package/vendor/agent-root/src/agent/tool/types.ts +0 -116
  236. package/vendor/agent-root/src/agent/tool/web-fetch.ts +0 -227
  237. package/vendor/agent-root/src/agent/tool/web-search.ts +0 -208
  238. package/vendor/agent-root/src/agent/tool/write-file.ts +0 -497
  239. package/vendor/agent-root/src/agent/types.ts +0 -232
  240. package/vendor/agent-root/src/agent/utils/__tests__/index.test.ts +0 -18
  241. package/vendor/agent-root/src/agent/utils/__tests__/message-utils.test.ts +0 -610
  242. package/vendor/agent-root/src/agent/utils/__tests__/message.test.ts +0 -223
  243. package/vendor/agent-root/src/agent/utils/__tests__/token.test.ts +0 -42
  244. package/vendor/agent-root/src/agent/utils/index.ts +0 -16
  245. package/vendor/agent-root/src/agent/utils/message.ts +0 -171
  246. package/vendor/agent-root/src/agent/utils/token.ts +0 -28
  247. package/vendor/agent-root/src/config/__tests__/load-config-to-env.test.ts +0 -238
  248. package/vendor/agent-root/src/config/__tests__/loader.test.ts +0 -361
  249. package/vendor/agent-root/src/config/__tests__/runtime.test.ts +0 -88
  250. package/vendor/agent-root/src/config/index.ts +0 -55
  251. package/vendor/agent-root/src/config/loader.ts +0 -494
  252. package/vendor/agent-root/src/config/paths.ts +0 -30
  253. package/vendor/agent-root/src/config/runtime.ts +0 -163
  254. package/vendor/agent-root/src/config/types.ts +0 -96
  255. package/vendor/agent-root/src/logger/index.ts +0 -57
  256. package/vendor/agent-root/src/logger/logger.ts +0 -819
  257. package/vendor/agent-root/src/logger/types.ts +0 -150
  258. package/vendor/agent-root/src/providers/__tests__/errors.test.ts +0 -441
  259. package/vendor/agent-root/src/providers/__tests__/index.test.ts +0 -16
  260. package/vendor/agent-root/src/providers/__tests__/openai-compatible.options.test.ts +0 -318
  261. package/vendor/agent-root/src/providers/__tests__/openai-compatible.test.ts +0 -600
  262. package/vendor/agent-root/src/providers/__tests__/registry.test.ts +0 -523
  263. package/vendor/agent-root/src/providers/__tests__/responses-adapter.test.ts +0 -298
  264. package/vendor/agent-root/src/providers/adapters/__tests__/anthropic.test.ts +0 -354
  265. package/vendor/agent-root/src/providers/adapters/__tests__/kimi.test.ts +0 -58
  266. package/vendor/agent-root/src/providers/adapters/__tests__/standard.test.ts +0 -261
  267. package/vendor/agent-root/src/providers/adapters/anthropic.ts +0 -572
  268. package/vendor/agent-root/src/providers/adapters/base.ts +0 -131
  269. package/vendor/agent-root/src/providers/adapters/kimi.ts +0 -48
  270. package/vendor/agent-root/src/providers/adapters/responses.ts +0 -732
  271. package/vendor/agent-root/src/providers/adapters/standard.ts +0 -120
  272. package/vendor/agent-root/src/providers/http/__tests__/client.timeout.test.ts +0 -313
  273. package/vendor/agent-root/src/providers/http/client.ts +0 -289
  274. package/vendor/agent-root/src/providers/http/stream-parser.ts +0 -109
  275. package/vendor/agent-root/src/providers/index.ts +0 -76
  276. package/vendor/agent-root/src/providers/kimi-headers.ts +0 -177
  277. package/vendor/agent-root/src/providers/openai-compatible.ts +0 -387
  278. package/vendor/agent-root/src/providers/registry/model-config.ts +0 -477
  279. package/vendor/agent-root/src/providers/registry/provider-factory.ts +0 -127
  280. package/vendor/agent-root/src/providers/registry.ts +0 -135
  281. package/vendor/agent-root/src/providers/types/api.ts +0 -284
  282. package/vendor/agent-root/src/providers/types/config.ts +0 -58
  283. package/vendor/agent-root/src/providers/types/errors.ts +0 -323
  284. package/vendor/agent-root/src/providers/types/index.ts +0 -72
  285. package/vendor/agent-root/src/providers/types/provider.ts +0 -45
  286. package/vendor/agent-root/src/providers/types/registry.ts +0 -68
@@ -1,972 +0,0 @@
1
- # 15. 基于 agent-v4 实现 OpenClaw 风格项目的完整蓝图
2
-
3
- ## 1. 这篇文档要解决什么问题
4
-
5
- 你现在有一个做得不错的无状态 Agent 内核,在目录 `src/agent-v4`。
6
-
7
- 你想要的不是“再写一个能回答问题的 Agent”,而是做一个更完整的系统:
8
-
9
- - 能接入微信、Telegram、企业微信、Slack 等外部应用
10
- - 能把外部消息路由到不同会话和不同 Agent
11
- - 能通过 WebSocket / HTTP / Webhook 对外提供统一入口
12
- - 能通过插件扩展渠道、命令、工具、服务
13
- - 能长期运行、可观察、可排障、可部署
14
-
15
- 这正是 `openclaw` 的核心价值。
16
-
17
- 一句话总结:
18
-
19
- > `agent-v4` 现在更像是“执行内核”,而 `openclaw` 是“执行内核 + 网关 + 渠道平台 + 插件系统 + 会话路由 + 运维安全”。
20
-
21
- 所以你应该做的,不是推翻 `agent-v4`,而是在它外面补齐平台层。
22
-
23
- ## 2. 先说结论:你现在已经有什么
24
-
25
- 从现有代码看,`agent-v4` 已经具备成为平台底座的几个关键条件。
26
-
27
- ### 2.1 无状态执行内核
28
-
29
- `StatelessAgent` 已经是一个比较清晰的执行内核:
30
-
31
- - 输入是 `messages + tools + config`
32
- - 输出是流式事件
33
- - 支持工具调用
34
- - 支持工具幂等账本
35
- - 支持超时预算
36
- - 支持上下文压缩
37
- - 不直接依赖具体渠道
38
-
39
- 这部分在:
40
-
41
- - `src/agent-v4/agent/index.ts`
42
-
43
- 这意味着它适合作为系统最内层的 `Kernel`。
44
-
45
- ### 2.2 应用层编排
46
-
47
- `AgentAppService` 已经在做比内核更上一层的事情:
48
-
49
- - 创建 execution
50
- - 追加事件
51
- - 写消息投影
52
- - 推送前台回调
53
- - 汇总 usage
54
- - 管理 run 状态
55
-
56
- 这部分在:
57
-
58
- - `src/agent-v4/app/agent-app-service.ts`
59
-
60
- 这说明你已经有了“运行编排器”的雏形。
61
-
62
- ### 2.3 存储抽象和 SQLite 落地
63
-
64
- 你已经把存储拆成 Port:
65
-
66
- - `ExecutionStorePort`
67
- - `EventStorePort`
68
- - `MessageProjectionStorePort`
69
- - `ContextProjectionStorePort`
70
- - `RunLogStorePort`
71
-
72
- 这部分在:
73
-
74
- - `src/agent-v4/app/ports.ts`
75
- - `src/agent-v4/app/sqlite-agent-app-store.ts`
76
-
77
- 这非常重要。因为 `openclaw` 风格项目本质上是事件驱动和多入口系统,没有 Port 抽象,后面会很难扩展。
78
-
79
- ### 2.4 工具系统
80
-
81
- 你已经有:
82
-
83
- - 工具注册
84
- - 工具参数校验
85
- - 工具策略检查
86
- - 工具确认流
87
- - 工具并发策略
88
-
89
- 这部分在:
90
-
91
- - `src/agent-v4/tool/tool-manager.ts`
92
-
93
- 这意味着你已经有一个很像 `openclaw` Tool Runtime 的基础版本。
94
-
95
- ### 2.5 子代理 / 工作流雏形
96
-
97
- `task-subagent-config.ts` 说明你已经开始走“多角色、多工作模式”的方向:
98
-
99
- - Explore
100
- - Plan
101
- - research-agent
102
- - general-purpose
103
-
104
- 这会成为将来多 Agent 路由的重要基础。
105
-
106
- ## 3. 你缺什么
107
-
108
- 如果要做成 `openclaw` 那种项目,现在还缺五大块:
109
-
110
- 1. `Gateway`
111
- 2. `Channel Adapter`
112
- 3. `Plugin Runtime`
113
- 4. `Session Routing`
114
- 5. `Security + Ops`
115
-
116
- 下面逐个讲。
117
-
118
- ## 4. 正确的整体架构
119
-
120
- 建议你把项目理解成下面这 7 层。
121
-
122
- ```mermaid
123
- flowchart TD
124
- A["External Surfaces\nWeChat / Telegram / Slack / Web UI / CLI"] --> B["Gateway Layer"]
125
- B --> C["Routing Layer"]
126
- C --> D["Application Layer\nAgentAppService / Run Orchestrator"]
127
- D --> E["Kernel Layer\nStatelessAgent"]
128
- E --> F["Tool Runtime"]
129
- D --> G["Storage Layer\nRuns / Events / Messages / Context"]
130
- B --> H["Plugin Runtime"]
131
- H --> B
132
- H --> C
133
- H --> F
134
- ```
135
-
136
- ### 4.1 每层职责
137
-
138
- #### Surface Layer
139
-
140
- 这是用户和系统接触的入口:
141
-
142
- - 微信
143
- - Telegram
144
- - Slack
145
- - WebChat
146
- - CLI
147
- - 内部 HTTP API
148
-
149
- 这些入口不应该直接调用 `StatelessAgent`。
150
-
151
- 它们只能调用 `Gateway`。
152
-
153
- #### Gateway Layer
154
-
155
- 这是整个系统的控制平面。
156
-
157
- 负责:
158
-
159
- - 接受外部消息
160
- - 鉴权
161
- - 限流
162
- - 识别入口类型
163
- - 调用 Routing
164
- - 启动一次 Agent 执行
165
- - 把结果回发给渠道或前端
166
-
167
- `openclaw` 最像的部分就在这里。
168
-
169
- #### Routing Layer
170
-
171
- 负责把“某个渠道来的某条消息”映射到:
172
-
173
- - 哪个 `conversationId`
174
- - 哪个 `agentId`
175
- - 哪个 `workspace`
176
- - 哪个 `accountId`
177
- - 哪个 `threadId`
178
-
179
- 这是多渠道系统最容易一开始忽略、后面最难补的东西。
180
-
181
- #### Application Layer
182
-
183
- 这一层负责:
184
-
185
- - 读上下文
186
- - 组装执行输入
187
- - 调用 `StatelessAgent`
188
- - 把事件和消息写到数据库
189
- - 产生运行状态
190
-
191
- 你现在的 `AgentAppService` 已经基本属于这一层。
192
-
193
- #### Kernel Layer
194
-
195
- 只做一件事:
196
-
197
- > 给我消息和工具,我来推理、决定是否调用工具、产出消息和事件。
198
-
199
- 这就是 `StatelessAgent`。
200
-
201
- #### Tool Runtime
202
-
203
- 负责:
204
-
205
- - 工具注册
206
- - 工具权限
207
- - 工具确认
208
- - 工具执行
209
- - 工具幂等
210
- - 工具输出流
211
-
212
- #### Storage Layer
213
-
214
- 负责:
215
-
216
- - runs
217
- - events
218
- - messages
219
- - context_messages
220
- - run_logs
221
- - routing bindings
222
- - channel accounts
223
- - pairing / allowlist
224
-
225
- ## 5. 你应该如何映射现有 agent-v4
226
-
227
- 下面是“现有代码 -> 目标系统角色”的映射表。
228
-
229
- | 现有模块 | 角色 | 保留还是重写 |
230
- | --- | --- | --- |
231
- | `agent/index.ts` | Kernel | 保留 |
232
- | `app/agent-app-service.ts` | Application Orchestrator | 保留并扩展 |
233
- | `app/ports.ts` | App Ports | 保留 |
234
- | `app/sqlite-agent-app-store.ts` | 本地存储适配器 | 保留并扩展 |
235
- | `tool/tool-manager.ts` | Tool Runtime | 保留并扩展 |
236
- | `tool/task-*` | 子任务 / 子代理能力 | 保留 |
237
- | `docs/cli-app-layer/*` | 现有应用层文档 | 保留 |
238
- | 新增 `gateway/*` | Gateway 控制平面 | 新增 |
239
- | 新增 `channels/*` | 外部渠道适配器 | 新增 |
240
- | 新增 `plugins/*` | 插件系统 | 新增 |
241
- | 新增 `routing/*` | 会话路由 | 新增 |
242
- | 新增 `security/*` | 安全和策略 | 新增 |
243
-
244
- ## 6. 推荐目录结构
245
-
246
- 建议在 `src/agent-v4` 下面逐步长成下面这样:
247
-
248
- ```text
249
- src/agent-v4/
250
- agent/ # 无状态内核,保留
251
- app/ # 执行编排,保留并扩展
252
- tool/ # 工具系统,保留并扩展
253
- gateway/ # 新增:HTTP/WS/Webhook 控制平面
254
- channels/ # 新增:各平台接入
255
- base/
256
- webchat/
257
- telegram/
258
- wechat/
259
- slack/
260
- plugins/ # 新增:插件加载与注册
261
- routing/ # 新增:conversation / agent / account 路由
262
- security/ # 新增:auth、allowlist、pairing、rate limit
263
- surfaces/ # 可选:CLI / web / bot 入站聚合
264
- docs/
265
- ```
266
-
267
- 对于一个刚开始做后端的人,我建议你先不要追求一步到位。
268
-
269
- 先从最小结构开始:
270
-
271
- ```text
272
- src/agent-v4/
273
- agent/
274
- app/
275
- tool/
276
- gateway/
277
- channels/
278
- routing/
279
- security/
280
- ```
281
-
282
- 等跑通以后,再补 `plugins/`。
283
-
284
- ## 7. 最核心的新概念:Gateway
285
-
286
- 如果说 `StatelessAgent` 是大脑,那 `Gateway` 就是神经中枢。
287
-
288
- ### 7.1 Gateway 负责什么
289
-
290
- - 提供 HTTP API
291
- - 提供 WebSocket 或 SSE 实时事件
292
- - 接受外部 webhook
293
- - 管理渠道适配器的生命周期
294
- - 管理插件加载
295
- - 管理运行时鉴权
296
- - 调用 `AgentAppService`
297
- - 把执行结果回送给渠道
298
-
299
- ### 7.2 一个最小 Gateway 需要哪些接口
300
-
301
- 建议先设计成下面这样:
302
-
303
- ```ts
304
- export interface GatewayServer {
305
- start(): Promise<void>;
306
- stop(): Promise<void>;
307
- }
308
-
309
- export interface GatewayDeps {
310
- appService: AgentAppService;
311
- router: ConversationRouter;
312
- channelRegistry: ChannelRegistry;
313
- auth: GatewayAuthService;
314
- rateLimit: RateLimitService;
315
- }
316
- ```
317
-
318
- ### 7.3 最小 HTTP API
319
-
320
- 第一阶段只做这些接口就够了:
321
-
322
- - `POST /api/runs`
323
- 触发一次会话执行
324
- - `GET /api/runs/:executionId`
325
- 查询一次执行状态
326
- - `GET /api/conversations/:conversationId/messages`
327
- 查看会话消息
328
- - `GET /api/conversations/:conversationId/events`
329
- 查看会话事件流
330
- - `POST /api/webhooks/:channelId`
331
- 接收入站渠道消息
332
-
333
- ### 7.4 实时能力
334
-
335
- 建议先做 SSE,再做 WebSocket。
336
-
337
- 原因:
338
-
339
- - SSE 更简单
340
- - 服务端推送 run 事件足够用了
341
- - 适合你现在这种“后端初学 + Node.js”阶段
342
-
343
- 等你把系统跑稳了,再考虑 WS。
344
-
345
- ## 8. 最核心的新概念:Channel Adapter
346
-
347
- 这部分决定了你将来怎么接微信、Telegram、企业微信。
348
-
349
- ### 8.1 一个渠道适配器到底是什么
350
-
351
- 它不是 Agent。
352
-
353
- 它只是把外部平台消息翻译成统一格式,再把结果翻译回平台格式。
354
-
355
- 它应该只关心:
356
-
357
- - 怎么收消息
358
- - 怎么发消息
359
- - 怎么登录 / 配对
360
- - 怎么健康检查
361
-
362
- ### 8.2 建议统一的入站消息格式
363
-
364
- ```ts
365
- export interface InboundChannelMessage {
366
- channelId: string;
367
- accountId?: string;
368
- peerId: string;
369
- threadId?: string;
370
- senderId: string;
371
- senderName?: string;
372
- text?: string;
373
- media?: Array<{
374
- type: 'image' | 'audio' | 'video' | 'file';
375
- url?: string;
376
- mimeType?: string;
377
- name?: string;
378
- }>;
379
- rawEvent?: unknown;
380
- receivedAt: number;
381
- }
382
- ```
383
-
384
- ### 8.3 建议统一的出站消息格式
385
-
386
- ```ts
387
- export interface OutboundChannelMessage {
388
- conversationId: string;
389
- channelId: string;
390
- accountId?: string;
391
- peerId: string;
392
- threadId?: string;
393
- text: string;
394
- replyToMessageId?: string;
395
- }
396
- ```
397
-
398
- ### 8.4 建议的渠道接口
399
-
400
- ```ts
401
- export interface ChannelAdapter {
402
- id: string;
403
- start(ctx: ChannelRuntimeContext): Promise<void>;
404
- stop(): Promise<void>;
405
- send(message: OutboundChannelMessage): Promise<ChannelSendResult>;
406
- probe?(): Promise<ChannelProbeResult>;
407
- }
408
- ```
409
-
410
- ### 8.5 为什么微信不能写死在内核里
411
-
412
- 因为微信只是一个渠道。
413
-
414
- 今天你接微信:
415
-
416
- - 可能是 webhook
417
- - 可能是第三方协议
418
- - 可能是桌面自动化
419
-
420
- 明天你接 Telegram:
421
-
422
- - 可能是 webhook
423
- - 可能是 bot API
424
-
425
- 这些都不应该污染 `StatelessAgent`。
426
-
427
- 正确做法是:
428
-
429
- - `StatelessAgent` 不知道微信是什么
430
- - `AgentAppService` 不知道微信 API 怎么调
431
- - 只有 `channels/wechat/*` 知道微信怎么接
432
-
433
- ## 9. 最核心的新概念:Session Routing
434
-
435
- 这部分是 `openclaw` 风格系统里最值钱也最容易做错的设计。
436
-
437
- ### 9.1 为什么一定要有 Routing
438
-
439
- 因为一个真实系统里,消息不是只有“用户输入一句话”这么简单。
440
-
441
- 同一个人可能:
442
-
443
- - 通过微信找你
444
- - 通过 Telegram 找你
445
- - 在群里艾特你
446
- - 在不同账号下找你
447
- - 在同一个平台的不同会话线程找你
448
-
449
- 你必须回答这几个问题:
450
-
451
- - 这些消息是不是同一个 `conversationId`
452
- - 是不是同一个 `agentId`
453
- - 需不需要共享上下文
454
- - 需不需要按群聊和私聊隔离
455
-
456
- ### 9.2 第一个版本的路由规则
457
-
458
- 刚开始不要太复杂,先用下面这套规则:
459
-
460
- #### 私聊
461
-
462
- ```text
463
- conversationId = dm:<channelId>:<accountId>:<peerId>
464
- ```
465
-
466
- #### 群聊
467
-
468
- ```text
469
- conversationId = group:<channelId>:<accountId>:<threadId or peerId>
470
- ```
471
-
472
- #### 指定 Agent
473
-
474
- 如果渠道配置里指定了 `agentId`,那就把消息路由给该 Agent。
475
-
476
- 如果没指定,就走默认 Agent。
477
-
478
- ### 9.3 将来再升级的路由规则
479
-
480
- 以后你可以支持:
481
-
482
- - 同一渠道不同账号路由到不同 Agent
483
- - 同一群不同关键词路由到不同 Agent
484
- - 同一个人跨渠道共享“用户画像”但不共享对话上下文
485
-
486
- 但这些都应该建立在“第一版规则稳定”之后。
487
-
488
- ## 10. Plugin Runtime 应该怎么做
489
-
490
- `openclaw` 很强的一点,是它不是把所有能力写死在主程序里。
491
-
492
- ### 10.1 插件系统的目标
493
-
494
- 让外部模块可以注册:
495
-
496
- - 渠道
497
- - HTTP 路由
498
- - 命令
499
- - 后台服务
500
- - Hook
501
-
502
- ### 10.2 你应该先做最小插件 API
503
-
504
- ```ts
505
- export interface GatewayPluginApi {
506
- registerChannel(adapter: ChannelAdapter): void;
507
- registerHttpRoute(route: HttpRoute): void;
508
- registerCommand(command: GatewayCommand): void;
509
- registerService(service: BackgroundService): void;
510
- }
511
-
512
- export interface GatewayPlugin {
513
- id: string;
514
- name: string;
515
- register(api: GatewayPluginApi): void | Promise<void>;
516
- }
517
- ```
518
-
519
- ### 10.3 为什么先不要一开始做太复杂
520
-
521
- 因为你是 Node.js 后端刚起步,插件系统一复杂,很容易一上来就陷入:
522
-
523
- - manifest 设计过度
524
- - sandbox 设计过度
525
- - 动态 import 兼容性
526
- - 生命周期混乱
527
-
528
- 所以建议三步走:
529
-
530
- 1. 先支持“本地代码插件”
531
- 2. 再支持“配置声明插件”
532
- 3. 最后再支持“包安装插件”
533
-
534
- ## 11. Security 需要从第一天就开始做
535
-
536
- 很多人一开始做 Agent 平台,只写功能,不写安全边界。
537
-
538
- 这会导致系统能跑,但不能上线。
539
-
540
- ### 11.1 第一版必须有的安全能力
541
-
542
- - webhook secret
543
- - basic token auth
544
- - sender allowlist
545
- - pairing code
546
- - rate limit
547
- - 工具权限控制
548
-
549
- ### 11.2 pairing 是什么
550
-
551
- 例如微信、Telegram、Slack 来了一个陌生人私信:
552
-
553
- - 不是直接让 Agent 执行
554
- - 先返回一个配对码
555
- - 你在后台或 CLI 确认后,这个 sender 才进入 allowlist
556
-
557
- 这能大幅降低“公开入口直接被陌生人调用”的风险。
558
-
559
- ### 11.3 工具权限不要交给 LLM 自己决定
560
-
561
- LLM 可以建议调用工具。
562
-
563
- 但是否允许执行,必须由系统策略层判断。
564
-
565
- 你现在的 `tool-manager.ts` 已经有这个方向,这是对的。
566
-
567
- 建议后面继续扩展成:
568
-
569
- - `guest`
570
- - `paired_user`
571
- - `owner`
572
- - `admin`
573
-
574
- 不同身份可以调用不同工具。
575
-
576
- ## 12. 存储层下一步应该扩什么
577
-
578
- 你现有的表已经很好了,但要做成 `openclaw` 风格项目,还需要补几类表。
579
-
580
- ### 12.1 conversations
581
-
582
- 记录会话元数据:
583
-
584
- - `conversation_id`
585
- - `channel_id`
586
- - `account_id`
587
- - `peer_id`
588
- - `thread_id`
589
- - `agent_id`
590
- - `workspace_path`
591
- - `status`
592
-
593
- ### 12.2 channel_accounts
594
-
595
- 记录渠道账号:
596
-
597
- - `channel_id`
598
- - `account_id`
599
- - `display_name`
600
- - `auth_state`
601
- - `config_json`
602
- - `enabled`
603
-
604
- ### 12.3 channel_pairings
605
-
606
- 记录陌生 sender 的配对状态:
607
-
608
- - `channel_id`
609
- - `account_id`
610
- - `sender_id`
611
- - `pair_code`
612
- - `status`
613
- - `expires_at`
614
-
615
- ### 12.4 sender_allowlist
616
-
617
- 记录允许访问的发送方:
618
-
619
- - `channel_id`
620
- - `account_id`
621
- - `sender_id`
622
- - `source`
623
- - `created_at`
624
-
625
- ### 12.5 route_bindings
626
-
627
- 记录“某类消息应该路由给谁”:
628
-
629
- - `channel_id`
630
- - `account_id`
631
- - `peer_id` 或 `thread_id`
632
- - `agent_id`
633
- - `conversation_id`
634
-
635
- ## 13. 推荐的第一版执行流程
636
-
637
- 下面是一个真实的“渠道消息 -> Agent 执行 -> 渠道回复”的流程。
638
-
639
- ```mermaid
640
- sequenceDiagram
641
- participant U as User
642
- participant C as Channel Adapter
643
- participant G as Gateway
644
- participant R as Router
645
- participant A as AgentAppService
646
- participant K as StatelessAgent
647
- participant T as Tool Runtime
648
- participant S as Store
649
-
650
- U->>C: Send message
651
- C->>G: InboundChannelMessage
652
- G->>G: auth + rate limit + allowlist
653
- G->>R: resolve conversationId / agentId
654
- R-->>G: routing result
655
- G->>A: runForeground(...)
656
- A->>S: create run + append user event
657
- A->>K: runStream(...)
658
- K->>T: execute tools if needed
659
- T-->>K: tool result
660
- K-->>A: assistant messages + events
661
- A->>S: append events + project messages
662
- A-->>G: final / streamed result
663
- G->>C: OutboundChannelMessage
664
- C->>U: reply
665
- ```
666
-
667
- ## 14. 对一个后端初学者来说,真正应该先写什么
668
-
669
- 这部分最重要。
670
-
671
- 不要一上来就写“微信插件”。
672
-
673
- 你应该按下面的顺序推进。
674
-
675
- ### Phase A:把 Gateway 跑起来
676
-
677
- 目标:
678
-
679
- - 一个 HTTP 服务能启动
680
- - 能调用 `AgentAppService`
681
- - 能保存 runs/events/messages
682
-
683
- 你要做的事:
684
-
685
- 1. 新建 `gateway/http-server.ts`
686
- 2. 暴露 `POST /api/runs`
687
- 3. 暴露 `GET /api/runs/:id`
688
- 4. 暴露 `GET /api/conversations/:id/messages`
689
-
690
- 验收标准:
691
-
692
- - 通过 HTTP 发一句话
693
- - 能收到结果
694
- - 数据库里能看到 run 和 event
695
-
696
- ### Phase B:把 WebChat 做出来
697
-
698
- 目标:
699
-
700
- - 先有一个最简单的 Web UI 或 Postman 流程
701
- - 让你能稳定调试整个系统
702
-
703
- 为什么先做这个:
704
-
705
- - 它最简单
706
- - 不涉及第三方平台认证
707
- - 可以快速验证 Gateway 和 Routing 设计对不对
708
-
709
- ### Phase C:加入 Routing
710
-
711
- 目标:
712
-
713
- - 相同 conversation 能自动带上下文
714
- - 不同 conversation 相互隔离
715
-
716
- 你要做的事:
717
-
718
- 1. 建 `conversations` 表
719
- 2. 实现 `ConversationRouter`
720
- 3. 实现 `ContextProviderPort.load()`
721
-
722
- ### Phase D:接入第一个真实渠道
723
-
724
- 建议优先选:
725
-
726
- - Telegram Bot
727
- - 企业微信 webhook
728
- - 自建 WebChat
729
-
730
- 不要先选微信个人号,原因是:
731
-
732
- - 接入方式不稳定
733
- - 依赖第三方协议或桌面自动化
734
- - 排障成本高
735
-
736
- ### Phase E:做插件系统
737
-
738
- 等你已经有:
739
-
740
- - Gateway
741
- - 一个渠道
742
- - 稳定路由
743
-
744
- 再做插件系统。
745
-
746
- 因为这时你已经知道:
747
-
748
- - 插件要注册什么
749
- - 生命周期长什么样
750
- - 哪些接口真的需要抽象
751
-
752
- ## 15. 微信在这个系统里应该放哪
753
-
754
- 微信不是核心层,不是应用层,也不是内核层。
755
-
756
- 它应该只属于:
757
-
758
- - `channels/wechat/*`
759
-
760
- - `plugins/wechat/*`
761
-
762
- ### 15.1 微信适配器应该负责什么
763
-
764
- - 登录 / 绑定
765
- - 收取入站消息
766
- - 把微信事件转换成 `InboundChannelMessage`
767
- - 把系统消息转换成微信发送接口调用
768
-
769
- ### 15.2 微信适配器不应该负责什么
770
-
771
- - 不负责拼上下文
772
- - 不负责决定 conversationId
773
- - 不负责做 Agent 执行
774
- - 不负责消息持久化
775
- - 不负责业务权限判定
776
-
777
- 这几点必须严格分开。
778
-
779
- ## 16. 你应该写的第一批 TypeScript 接口
780
-
781
- 如果你现在开始实现,我建议先落这几组接口。
782
-
783
- ### 16.1 Gateway
784
-
785
- ```ts
786
- export interface GatewayRequestContext {
787
- requestId: string;
788
- source: 'http' | 'webhook' | 'cli' | 'websocket';
789
- ip?: string;
790
- headers?: Record<string, string>;
791
- }
792
-
793
- export interface Gateway {
794
- handleInboundMessage(
795
- message: InboundChannelMessage,
796
- ctx: GatewayRequestContext
797
- ): Promise<void>;
798
- }
799
- ```
800
-
801
- ### 16.2 Routing
802
-
803
- ```ts
804
- export interface RoutingResult {
805
- conversationId: string;
806
- agentId: string;
807
- workspacePath?: string;
808
- }
809
-
810
- export interface ConversationRouter {
811
- resolveInbound(message: InboundChannelMessage): Promise<RoutingResult>;
812
- }
813
- ```
814
-
815
- ### 16.3 Channel Registry
816
-
817
- ```ts
818
- export interface ChannelRegistry {
819
- register(adapter: ChannelAdapter): void;
820
- get(channelId: string): ChannelAdapter | undefined;
821
- list(): ChannelAdapter[];
822
- }
823
- ```
824
-
825
- ### 16.4 Plugin Registry
826
-
827
- ```ts
828
- export interface PluginRegistry {
829
- loadAll(): Promise<void>;
830
- list(): GatewayPlugin[];
831
- }
832
- ```
833
-
834
- ### 16.5 Security
835
-
836
- ```ts
837
- export interface SenderAccessDecision {
838
- allowed: boolean;
839
- reason?: string;
840
- requiresPairing?: boolean;
841
- }
842
-
843
- export interface SenderAccessService {
844
- check(message: InboundChannelMessage): Promise<SenderAccessDecision>;
845
- }
846
- ```
847
-
848
- ## 17. 最推荐的最小开发路线
849
-
850
- 对于你当前阶段,我最推荐下面这条路线:
851
-
852
- 1. 保持 `StatelessAgent` 不动
853
- 2. 保持 `AgentAppService` 为应用编排核心
854
- 3. 新增一个最小 `gateway/`
855
- 4. 新增一个最小 `routing/`
856
- 5. 新增一个最小 `channels/webchat/`
857
- 6. 跑通一条完整链路
858
- 7. 再接 Telegram
859
- 8. 最后再考虑微信
860
-
861
- 这是最稳的路径。
862
-
863
- ## 18. 容易踩的坑
864
-
865
- ### 坑 1:把渠道逻辑写进 Agent
866
-
867
- 后果:
868
-
869
- - 以后每接一个平台都要改内核
870
- - 测试难
871
- - Bug 很难隔离
872
-
873
- 正确做法:
874
-
875
- - 渠道只做适配
876
-
877
- ### 坑 2:没有会话路由层
878
-
879
- 后果:
880
-
881
- - 群聊和私聊串上下文
882
- - 多账号串会话
883
- - 后期几乎无法修复
884
-
885
- 正确做法:
886
-
887
- - 先定义稳定的 `conversationId` 规则
888
-
889
- ### 坑 3:没有统一入站消息模型
890
-
891
- 后果:
892
-
893
- - 每个渠道都直接传自己的原始对象
894
- - 业务代码到处写 `if telegram ... if wechat ...`
895
-
896
- 正确做法:
897
-
898
- - 所有渠道先转成统一 `InboundChannelMessage`
899
-
900
- ### 坑 4:先做复杂插件系统
901
-
902
- 后果:
903
-
904
- - 抽象过早
905
- - 生命周期混乱
906
- - 调试困难
907
-
908
- 正确做法:
909
-
910
- - 先做 1 个内建渠道
911
- - 再抽象插件
912
-
913
- ### 坑 5:没有安全层
914
-
915
- 后果:
916
-
917
- - webhook 被刷
918
- - 陌生人直接驱动高权限工具
919
- - 平台上线风险很高
920
-
921
- 正确做法:
922
-
923
- - webhook secret
924
- - allowlist
925
- - pairing
926
- - rate limit
927
-
928
- ## 19. 这套方案和 openclaw 的关系
929
-
930
- 你不需要逐行模仿 `openclaw`。
931
-
932
- 你要模仿的是它的系统分层思想:
933
-
934
- - 用 `Gateway` 统一承接外部入口
935
- - 用 `Plugin` 注册扩展能力
936
- - 用 `Channel Adapter` 隔离平台差异
937
- - 用 `Routing` 隔离会话和 Agent
938
- - 用 `Kernel` 专注推理和工具调用
939
-
940
- 这才是 `openclaw` 风格项目真正值得学的地方。
941
-
942
- ## 20. 最终建议
943
-
944
- 对于你现在的代码和经验阶段,最合适的策略是:
945
-
946
- ### 现在就做
947
-
948
- - 补 `Gateway`
949
- - 补 `ConversationRouter`
950
- - 补 `conversations / pairings / allowlist` 表
951
- - 跑通 `WebChat -> Gateway -> AgentAppService -> StatelessAgent -> 回写消息`
952
-
953
- ### 下一步做
954
-
955
- - 接第一个真实 webhook 渠道
956
- - 做 sender access control
957
- - 做 SSE 事件流
958
-
959
- ### 最后做
960
-
961
- - 插件系统
962
- - 多账号
963
- - 多 Agent 路由
964
- - 微信
965
-
966
- ## 21. 一句话架构原则
967
-
968
- 以后你写代码时,始终记住这句话:
969
-
970
- > 渠道只负责接入,网关只负责编排,路由只负责定位,会话只负责上下文,Agent 内核只负责思考。
971
-
972
- 只要这条线不乱,你的项目就能稳定长大。