@renxqoo/renx-code 0.0.9 → 0.0.12
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.
- package/README.md +31 -143
- package/bin/renx.cjs +79 -42
- package/bin/renx.exe +0 -0
- package/package.json +10 -28
- package/src/App.tsx +0 -297
- package/src/agent/runtime/event-format.ts +0 -258
- package/src/agent/runtime/model-types.ts +0 -13
- package/src/agent/runtime/runtime.context-usage.test.ts +0 -192
- package/src/agent/runtime/runtime.error-handling.test.ts +0 -235
- package/src/agent/runtime/runtime.simple.test.ts +0 -16
- package/src/agent/runtime/runtime.test.ts +0 -296
- package/src/agent/runtime/runtime.ts +0 -875
- package/src/agent/runtime/runtime.usage-forwarding.test.ts +0 -228
- package/src/agent/runtime/source-modules.test.ts +0 -38
- package/src/agent/runtime/source-modules.ts +0 -370
- package/src/agent/runtime/tool-call-buffer.test.ts +0 -65
- package/src/agent/runtime/tool-call-buffer.ts +0 -60
- package/src/agent/runtime/tool-confirmation.test.ts +0 -56
- package/src/agent/runtime/tool-confirmation.ts +0 -15
- package/src/agent/runtime/types.ts +0 -99
- package/src/commands/slash-commands.test.ts +0 -216
- package/src/commands/slash-commands.ts +0 -64
- package/src/components/chat/assistant-reply.test.tsx +0 -47
- package/src/components/chat/assistant-reply.tsx +0 -136
- package/src/components/chat/assistant-segment.test.ts +0 -99
- package/src/components/chat/assistant-segment.tsx +0 -125
- package/src/components/chat/assistant-tool-group.tsx +0 -900
- package/src/components/chat/code-block.test.tsx +0 -206
- package/src/components/chat/code-block.tsx +0 -313
- package/src/components/chat/prompt-card.tsx +0 -81
- package/src/components/chat/segment-groups.test.ts +0 -52
- package/src/components/chat/segment-groups.ts +0 -106
- package/src/components/chat/turn-item.tsx +0 -39
- package/src/components/conversation-panel.tsx +0 -43
- package/src/components/file-mention-menu.tsx +0 -77
- package/src/components/file-picker-dialog.tsx +0 -206
- package/src/components/footer-hints.tsx +0 -75
- package/src/components/model-picker-dialog.tsx +0 -248
- package/src/components/prompt.tsx +0 -233
- package/src/components/slash-command-menu.tsx +0 -65
- package/src/components/tool-confirm-dialog-content.test.ts +0 -103
- package/src/components/tool-confirm-dialog-content.ts +0 -186
- package/src/components/tool-confirm-dialog.tsx +0 -187
- package/src/components/tool-display-config.ts +0 -119
- package/src/context-usage-regressions.test.ts +0 -26
- package/src/files/attachment-capabilities.test.ts +0 -30
- package/src/files/attachment-capabilities.ts +0 -50
- package/src/files/attachment-content.ts +0 -153
- package/src/files/file-mention-query.test.ts +0 -34
- package/src/files/file-mention-query.ts +0 -32
- package/src/files/prompt-display.ts +0 -13
- package/src/files/types.ts +0 -5
- package/src/files/workspace-files.ts +0 -61
- package/src/hooks/agent-event-handlers.test.ts +0 -207
- package/src/hooks/agent-event-handlers.ts +0 -196
- package/src/hooks/chat-local-replies.fixed.test.ts +0 -119
- package/src/hooks/chat-local-replies.test.ts +0 -153
- package/src/hooks/chat-local-replies.ts +0 -63
- package/src/hooks/turn-updater.test.ts +0 -70
- package/src/hooks/turn-updater.ts +0 -166
- package/src/hooks/use-agent-chat.context.test.ts +0 -10
- package/src/hooks/use-agent-chat.status.test.ts +0 -14
- package/src/hooks/use-agent-chat.test.ts +0 -80
- package/src/hooks/use-agent-chat.ts +0 -621
- package/src/hooks/use-file-mention-menu.ts +0 -196
- package/src/hooks/use-file-picker.ts +0 -185
- package/src/hooks/use-model-picker.ts +0 -196
- package/src/hooks/use-slash-command-menu.ts +0 -154
- package/src/index.tsx +0 -55
- package/src/runtime/clipboard.test.ts +0 -43
- package/src/runtime/clipboard.ts +0 -89
- package/src/runtime/exit.test.ts +0 -177
- package/src/runtime/exit.ts +0 -98
- package/src/runtime/runtime-support.test.ts +0 -31
- package/src/runtime/terminal-theme.test.ts +0 -55
- package/src/runtime/terminal-theme.ts +0 -196
- package/src/types/chat.ts +0 -32
- package/src/types/message-content.ts +0 -48
- package/src/ui/open-code-theme.ts +0 -176
- package/src/ui/opencode-markdown.ts +0 -211
- package/src/ui/theme.simple.test.ts +0 -52
- package/src/ui/theme.test.ts +0 -151
- package/src/ui/theme.ts +0 -152
- package/src/utils/time.test.ts +0 -144
- package/src/utils/time.ts +0 -7
- package/tsconfig.json +0 -30
- package/vendor/agent-root/src/agent/ENTERPRISE_ACCEPTANCE_CHECKLIST.md +0 -95
- package/vendor/agent-root/src/agent/ENTERPRISE_REALTIME.html +0 -1345
- package/vendor/agent-root/src/agent/ENTERPRISE_REALTIME.md +0 -1353
- package/vendor/agent-root/src/agent/ERROR_CONTRACT.md +0 -60
- package/vendor/agent-root/src/agent/TEST_COVERAGE_ANALYSIS.md +0 -278
- package/vendor/agent-root/src/agent/__test__/error-contract.test.ts +0 -72
- package/vendor/agent-root/src/agent/__test__/types.test.ts +0 -137
- package/vendor/agent-root/src/agent/agent/__test__/abort-runtime.test.ts +0 -83
- package/vendor/agent-root/src/agent/agent/__test__/callback-safety.test.ts +0 -34
- package/vendor/agent-root/src/agent/agent/__test__/compaction.test.ts +0 -323
- package/vendor/agent-root/src/agent/agent/__test__/concurrency.test.ts +0 -290
- package/vendor/agent-root/src/agent/agent/__test__/error-normalizer.test.ts +0 -377
- package/vendor/agent-root/src/agent/agent/__test__/error.test.ts +0 -212
- package/vendor/agent-root/src/agent/agent/__test__/fault-injection.test.ts +0 -295
- package/vendor/agent-root/src/agent/agent/__test__/index.test.ts +0 -3607
- package/vendor/agent-root/src/agent/agent/__test__/logger.test.ts +0 -35
- package/vendor/agent-root/src/agent/agent/__test__/message-utils.test.ts +0 -517
- package/vendor/agent-root/src/agent/agent/__test__/telemetry.test.ts +0 -97
- package/vendor/agent-root/src/agent/agent/__test__/timeout-budget.test.ts +0 -479
- package/vendor/agent-root/src/agent/agent/__test__/tool-call-merge.test.ts +0 -80
- package/vendor/agent-root/src/agent/agent/__test__/tool-execution-ledger.test.ts +0 -76
- package/vendor/agent-root/src/agent/agent/__test__/write-buffer.test.ts +0 -173
- package/vendor/agent-root/src/agent/agent/__test__/write-file-session.test.ts +0 -109
- package/vendor/agent-root/src/agent/agent/abort-runtime.ts +0 -71
- package/vendor/agent-root/src/agent/agent/callback-safety.ts +0 -33
- package/vendor/agent-root/src/agent/agent/compaction.ts +0 -291
- package/vendor/agent-root/src/agent/agent/concurrency.ts +0 -103
- package/vendor/agent-root/src/agent/agent/error-normalizer.ts +0 -190
- package/vendor/agent-root/src/agent/agent/error.ts +0 -198
- package/vendor/agent-root/src/agent/agent/index.ts +0 -1772
- package/vendor/agent-root/src/agent/agent/logger.ts +0 -65
- package/vendor/agent-root/src/agent/agent/message-utils.ts +0 -101
- package/vendor/agent-root/src/agent/agent/stream-events.ts +0 -61
- package/vendor/agent-root/src/agent/agent/telemetry.ts +0 -123
- package/vendor/agent-root/src/agent/agent/timeout-budget.ts +0 -227
- package/vendor/agent-root/src/agent/agent/tool-call-merge.ts +0 -111
- package/vendor/agent-root/src/agent/agent/tool-execution-ledger.ts +0 -164
- package/vendor/agent-root/src/agent/agent/write-buffer.ts +0 -188
- package/vendor/agent-root/src/agent/agent/write-file-session.ts +0 -238
- package/vendor/agent-root/src/agent/app/__test__/agent-app-service.test.ts +0 -1053
- package/vendor/agent-root/src/agent/app/__test__/minimal-agent-application.test.ts +0 -158
- package/vendor/agent-root/src/agent/app/__test__/sqlite-agent-app-store.test.ts +0 -437
- package/vendor/agent-root/src/agent/app/agent-app-service.ts +0 -748
- package/vendor/agent-root/src/agent/app/contracts.ts +0 -109
- package/vendor/agent-root/src/agent/app/index.ts +0 -5
- package/vendor/agent-root/src/agent/app/minimal-agent-application.ts +0 -151
- package/vendor/agent-root/src/agent/app/ports.ts +0 -72
- package/vendor/agent-root/src/agent/app/sqlite-agent-app-store.ts +0 -1182
- package/vendor/agent-root/src/agent/app/sqlite-client.ts +0 -177
- package/vendor/agent-root/src/agent/docs/cli-app-layer/00-README.md +0 -36
- package/vendor/agent-root/src/agent/docs/cli-app-layer/01-scope-and-goals.md +0 -33
- package/vendor/agent-root/src/agent/docs/cli-app-layer/02-architecture-overview.md +0 -40
- package/vendor/agent-root/src/agent/docs/cli-app-layer/03-domain-model-and-contracts.md +0 -91
- package/vendor/agent-root/src/agent/docs/cli-app-layer/04-ports-and-interfaces.md +0 -116
- package/vendor/agent-root/src/agent/docs/cli-app-layer/05-run-orchestration-and-state-machine.md +0 -52
- package/vendor/agent-root/src/agent/docs/cli-app-layer/06-cli-commands-and-ux.md +0 -53
- package/vendor/agent-root/src/agent/docs/cli-app-layer/07-storage-design-local.md +0 -52
- package/vendor/agent-root/src/agent/docs/cli-app-layer/08-error-and-observability.md +0 -40
- package/vendor/agent-root/src/agent/docs/cli-app-layer/09-security-and-policy-boundary.md +0 -19
- package/vendor/agent-root/src/agent/docs/cli-app-layer/10-test-plan-and-acceptance.md +0 -28
- package/vendor/agent-root/src/agent/docs/cli-app-layer/11-implementation-phases.md +0 -26
- package/vendor/agent-root/src/agent/docs/cli-app-layer/12-open-questions-and-risks.md +0 -30
- package/vendor/agent-root/src/agent/docs/cli-app-layer/13-sqlite-schema-fields-and-rationale.md +0 -567
- package/vendor/agent-root/src/agent/docs/cli-app-layer/14-project-flow-mermaid.md +0 -583
- package/vendor/agent-root/src/agent/docs/cli-app-layer/15-openclaw-style-project-blueprint.md +0 -972
- package/vendor/agent-root/src/agent/error-contract.ts +0 -154
- package/vendor/agent-root/src/agent/prompts/system.ts +0 -246
- package/vendor/agent-root/src/agent/prompts/system1.ts +0 -208
- package/vendor/agent-root/src/agent/storage/__test__/file-history-store.test.ts +0 -98
- package/vendor/agent-root/src/agent/storage/file-history-store.ts +0 -313
- package/vendor/agent-root/src/agent/storage/file-storage-config.ts +0 -94
- package/vendor/agent-root/src/agent/storage/file-system.ts +0 -31
- package/vendor/agent-root/src/agent/storage/file-write-service.ts +0 -21
- package/vendor/agent-root/src/agent/tool/__test__/base-tool.test.ts +0 -413
- package/vendor/agent-root/src/agent/tool/__test__/bash-policy.test.ts +0 -356
- package/vendor/agent-root/src/agent/tool/__test__/bash.mocked-coverage.test.ts +0 -375
- package/vendor/agent-root/src/agent/tool/__test__/bash.test.ts +0 -372
- package/vendor/agent-root/src/agent/tool/__test__/error.test.ts +0 -108
- package/vendor/agent-root/src/agent/tool/__test__/file-edit-tool.test.ts +0 -258
- package/vendor/agent-root/src/agent/tool/__test__/file-history-tools.test.ts +0 -121
- package/vendor/agent-root/src/agent/tool/__test__/file-read-tool.test.ts +0 -210
- package/vendor/agent-root/src/agent/tool/__test__/glob.test.ts +0 -139
- package/vendor/agent-root/src/agent/tool/__test__/grep.mocked-coverage.test.ts +0 -456
- package/vendor/agent-root/src/agent/tool/__test__/grep.test.ts +0 -192
- package/vendor/agent-root/src/agent/tool/__test__/lsp.test.ts +0 -300
- package/vendor/agent-root/src/agent/tool/__test__/outside-workspace-confirmation.test.ts +0 -214
- package/vendor/agent-root/src/agent/tool/__test__/path-security.test.ts +0 -336
- package/vendor/agent-root/src/agent/tool/__test__/skill-loader.test.ts +0 -494
- package/vendor/agent-root/src/agent/tool/__test__/skill-parser.test.ts +0 -543
- package/vendor/agent-root/src/agent/tool/__test__/skill-tool.test.ts +0 -172
- package/vendor/agent-root/src/agent/tool/__test__/task-concurrency-and-version.test.ts +0 -116
- package/vendor/agent-root/src/agent/tool/__test__/task-create-get-list-update.test.ts +0 -267
- package/vendor/agent-root/src/agent/tool/__test__/task-create.test.ts +0 -519
- package/vendor/agent-root/src/agent/tool/__test__/task-errors.test.ts +0 -225
- package/vendor/agent-root/src/agent/tool/__test__/task-output-blocking.test.ts +0 -223
- package/vendor/agent-root/src/agent/tool/__test__/task-output.test.ts +0 -184
- package/vendor/agent-root/src/agent/tool/__test__/task-parent-abort.test.ts +0 -287
- package/vendor/agent-root/src/agent/tool/__test__/task-real-runner-adapter.test.ts +0 -190
- package/vendor/agent-root/src/agent/tool/__test__/task-run-lifecycle.test.ts +0 -352
- package/vendor/agent-root/src/agent/tool/__test__/task-store-runner-branches.test.ts +0 -395
- package/vendor/agent-root/src/agent/tool/__test__/task-store.test.ts +0 -391
- package/vendor/agent-root/src/agent/tool/__test__/task-subagent-config-integration.test.ts +0 -176
- package/vendor/agent-root/src/agent/tool/__test__/task-subagent-config.test.ts +0 -68
- package/vendor/agent-root/src/agent/tool/__test__/task-tools-core-edges.test.ts +0 -630
- package/vendor/agent-root/src/agent/tool/__test__/task-tools-runtime-edges.test.ts +0 -732
- package/vendor/agent-root/src/agent/tool/__test__/task-types.test.ts +0 -494
- package/vendor/agent-root/src/agent/tool/__test__/task-utils-branches.test.ts +0 -175
- package/vendor/agent-root/src/agent/tool/__test__/tool-manager.test.ts +0 -505
- package/vendor/agent-root/src/agent/tool/__test__/types.test.ts +0 -55
- package/vendor/agent-root/src/agent/tool/__test__/web-fetch.test.ts +0 -244
- package/vendor/agent-root/src/agent/tool/__test__/web-search.test.ts +0 -290
- package/vendor/agent-root/src/agent/tool/__test__/write-file.test.ts +0 -368
- package/vendor/agent-root/src/agent/tool/base-tool.ts +0 -345
- package/vendor/agent-root/src/agent/tool/bash-policy.ts +0 -636
- package/vendor/agent-root/src/agent/tool/bash.ts +0 -688
- package/vendor/agent-root/src/agent/tool/error.ts +0 -131
- package/vendor/agent-root/src/agent/tool/file-edit-tool.ts +0 -264
- package/vendor/agent-root/src/agent/tool/file-history-list.ts +0 -103
- package/vendor/agent-root/src/agent/tool/file-history-restore.ts +0 -149
- package/vendor/agent-root/src/agent/tool/file-read-tool.ts +0 -211
- package/vendor/agent-root/src/agent/tool/glob.ts +0 -171
- package/vendor/agent-root/src/agent/tool/grep.ts +0 -496
- package/vendor/agent-root/src/agent/tool/lsp.ts +0 -481
- package/vendor/agent-root/src/agent/tool/path-security.ts +0 -117
- package/vendor/agent-root/src/agent/tool/search/common.ts +0 -153
- package/vendor/agent-root/src/agent/tool/skill/index.ts +0 -13
- package/vendor/agent-root/src/agent/tool/skill/loader.ts +0 -229
- package/vendor/agent-root/src/agent/tool/skill/parser.ts +0 -124
- package/vendor/agent-root/src/agent/tool/skill/types.ts +0 -27
- package/vendor/agent-root/src/agent/tool/skill-tool.ts +0 -143
- package/vendor/agent-root/src/agent/tool/task-create.ts +0 -186
- package/vendor/agent-root/src/agent/tool/task-errors.ts +0 -42
- package/vendor/agent-root/src/agent/tool/task-get.ts +0 -116
- package/vendor/agent-root/src/agent/tool/task-graph.ts +0 -78
- package/vendor/agent-root/src/agent/tool/task-list.ts +0 -141
- package/vendor/agent-root/src/agent/tool/task-mock-runner-adapter.ts +0 -232
- package/vendor/agent-root/src/agent/tool/task-output.ts +0 -223
- package/vendor/agent-root/src/agent/tool/task-parent-abort.ts +0 -115
- package/vendor/agent-root/src/agent/tool/task-real-runner-adapter.ts +0 -336
- package/vendor/agent-root/src/agent/tool/task-runner-adapter.ts +0 -55
- package/vendor/agent-root/src/agent/tool/task-stop.ts +0 -187
- package/vendor/agent-root/src/agent/tool/task-store.ts +0 -217
- package/vendor/agent-root/src/agent/tool/task-subagent-config.ts +0 -149
- package/vendor/agent-root/src/agent/tool/task-types.ts +0 -264
- package/vendor/agent-root/src/agent/tool/task-update.ts +0 -315
- package/vendor/agent-root/src/agent/tool/task.ts +0 -209
- package/vendor/agent-root/src/agent/tool/tool-manager.ts +0 -361
- package/vendor/agent-root/src/agent/tool/tool-prompts.ts +0 -242
- package/vendor/agent-root/src/agent/tool/types.ts +0 -116
- package/vendor/agent-root/src/agent/tool/web-fetch.ts +0 -227
- package/vendor/agent-root/src/agent/tool/web-search.ts +0 -208
- package/vendor/agent-root/src/agent/tool/write-file.ts +0 -497
- package/vendor/agent-root/src/agent/types.ts +0 -232
- package/vendor/agent-root/src/agent/utils/__tests__/index.test.ts +0 -18
- package/vendor/agent-root/src/agent/utils/__tests__/message-utils.test.ts +0 -610
- package/vendor/agent-root/src/agent/utils/__tests__/message.test.ts +0 -223
- package/vendor/agent-root/src/agent/utils/__tests__/token.test.ts +0 -42
- package/vendor/agent-root/src/agent/utils/index.ts +0 -16
- package/vendor/agent-root/src/agent/utils/message.ts +0 -171
- package/vendor/agent-root/src/agent/utils/token.ts +0 -28
- package/vendor/agent-root/src/config/__tests__/load-config-to-env.test.ts +0 -238
- package/vendor/agent-root/src/config/__tests__/loader.test.ts +0 -361
- package/vendor/agent-root/src/config/__tests__/runtime.test.ts +0 -88
- package/vendor/agent-root/src/config/index.ts +0 -55
- package/vendor/agent-root/src/config/loader.ts +0 -494
- package/vendor/agent-root/src/config/paths.ts +0 -30
- package/vendor/agent-root/src/config/runtime.ts +0 -163
- package/vendor/agent-root/src/config/types.ts +0 -96
- package/vendor/agent-root/src/logger/index.ts +0 -57
- package/vendor/agent-root/src/logger/logger.ts +0 -819
- package/vendor/agent-root/src/logger/types.ts +0 -150
- package/vendor/agent-root/src/providers/__tests__/errors.test.ts +0 -441
- package/vendor/agent-root/src/providers/__tests__/index.test.ts +0 -16
- package/vendor/agent-root/src/providers/__tests__/openai-compatible.options.test.ts +0 -318
- package/vendor/agent-root/src/providers/__tests__/openai-compatible.test.ts +0 -600
- package/vendor/agent-root/src/providers/__tests__/registry.test.ts +0 -523
- package/vendor/agent-root/src/providers/__tests__/responses-adapter.test.ts +0 -298
- package/vendor/agent-root/src/providers/adapters/__tests__/anthropic.test.ts +0 -354
- package/vendor/agent-root/src/providers/adapters/__tests__/kimi.test.ts +0 -58
- package/vendor/agent-root/src/providers/adapters/__tests__/standard.test.ts +0 -261
- package/vendor/agent-root/src/providers/adapters/anthropic.ts +0 -572
- package/vendor/agent-root/src/providers/adapters/base.ts +0 -131
- package/vendor/agent-root/src/providers/adapters/kimi.ts +0 -48
- package/vendor/agent-root/src/providers/adapters/responses.ts +0 -732
- package/vendor/agent-root/src/providers/adapters/standard.ts +0 -120
- package/vendor/agent-root/src/providers/http/__tests__/client.timeout.test.ts +0 -313
- package/vendor/agent-root/src/providers/http/client.ts +0 -289
- package/vendor/agent-root/src/providers/http/stream-parser.ts +0 -109
- package/vendor/agent-root/src/providers/index.ts +0 -76
- package/vendor/agent-root/src/providers/kimi-headers.ts +0 -177
- package/vendor/agent-root/src/providers/openai-compatible.ts +0 -387
- package/vendor/agent-root/src/providers/registry/model-config.ts +0 -477
- package/vendor/agent-root/src/providers/registry/provider-factory.ts +0 -127
- package/vendor/agent-root/src/providers/registry.ts +0 -135
- package/vendor/agent-root/src/providers/types/api.ts +0 -284
- package/vendor/agent-root/src/providers/types/config.ts +0 -58
- package/vendor/agent-root/src/providers/types/errors.ts +0 -323
- package/vendor/agent-root/src/providers/types/index.ts +0 -72
- package/vendor/agent-root/src/providers/types/provider.ts +0 -45
- package/vendor/agent-root/src/providers/types/registry.ts +0 -68
package/vendor/agent-root/src/agent/docs/cli-app-layer/15-openclaw-style-project-blueprint.md
DELETED
|
@@ -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
|
-
只要这条线不乱,你的项目就能稳定长大。
|