@bolloon/bolloon-agent 0.2.8 → 0.2.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 (268) hide show
  1. package/README.md +467 -467
  2. package/bin/bolloon-cli.cjs +183 -183
  3. package/bin/bolloon.cjs +0 -0
  4. package/bin/bolloon.js +157 -0
  5. package/dist/agents/agent-manifest-protocol.js +0 -52
  6. package/dist/agents/constraint-layer.js +19 -19
  7. package/dist/agents/pi-sdk.js +287 -1213
  8. package/dist/agents/shell-guard.js +2 -2
  9. package/dist/agents/workflow-pivot-loop.js +2 -81
  10. package/dist/bollharness/src/scripts/deploy-guard.js +8 -8
  11. package/dist/bollharness-integration/context-router-judgment.js +4 -4
  12. package/dist/bollharness-integration/context-router.js +292 -292
  13. package/dist/bollharness-integration/gate-state-machine.js +13 -26
  14. package/dist/bollharness-integration/integration.js +0 -71
  15. package/dist/bollharness-integration/llm-judgment-engine.js +134 -134
  16. package/dist/bollharness-integration/skill-adapter.js +127 -52
  17. package/dist/bootstrap/context-collector.js +3 -6
  18. package/dist/bootstrap/lifecycle-hooks.js +1 -15
  19. package/dist/cli-entry.js +35 -39
  20. package/dist/constraint-runtime/src/_archive_helper.js +9 -0
  21. package/dist/constraint-runtime/src/agent/coordinator.js +48 -0
  22. package/dist/constraint-runtime/src/agent/index.js +1 -0
  23. package/dist/constraint-runtime/src/assistant/index.js +12 -0
  24. package/dist/constraint-runtime/src/bootstrap/index.js +12 -0
  25. package/dist/constraint-runtime/src/bootstrap_graph.js +13 -0
  26. package/dist/constraint-runtime/src/bridge/index.js +12 -0
  27. package/dist/constraint-runtime/src/buddy/index.js +12 -0
  28. package/dist/constraint-runtime/src/cli/index.js +12 -0
  29. package/dist/constraint-runtime/src/command_graph.js +10 -0
  30. package/dist/constraint-runtime/src/commands.js +60 -0
  31. package/dist/constraint-runtime/src/components/index.js +12 -0
  32. package/dist/constraint-runtime/src/constants/index.js +12 -0
  33. package/dist/constraint-runtime/src/constraint/budget.js +22 -0
  34. package/dist/constraint-runtime/src/constraint/index.js +2 -0
  35. package/dist/constraint-runtime/src/constraint/permission.js +20 -0
  36. package/dist/constraint-runtime/src/context.js +30 -0
  37. package/dist/constraint-runtime/src/coordinator/index.js +12 -0
  38. package/dist/constraint-runtime/src/cost_hook.js +4 -0
  39. package/dist/constraint-runtime/src/cost_tracker.js +8 -0
  40. package/dist/constraint-runtime/src/deferred_init.js +10 -0
  41. package/dist/constraint-runtime/src/direct_modes.js +6 -0
  42. package/dist/constraint-runtime/src/dynamic-tool-loader.js +85 -0
  43. package/dist/constraint-runtime/src/entrypoints/index.js +12 -0
  44. package/dist/constraint-runtime/src/execution_registry.js +44 -0
  45. package/dist/constraint-runtime/src/history.js +9 -0
  46. package/dist/constraint-runtime/src/hooks/index.js +12 -0
  47. package/dist/constraint-runtime/src/index.js +26 -0
  48. package/dist/constraint-runtime/src/ink.js +4 -0
  49. package/dist/constraint-runtime/src/keybindings/index.js +12 -0
  50. package/dist/constraint-runtime/src/memdir/index.js +12 -0
  51. package/dist/constraint-runtime/src/migrations/index.js +12 -0
  52. package/dist/constraint-runtime/src/models.js +1 -0
  53. package/dist/constraint-runtime/src/moreright/index.js +12 -0
  54. package/dist/constraint-runtime/src/native_ts/index.js +12 -0
  55. package/dist/constraint-runtime/src/output_styles/index.js +12 -0
  56. package/dist/constraint-runtime/src/parity_audit.js +12 -0
  57. package/dist/constraint-runtime/src/plugins/index.js +12 -0
  58. package/dist/constraint-runtime/src/port_manifest.js +11 -0
  59. package/dist/constraint-runtime/src/prefetch.js +9 -0
  60. package/dist/constraint-runtime/src/query.js +1 -0
  61. package/dist/constraint-runtime/src/remote/index.js +12 -0
  62. package/dist/constraint-runtime/src/remote_runtime.js +9 -0
  63. package/dist/constraint-runtime/src/runtime/index.js +1 -0
  64. package/dist/constraint-runtime/src/runtime/session.js +35 -0
  65. package/dist/constraint-runtime/src/schemas/index.js +12 -0
  66. package/dist/constraint-runtime/src/screens/index.js +12 -0
  67. package/dist/constraint-runtime/src/server/index.js +12 -0
  68. package/dist/constraint-runtime/src/services/index.js +12 -0
  69. package/dist/constraint-runtime/src/session_store.js +22 -0
  70. package/dist/constraint-runtime/src/setup.js +30 -0
  71. package/dist/constraint-runtime/src/skills/index.js +1 -0
  72. package/dist/constraint-runtime/src/skills/skill-registry.js +28 -0
  73. package/dist/constraint-runtime/src/state/index.js +12 -0
  74. package/dist/constraint-runtime/src/system_init.js +20 -0
  75. package/dist/constraint-runtime/src/thinking/engine.js +42 -0
  76. package/dist/constraint-runtime/src/thinking/index.js +1 -0
  77. package/dist/constraint-runtime/src/tool_pool.js +8 -0
  78. package/dist/constraint-runtime/src/tools/OpenCLI/execAdapter.js +7 -0
  79. package/dist/constraint-runtime/src/tools/OpenCLI/listAdapters.js +7 -0
  80. package/dist/constraint-runtime/src/tools/OpenCLI/runCommand.js +7 -0
  81. package/dist/constraint-runtime/src/tools/SafeSDK/confirmTransaction.js +6 -0
  82. package/dist/constraint-runtime/src/tools/SafeSDK/createTransaction.js +8 -0
  83. package/dist/constraint-runtime/src/tools/SafeSDK/executeTransaction.js +6 -0
  84. package/dist/constraint-runtime/src/tools/SafeSDK/getBalance.js +6 -0
  85. package/dist/constraint-runtime/src/tools/SafeSDK/getPendingTransactions.js +6 -0
  86. package/dist/constraint-runtime/src/tools/SafeSDK/proposeTransaction.js +6 -0
  87. package/dist/constraint-runtime/src/tools.js +80 -0
  88. package/dist/constraint-runtime/src/transcript.js +19 -0
  89. package/dist/constraint-runtime/src/types/index.js +12 -0
  90. package/dist/constraint-runtime/src/upstream_proxy/index.js +12 -0
  91. package/dist/constraint-runtime/src/utils/index.js +12 -0
  92. package/dist/constraint-runtime/src/vim/index.js +12 -0
  93. package/dist/constraint-runtime/src/voice/index.js +12 -0
  94. package/dist/constraint-runtime/tests/agent.test.js +16 -0
  95. package/dist/constraint-runtime/tests/constraint.test.js +41 -0
  96. package/dist/constraint-runtime/tests/skill.test.js +19 -0
  97. package/dist/constraint-runtime/tests/thinking.test.js +22 -0
  98. package/dist/context-compaction/auto-compact.js +7 -7
  99. package/dist/electron-preload.js +1 -18
  100. package/dist/electron-preload.js.map +1 -1
  101. package/dist/electron.js +168 -3
  102. package/dist/electron.js.map +1 -1
  103. package/dist/index.js +116 -136
  104. package/dist/llm/config-store.js +8 -24
  105. package/dist/llm/llm-judgment-client.js +102 -102
  106. package/dist/llm/pi-ai.js +85 -126
  107. package/dist/llm/system-prompt/layers/channel/local.md +14 -14
  108. package/dist/llm/system-prompt/layers/channel/p2p-agent.md +18 -18
  109. package/dist/llm/system-prompt/layers/channel/p2p-visitor.md +19 -19
  110. package/dist/llm/system-prompt/layers/core/artifacts_storage.md +89 -89
  111. package/dist/llm/system-prompt/layers/core/evenhandedness.md +21 -21
  112. package/dist/llm/system-prompt/layers/core/hibs_reminders.md +15 -15
  113. package/dist/llm/system-prompt/layers/core/identity.md +37 -37
  114. package/dist/llm/system-prompt/layers/core/knowledge.md +17 -17
  115. package/dist/llm/system-prompt/layers/core/memory_system.md +12 -12
  116. package/dist/llm/system-prompt/layers/core/network_filesystem.md +28 -28
  117. package/dist/llm/system-prompt/layers/core/refusal.md +37 -37
  118. package/dist/llm/system-prompt/layers/core/tone.md +31 -31
  119. package/dist/llm/system-prompt/layers/core/tools.thin.md +13 -13
  120. package/dist/llm/system-prompt/layers/core/wellbeing.md +41 -41
  121. package/dist/llm/system-prompt/layers/role/architect.md +20 -20
  122. package/dist/llm/system-prompt/layers/role/expert.md +19 -19
  123. package/dist/llm/system-prompt/layers/role/implementer.md +15 -15
  124. package/dist/llm/system-prompt/layers/role/security.md +15 -15
  125. package/dist/llm/system-prompt/layers/tool/artifacts.md +72 -72
  126. package/dist/llm/system-prompt/layers/tool/bash.md +25 -25
  127. package/dist/llm/system-prompt/layers/tool/hibs_api.md +171 -171
  128. package/dist/llm/system-prompt/layers/tool/image_search.md +70 -70
  129. package/dist/llm/system-prompt/layers/tool/manifest.md +89 -89
  130. package/dist/llm/system-prompt/layers/tool/mcp_apps.md +53 -53
  131. package/dist/llm/system-prompt/layers/tool/web_search.md +83 -83
  132. package/dist/llm/tool-manifest/ask_user_input.js +1 -1
  133. package/dist/llm/tool-manifest/bash.js +3 -3
  134. package/dist/llm/tool-manifest/create_file.js +4 -4
  135. package/dist/llm/tool-manifest/fetch_sports_data.js +3 -3
  136. package/dist/llm/tool-manifest/image_search.js +2 -2
  137. package/dist/llm/tool-manifest/mcp.js +2 -2
  138. package/dist/llm/tool-manifest/message_compose.js +3 -3
  139. package/dist/llm/tool-manifest/places.js +2 -2
  140. package/dist/llm/tool-manifest/present_files.js +1 -1
  141. package/dist/llm/tool-manifest/recipe.js +2 -2
  142. package/dist/llm/tool-manifest/str_replace.js +5 -5
  143. package/dist/llm/tool-manifest/view.js +3 -3
  144. package/dist/llm/tool-manifest/weather.js +4 -4
  145. package/dist/llm/tool-manifest/web.js +4 -4
  146. package/dist/pi-ecosystem-colony/index.js +365 -0
  147. package/dist/pi-ecosystem-judgment/causal-judge.js +51 -51
  148. package/dist/pi-ecosystem-judgment/distill-prompt.js +42 -42
  149. package/dist/pi-ecosystem-judgment/distillation.js +14 -14
  150. package/dist/pi-ecosystem-judgment/monitor-gate.js +28 -28
  151. package/dist/pi-ecosystem-judgment/value-injection.js +102 -102
  152. package/dist/security/context-router-tool.js +15 -15
  153. package/dist/security/tool-gate.js +0 -11
  154. package/dist/social/ant-colony/AdaptiveHeartbeat.js +101 -0
  155. package/dist/social/ant-colony/PheromoneEngine.js +227 -0
  156. package/dist/social/ant-colony/index.js +6 -0
  157. package/dist/social/ant-colony/types.js +24 -0
  158. package/dist/test/ai-judgment-test.js +80 -0
  159. package/dist/test/bollharness-integration.test.js +318 -0
  160. package/dist/test/channel-agent-multi-dialogue.js +205 -0
  161. package/dist/test/channel-heartbeat-agent-test.js +201 -0
  162. package/dist/test/constraint-layer.test.js +164 -0
  163. package/dist/test/diap-identity-test.js +172 -0
  164. package/dist/test/diap-quick-test.js +62 -0
  165. package/dist/test/global-shared-context.test.js +315 -0
  166. package/dist/test/harness-judgment-injection.test.js +246 -0
  167. package/dist/test/harness-workflow-integrator-test.js +228 -0
  168. package/dist/test/human-value-store.test.js +243 -0
  169. package/dist/test/hybrid-integration-test.js +118 -0
  170. package/dist/test/hybrid-messenger-verify.js +55 -0
  171. package/dist/test/iroh-bistream-debug.js +38 -0
  172. package/dist/test/iroh-communication.test.js +66 -0
  173. package/dist/test/iroh-debug-test.js +57 -0
  174. package/dist/test/iroh-diap-test.js +71 -0
  175. package/dist/test/iroh-direct-connect.js +55 -0
  176. package/dist/test/iroh-e2e-fixed.js +89 -0
  177. package/dist/test/iroh-e2e-same-process.js +63 -0
  178. package/dist/test/iroh-e2e.js +66 -0
  179. package/dist/test/iroh-final-e2e.js +72 -0
  180. package/dist/test/iroh-relay-test.js +37 -0
  181. package/dist/test/iroh-simple-test.js +41 -0
  182. package/dist/test/iroh-transport-verify.js +54 -0
  183. package/dist/test/iroh-transport.test.js +37 -0
  184. package/dist/test/iroh-two-nodes.js +70 -0
  185. package/dist/test/iroh-verify.js +44 -0
  186. package/dist/test/judgment-decision.test.js +219 -0
  187. package/dist/test/llm-judgment-integration.test.js +220 -0
  188. package/dist/test/p2p-agent-complex-dialogue.js +385 -0
  189. package/dist/test/p2p-agent-dialogue.js +341 -0
  190. package/dist/test/p2p-agent-full-bidirectional.js +510 -0
  191. package/dist/test/p2p-agent-harness-flow.js +437 -0
  192. package/dist/test/p2p-agent-harness-single.js +143 -0
  193. package/dist/test/p2p-ai-dialogue-test.js +318 -0
  194. package/dist/test/p2p-cid-connect-test.js +195 -0
  195. package/dist/test/p2p-connect-receiver.js +69 -0
  196. package/dist/test/p2p-doc-transfer.js +110 -0
  197. package/dist/test/p2p-identity-page-test.js +77 -0
  198. package/dist/test/p2p-iroh-test.js +171 -0
  199. package/dist/test/p2p-minimal-test.js +241 -0
  200. package/dist/test/p2p-node-1.js +148 -0
  201. package/dist/test/p2p-node-2.js +148 -0
  202. package/dist/test/p2p-server.js +281 -0
  203. package/dist/test/p2p-two-nodes-test.js +438 -0
  204. package/dist/test/pi-sdk.test.js +44 -0
  205. package/dist/test/set-persona.js +40 -0
  206. package/dist/test/simple.test.js +9 -0
  207. package/dist/test/storage-integration.test.js +150 -0
  208. package/dist/test/subagent-manager.test.js +276 -0
  209. package/dist/test/test-gate-flow.test.js +81 -0
  210. package/dist/test/workflow-engine.test.js +87 -0
  211. package/dist/test/workflow-pivot-loop.test.js +246 -0
  212. package/dist/web/api-config.html +520 -520
  213. package/dist/web/client.js +2917 -3791
  214. package/dist/web/components/p2p/index.js +234 -276
  215. package/dist/web/components/wallet-viem.mjs +118 -118
  216. package/dist/web/index.html +374 -373
  217. package/dist/web/manifest.json +20 -20
  218. package/dist/web/server.js +23 -775
  219. package/dist/web/style.css +4737 -4737
  220. package/dist/web/ui/message-renderer.js +373 -451
  221. package/dist/web/ui/step-timeline.js +255 -351
  222. package/package.json +160 -157
  223. package/scripts/build-cli.js +216 -0
  224. package/scripts/build-web.ts +125 -0
  225. package/scripts/postinstall.js +153 -0
  226. package/bin/bolloon-daemon.sh +0 -207
  227. package/bin/ipfs +0 -0
  228. package/dist/agents/chat-segmenter.js +0 -298
  229. package/dist/agents/judgment-protocol.js +0 -479
  230. package/dist/agents/parse-tool-call.js +0 -304
  231. package/dist/agents/peer-manifest-loader.js +0 -210
  232. package/dist/agents/react-loop.js +0 -120
  233. package/dist/agents/session-store.js +0 -171
  234. package/dist/agents/tool-registry.js +0 -136
  235. package/dist/bootstrap/chat-archiver.js +0 -276
  236. package/dist/bootstrap/memory-compressor.js +0 -170
  237. package/dist/bootstrap/persona-loader.js +0 -94
  238. package/dist/electron/config.js +0 -16
  239. package/dist/electron/config.js.map +0 -1
  240. package/dist/electron/dialogs.js +0 -71
  241. package/dist/electron/dialogs.js.map +0 -1
  242. package/dist/electron/first-run.js +0 -129
  243. package/dist/electron/first-run.js.map +0 -1
  244. package/dist/electron/ipc.js +0 -16
  245. package/dist/electron/ipc.js.map +0 -1
  246. package/dist/electron/logger.js +0 -77
  247. package/dist/electron/logger.js.map +0 -1
  248. package/dist/electron/main.js +0 -60
  249. package/dist/electron/main.js.map +0 -1
  250. package/dist/electron/menu.js +0 -140
  251. package/dist/electron/menu.js.map +0 -1
  252. package/dist/electron/paths.js +0 -33
  253. package/dist/electron/paths.js.map +0 -1
  254. package/dist/electron/server.js +0 -74
  255. package/dist/electron/server.js.map +0 -1
  256. package/dist/electron/tray.js +0 -73
  257. package/dist/electron/tray.js.map +0 -1
  258. package/dist/electron/window.js +0 -69
  259. package/dist/electron/window.js.map +0 -1
  260. package/dist/network/local-inbox-bus.js +0 -73
  261. package/dist/network/p2p-outbox.js +0 -161
  262. package/dist/network/peer-fs.js +0 -420
  263. package/dist/network/peer-resource-bridge.js +0 -216
  264. package/dist/web/components/p2p/P2PModal.js +0 -188
  265. package/dist/web/components/p2p/p2p-modal.js +0 -664
  266. package/dist/web/components/p2p/p2p-tools.js +0 -248
  267. package/dist/web/input-validator.js +0 -103
  268. package/dist/web/util/safe-name.js +0 -32
@@ -0,0 +1,510 @@
1
+ /**
2
+ * P2P Agent Full Bidirectional HTTP Response Test
3
+ * 测试完整双向对话流:HTTP 请求-响应模式
4
+ *
5
+ * 运行: npx tsx src/test/p2p-agent-full-bidirectional.ts
6
+ */
7
+ import { config } from 'dotenv';
8
+ import express from 'express';
9
+ import { createServer } from 'http';
10
+ import crypto from 'crypto';
11
+ config();
12
+ const PORT_ALICE = 8401;
13
+ const PORT_BOB = 8402;
14
+ const REQUEST_TIMEOUT_MS = 10000;
15
+ class HarnessCore {
16
+ executionLog = [];
17
+ decide(content) {
18
+ const lower = content.toLowerCase();
19
+ // Gate 1: 架构设计
20
+ if (lower.includes('架构') || lower.includes('设计') || lower.includes('方案')) {
21
+ return {
22
+ shouldCall: true,
23
+ gate: 1,
24
+ reason: '检测到架构设计相关请求',
25
+ skills: ['arch', 'lead'],
26
+ result: '[Gate 1] 建议采用分层架构:表现层、业务层、数据层分离'
27
+ };
28
+ }
29
+ // Gate 2: 代码审查
30
+ if (lower.includes('review') || lower.includes('检查') || lower.includes('审核') || lower.includes('代码')) {
31
+ return {
32
+ shouldCall: true,
33
+ gate: 2,
34
+ reason: '检测到代码审查请求',
35
+ skills: ['arch', 'guardian-fixer'],
36
+ result: '[Gate 2] 建议添加输入验证和错误处理机制'
37
+ };
38
+ }
39
+ // Gate 4: 安全检查
40
+ if (lower.includes('安全') || lower.includes('权限') || lower.includes('认证')) {
41
+ return {
42
+ shouldCall: true,
43
+ gate: 4,
44
+ reason: '检测到安全相关请求',
45
+ skills: ['arch', 'guardian-fixer'],
46
+ result: '[Gate 4] 建议实现 JWT token 过期和刷新机制'
47
+ };
48
+ }
49
+ // Gate 5: 任务分解
50
+ if (lower.includes('任务') || lower.includes('分解') || lower.includes('计划')) {
51
+ return {
52
+ shouldCall: true,
53
+ gate: 5,
54
+ reason: '检测到任务规划请求',
55
+ skills: ['task-arch', 'crystal-learn'],
56
+ result: '[Gate 5] 已分解为 4 个子任务,按优先级排序'
57
+ };
58
+ }
59
+ // Gate 7: 代码实现
60
+ if (lower.includes('实现') || lower.includes('写代码') || lower.includes('开发')) {
61
+ return {
62
+ shouldCall: true,
63
+ gate: 7,
64
+ reason: '检测到代码实现请求',
65
+ skills: ['harness-eng', 'crystal-learn'],
66
+ result: '[Gate 7] 建议使用策略模式重构业务逻辑'
67
+ };
68
+ }
69
+ // Gate 8: 测试验证
70
+ if (lower.includes('测试') || lower.includes('验证')) {
71
+ return {
72
+ shouldCall: true,
73
+ gate: 8,
74
+ reason: '检测到测试验证请求',
75
+ skills: ['harness-eng', 'harness-eng-test'],
76
+ result: '[Gate 8] 建议优先测试核心业务逻辑'
77
+ };
78
+ }
79
+ return {
80
+ shouldCall: false,
81
+ gate: 0,
82
+ reason: '普通对话,无需 Harness',
83
+ skills: [],
84
+ result: ''
85
+ };
86
+ }
87
+ execute(gate, content) {
88
+ const decision = this.decide(content);
89
+ if (!decision.shouldCall) {
90
+ return {
91
+ success: true,
92
+ gate: 0,
93
+ skills: [],
94
+ result: '',
95
+ message: '无需 Harness 处理',
96
+ followUpRequired: false
97
+ };
98
+ }
99
+ this.executionLog.push({ gate: decision.gate, timestamp: Date.now(), input: content });
100
+ // 根据 Gate 生成更详细的响应
101
+ let detailedResult = '';
102
+ let followUpRequired = false;
103
+ let followUpSuggestion;
104
+ switch (gate) {
105
+ case 1:
106
+ detailedResult = `${decision.result}\n\n详细建议:\n1. 使用依赖注入降低耦合\n2. 引入接口隔离原则\n3. 考虑使用策略模式处理变化点`;
107
+ followUpRequired = true;
108
+ followUpSuggestion = '需要我进一步分析具体的模块设计吗?';
109
+ break;
110
+ case 2:
111
+ detailedResult = `${decision.result}\n\n审查要点:\n1. 检查边界条件处理\n2. 验证错误处理路径\n3. 确保资源正确释放`;
112
+ followUpRequired = true;
113
+ followUpSuggestion = '需要我帮你 review 具体的代码段吗?';
114
+ break;
115
+ case 4:
116
+ detailedResult = `${decision.result}\n\n安全建议:\n1. 使用 HTTPS 加密传输\n2. 实现 token 过期机制\n3. 添加二次验证层`;
117
+ followUpRequired = true;
118
+ followUpSuggestion = '需要我生成安全检查清单吗?';
119
+ break;
120
+ case 5:
121
+ detailedResult = `${decision.result}\n\n任务分解:\n1. 登录模块 (高优先级)\n2. 注册模块 (高优先级)\n3. 权限管理 (中优先级)\n4. 测试集成 (中优先级)`;
122
+ followUpRequired = false;
123
+ break;
124
+ case 7:
125
+ detailedResult = `${decision.result}\n\n实现计划:\n1. 定义接口契约\n2. 实现核心逻辑\n3. 添加单元测试`;
126
+ followUpRequired = true;
127
+ followUpSuggestion = '需要我帮你实现哪个部分?';
128
+ break;
129
+ case 8:
130
+ detailedResult = `${decision.result}\n\n测试策略:\n1. 单元测试 (覆盖率 80%)\n2. 集成测试\n3. E2E 测试`;
131
+ followUpRequired = true;
132
+ followUpSuggestion = '需要我生成测试用例吗?';
133
+ break;
134
+ default:
135
+ detailedResult = decision.result;
136
+ }
137
+ return {
138
+ success: true,
139
+ gate: decision.gate,
140
+ skills: decision.skills,
141
+ result: detailedResult,
142
+ message: `Gate ${decision.gate} 处理完成`,
143
+ followUpRequired,
144
+ followUpSuggestion
145
+ };
146
+ }
147
+ getExecutionLog() {
148
+ return [...this.executionLog];
149
+ }
150
+ }
151
+ class HTTPSessionManager {
152
+ pendingRequests = new Map();
153
+ responseHandlers = new Map();
154
+ agentPort;
155
+ constructor(agentPort) {
156
+ this.agentPort = agentPort;
157
+ }
158
+ createRequest(type, payload, fromPort) {
159
+ const requestId = crypto.randomUUID();
160
+ const timeout = setTimeout(() => {
161
+ this.failRequest(requestId, new Error('Request timeout'));
162
+ }, REQUEST_TIMEOUT_MS);
163
+ this.pendingRequests.set(requestId, {
164
+ requestId,
165
+ type,
166
+ payload,
167
+ fromPort,
168
+ timestamp: Date.now(),
169
+ timeout
170
+ });
171
+ return requestId;
172
+ }
173
+ completeRequest(requestId, response) {
174
+ const pending = this.pendingRequests.get(requestId);
175
+ if (pending) {
176
+ clearTimeout(pending.timeout);
177
+ this.pendingRequests.delete(requestId);
178
+ const handler = this.responseHandlers.get(requestId);
179
+ if (handler) {
180
+ handler(response);
181
+ this.responseHandlers.delete(requestId);
182
+ }
183
+ }
184
+ }
185
+ failRequest(requestId, error) {
186
+ const pending = this.pendingRequests.get(requestId);
187
+ if (pending) {
188
+ clearTimeout(pending.timeout);
189
+ this.pendingRequests.delete(requestId);
190
+ const handler = this.responseHandlers.get(requestId);
191
+ if (handler) {
192
+ handler({
193
+ requestId,
194
+ type: 'error',
195
+ payload: error.message,
196
+ from: '',
197
+ timestamp: Date.now(),
198
+ requiresHarness: false,
199
+ followUpRequired: false
200
+ });
201
+ this.responseHandlers.delete(requestId);
202
+ }
203
+ }
204
+ }
205
+ onResponse(requestId, handler) {
206
+ this.responseHandlers.set(requestId, handler);
207
+ }
208
+ getPendingRequests() {
209
+ return Array.from(this.pendingRequests.values());
210
+ }
211
+ clear() {
212
+ for (const req of this.pendingRequests.values()) {
213
+ clearTimeout(req.timeout);
214
+ }
215
+ this.pendingRequests.clear();
216
+ this.responseHandlers.clear();
217
+ }
218
+ }
219
+ class Agent {
220
+ id = crypto.randomUUID();
221
+ name;
222
+ port;
223
+ harness = new HarnessCore();
224
+ sessionManager;
225
+ messages = [];
226
+ peerPort = null;
227
+ constructor(name, port) {
228
+ this.name = name;
229
+ this.port = port;
230
+ this.sessionManager = new HTTPSessionManager(port);
231
+ }
232
+ async start() {
233
+ const app = express();
234
+ app.use(express.json());
235
+ // 健康检查
236
+ app.get('/health', (req, res) => {
237
+ res.json({
238
+ id: this.id,
239
+ name: this.name,
240
+ port: this.port,
241
+ messageCount: this.messages.length,
242
+ pendingRequests: this.sessionManager.getPendingRequests().length
243
+ });
244
+ });
245
+ // 发现端点
246
+ app.get('/discovery', (req, res) => {
247
+ res.json({
248
+ id: this.id,
249
+ name: this.name,
250
+ port: this.port,
251
+ capabilities: ['http-response', 'harness']
252
+ });
253
+ });
254
+ // 接收请求并发送响应
255
+ app.post('/request', async (req, res) => {
256
+ const { requestId, fromName, type, content, context } = req.body;
257
+ console.log(`\n📨 [${this.name}] 收到请求 from ${fromName}:`);
258
+ console.log(` Type: ${type}`);
259
+ console.log(` Content: "${content.substring(0, 50)}..."`);
260
+ // 处理请求
261
+ const decision = this.harness.decide(content);
262
+ let response;
263
+ if (decision.shouldCall) {
264
+ console.log(`🧠 [${this.name}] 调用 Harness: Gate ${decision.gate}`);
265
+ const harnessResult = this.harness.execute(decision.gate, content);
266
+ response = {
267
+ requestId: requestId || crypto.randomUUID(),
268
+ type: 'harness-response',
269
+ payload: harnessResult.result,
270
+ from: this.name,
271
+ timestamp: Date.now(),
272
+ requiresHarness: true,
273
+ harnessResult: {
274
+ gate: harnessResult.gate,
275
+ skills: harnessResult.skills,
276
+ result: harnessResult.result
277
+ },
278
+ followUpRequired: harnessResult.followUpRequired,
279
+ followUpContext: harnessResult.followUpSuggestion
280
+ };
281
+ console.log(` 📋 Skills: ${harnessResult.skills.join(', ')}`);
282
+ console.log(` 📤 响应: ${harnessResult.result.substring(0, 50)}...`);
283
+ }
284
+ else {
285
+ console.log(`🧠 [${this.name}] 普通响应 (无需 Harness)`);
286
+ const naturalResponse = this.generateNaturalResponse(content);
287
+ response = {
288
+ requestId: requestId || crypto.randomUUID(),
289
+ type: 'natural-response',
290
+ payload: naturalResponse,
291
+ from: this.name,
292
+ timestamp: Date.now(),
293
+ requiresHarness: false,
294
+ followUpRequired: false
295
+ };
296
+ console.log(` 📤 响应: ${naturalResponse.substring(0, 50)}...`);
297
+ }
298
+ // 记录消息
299
+ this.messages.push({
300
+ id: crypto.randomUUID(),
301
+ requestId,
302
+ from: fromName,
303
+ to: this.name,
304
+ content,
305
+ timestamp: Date.now(),
306
+ response,
307
+ processed: true
308
+ });
309
+ // 发送响应
310
+ res.json(response);
311
+ });
312
+ // 接收响应 (处理来自其他智能体的响应)
313
+ app.post('/response', async (req, res) => {
314
+ const response = req.body;
315
+ console.log(`\n📥 [${this.name}] 收到响应 from ${response.from}:`);
316
+ console.log(` Type: ${response.type}`);
317
+ console.log(` Payload: "${response.payload.substring(0, 50)}..."`);
318
+ if (response.requiresHarness && response.harnessResult) {
319
+ console.log(`🧠 [${this.name}] 响应包含 Harness 结果: Gate ${response.harnessResult.gate}`);
320
+ console.log(` Skills: ${response.harnessResult.skills.join(', ')}`);
321
+ }
322
+ // 完成挂起的请求
323
+ if (response.requestId) {
324
+ this.sessionManager.completeRequest(response.requestId, response);
325
+ }
326
+ res.json({ ok: true });
327
+ });
328
+ const server = createServer(app);
329
+ return new Promise(resolve => {
330
+ server.listen(this.port, () => {
331
+ console.log(`✓ [${this.name}] 启动 on port ${this.port}`);
332
+ resolve();
333
+ });
334
+ });
335
+ }
336
+ generateNaturalResponse(content) {
337
+ const lower = content.toLowerCase();
338
+ if (lower.includes('你好') || lower.includes('hi') || lower.includes('hello')) {
339
+ return `你好!我是 ${this.name},有什么可以帮你的吗?`;
340
+ }
341
+ if (lower.includes('谢谢') || lower.includes('感谢')) {
342
+ return `不客气!还有其他需要帮助的吗?`;
343
+ }
344
+ if (lower.includes('?') || lower.includes('?')) {
345
+ return `这是个有趣的问题。让我想想...`;
346
+ }
347
+ const responses = [
348
+ '明白了!',
349
+ '好的,我理解。',
350
+ '收到,让我处理一下。',
351
+ '没问题!',
352
+ '好的,继续。'
353
+ ];
354
+ return responses[Math.floor(Math.random() * responses.length)];
355
+ }
356
+ setPeer(port) {
357
+ this.peerPort = port;
358
+ }
359
+ async sendRequest(targetPort, type, content, relatedRequestId) {
360
+ const requestId = crypto.randomUUID();
361
+ console.log(`\n📤 [${this.name}] 发送请求 to port ${targetPort}:`);
362
+ console.log(` RequestId: ${requestId}`);
363
+ console.log(` Type: ${type}`);
364
+ console.log(` Content: "${content.substring(0, 50)}..."`);
365
+ try {
366
+ const res = await fetch(`http://localhost:${targetPort}/request`, {
367
+ method: 'POST',
368
+ headers: { 'Content-Type': 'application/json' },
369
+ body: JSON.stringify({
370
+ requestId,
371
+ fromName: this.name,
372
+ type,
373
+ content,
374
+ context: relatedRequestId
375
+ })
376
+ });
377
+ const response = await res.json();
378
+ console.log(`\n✅ [${this.name}] 收到响应`);
379
+ // 记录消息
380
+ this.messages.push({
381
+ id: crypto.randomUUID(),
382
+ requestId,
383
+ from: this.name,
384
+ to: `port:${targetPort}`,
385
+ content,
386
+ timestamp: Date.now(),
387
+ response,
388
+ processed: true
389
+ });
390
+ return response;
391
+ }
392
+ catch (err) {
393
+ console.error(`❌ [${this.name}] 请求失败:`, err);
394
+ return null;
395
+ }
396
+ }
397
+ getMessages() {
398
+ return [...this.messages];
399
+ }
400
+ async stop() {
401
+ this.sessionManager.clear();
402
+ }
403
+ }
404
+ // ============================================================================
405
+ // 测试场景
406
+ // ============================================================================
407
+ async function runFullBidirectionalTest() {
408
+ console.log('\n========================================');
409
+ console.log(' P2P Agent Full Bidirectional HTTP Test');
410
+ console.log(' 场景: 完整双向对话流 + Harness 调用');
411
+ console.log('========================================\n');
412
+ const alice = new Agent('Alice', PORT_ALICE);
413
+ const bob = new Agent('Bob', PORT_BOB);
414
+ // 设置邻居关系
415
+ alice.setPeer(PORT_BOB);
416
+ bob.setPeer(PORT_ALICE);
417
+ console.log('━━━ 启动智能体 ━━━\n');
418
+ await alice.start();
419
+ await bob.start();
420
+ console.log('\n━━━ 对话 1: 架构分析 (需要 Harness + 跟进) ━━━\n');
421
+ const response1 = await alice.sendRequest(PORT_BOB, 'analysis', 'Bob,我们需要设计一个用户认证系统,请帮我分析一下架构。');
422
+ if (response1) {
423
+ console.log(`\n✅ [Alice] 收到 Bob 的响应:`);
424
+ console.log(` 类型: ${response1.type}`);
425
+ console.log(` 需要 Harness: ${response1.requiresHarness}`);
426
+ if (response1.harnessResult) {
427
+ console.log(` Gate: ${response1.harnessResult.gate}`);
428
+ console.log(` Skills: ${response1.harnessResult.skills.join(', ')}`);
429
+ }
430
+ }
431
+ await new Promise(r => setTimeout(r, 1000));
432
+ console.log('\n━━━ 对话 2: 代码审查 (需要 Harness + 跟进) ━━━\n');
433
+ const response2 = await bob.sendRequest(PORT_ALICE, 'review', 'Alice,帮我 review 一下登录模块的代码实现。');
434
+ if (response2) {
435
+ console.log(`\n✅ [Bob] 收到 Alice 的响应:`);
436
+ console.log(` 类型: ${response2.type}`);
437
+ console.log(` 需要 Harness: ${response2.requiresHarness}`);
438
+ if (response2.harnessResult) {
439
+ console.log(` Gate: ${response2.harnessResult.gate}`);
440
+ console.log(` Skills: ${response2.harnessResult.skills.join(', ')}`);
441
+ }
442
+ }
443
+ await new Promise(r => setTimeout(r, 1000));
444
+ console.log('\n━━━ 对话 3: 简单问候 (无需 Harness) ━━━\n');
445
+ const response3 = await alice.sendRequest(PORT_BOB, 'greeting', 'Bob,你好吗?最近项目进展如何?');
446
+ if (response3) {
447
+ console.log(`\n✅ [Alice] 收到 Bob 的响应:`);
448
+ console.log(` 类型: ${response3.type}`);
449
+ console.log(` 需要 Harness: ${response3.requiresHarness}`);
450
+ console.log(` 内容: ${response3.payload}`);
451
+ }
452
+ await new Promise(r => setTimeout(r, 1000));
453
+ console.log('\n━━━ 对话 4: 任务分解 (需要 Harness) ━━━\n');
454
+ const response4 = await bob.sendRequest(PORT_ALICE, 'planning', 'Alice,我们需要完成用户管理功能,请帮我分解一下任务。');
455
+ if (response4) {
456
+ console.log(`\n✅ [Bob] 收到 Alice 的响应:`);
457
+ console.log(` 类型: ${response4.type}`);
458
+ console.log(` 需要 Harness: ${response4.requiresHarness}`);
459
+ if (response4.harnessResult) {
460
+ console.log(` Gate: ${response4.harnessResult.gate}`);
461
+ console.log(` 内容: ${response4.harnessResult.result.substring(0, 80)}...`);
462
+ }
463
+ }
464
+ await new Promise(r => setTimeout(r, 1000));
465
+ console.log('\n━━━ 结果汇总 ━━━\n');
466
+ const aliceMessages = alice.getMessages();
467
+ const bobMessages = bob.getMessages();
468
+ console.log(`[Alice] 消息数: ${aliceMessages.length}`);
469
+ console.log(`[Bob] 消息数: ${bobMessages.length}`);
470
+ // 统计 Harness 调用
471
+ const harnessCalls = [...aliceMessages, ...bobMessages].filter(m => m.response?.requiresHarness);
472
+ console.log(`\nHarness 调用次数: ${harnessCalls.length}`);
473
+ console.log('\nHarness 调用详情:');
474
+ harnessCalls.forEach((call, i) => {
475
+ console.log(` ${i + 1}. [${call.from}] -> [${call.to}]`);
476
+ if (call.response?.harnessResult) {
477
+ console.log(` Gate: ${call.response.harnessResult.gate}`);
478
+ console.log(` Skills: ${call.response.harnessResult.skills.join(', ')}`);
479
+ }
480
+ });
481
+ // 展示完整对话流
482
+ console.log('\n━━━ 完整对话流 ━━━\n');
483
+ const allMessages = [...aliceMessages, ...bobMessages]
484
+ .sort((a, b) => a.timestamp - b.timestamp)
485
+ .slice(0, 20);
486
+ for (const msg of allMessages) {
487
+ const harnessIcon = msg.response?.requiresHarness ? '🧠' : ' ';
488
+ const gateInfo = msg.response?.harnessResult ? ` [Gate ${msg.response.harnessResult.gate}]` : '';
489
+ console.log(`${harnessIcon} [${msg.from}]${gateInfo}: ${msg.content.substring(0, 40)}...`);
490
+ }
491
+ // 健康检查
492
+ console.log('\n━━━ 最终状态 ━━━\n');
493
+ const aliceHealth = await fetch(`http://localhost:${PORT_ALICE}/health`).then(r => r.json());
494
+ const bobHealth = await fetch(`http://localhost:${PORT_BOB}/health`).then(r => r.json());
495
+ console.log(`[Alice] ID: ${aliceHealth.id.substring(0, 16)}...`);
496
+ console.log(`[Bob] ID: ${bobHealth.id.substring(0, 16)}...`);
497
+ console.log(`\n总消息数: ${aliceMessages.length + bobMessages.length}`);
498
+ console.log(`Harness 调用: ${harnessCalls.length} 次`);
499
+ // 判断测试成功
500
+ const success = harnessCalls.length >= 3;
501
+ console.log(`\n${success ? '✅' : '⚠️'} ${success ? '测试成功' : '测试部分成功'}`);
502
+ console.log('\n========================================\n');
503
+ // 清理
504
+ await alice.stop();
505
+ await bob.stop();
506
+ }
507
+ runFullBidirectionalTest().catch(err => {
508
+ console.error('测试失败:', err);
509
+ process.exit(1);
510
+ });