@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,385 @@
1
+ /**
2
+ * P2P Agent Complex Multi-Turn Dialogue Test
3
+ * 复杂的智能体多轮对话,基于判断力动态调用 Harness
4
+ *
5
+ * 运行: npx tsx src/test/p2p-agent-complex-dialogue.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 = 6001;
13
+ const PORT_BOB = 6002;
14
+ class HarnessCore {
15
+ conversationHistory = [];
16
+ // 基于对话上下文做判断
17
+ decide(content, conversationSoFar) {
18
+ const context = conversationSoFar.join(' ').toLowerCase();
19
+ // 检查对话历史中的关键阶段
20
+ const hasArchitectureDiscussion = context.includes('架构') || context.includes('设计');
21
+ const hasCodeReview = context.includes('代码') || context.includes('review');
22
+ const hasTaskPlanning = context.includes('任务') || context.includes('分解') || context.includes('计划');
23
+ const hasImplementation = context.includes('实现') || context.includes('写代码') || context.includes('开发');
24
+ const hasTesting = context.includes('测试') || context.includes('验证');
25
+ // 当前消息的关键词
26
+ const currentKeywords = this.extractKeywords(content);
27
+ // 根据对话阶段和当前消息决定
28
+ if (hasArchitectureDiscussion && currentKeywords.some(k => ['检查', '审核', 'review', '分析'].includes(k))) {
29
+ return {
30
+ shouldCall: true,
31
+ gate: 2, // 代码审查 Gate
32
+ reason: '当前处于架构讨论阶段,需要代码审查',
33
+ skills: ['arch', 'guardian-fixer'],
34
+ result: '[Gate 2 - 代码审查] 建议检查接口设计是否符合单一职责原则'
35
+ };
36
+ }
37
+ if (hasTaskPlanning && currentKeywords.some(k => ['分配', '开始', '执行', '完成'].includes(k))) {
38
+ return {
39
+ shouldCall: true,
40
+ gate: 5, // 任务分解 Gate
41
+ reason: '任务规划阶段,需要任务分解',
42
+ skills: ['task-arch', 'crystal-learn'],
43
+ result: '[Gate 5 - 任务分解] 已分解为 4 个子任务,按优先级排序'
44
+ };
45
+ }
46
+ if (hasImplementation && currentKeywords.some(k => ['检查', 'review', '优化', '改进'].includes(k))) {
47
+ return {
48
+ shouldCall: true,
49
+ gate: 7, // 执行 Gate
50
+ reason: '实现阶段,需要代码修改和优化',
51
+ skills: ['harness-eng', 'crystal-learn'],
52
+ result: '[Gate 7 - 代码修改] 建议使用策略模式重构条件判断'
53
+ };
54
+ }
55
+ if (hasTesting || currentKeywords.some(k => ['测试', '验证', '检查'].includes(k))) {
56
+ return {
57
+ shouldCall: true,
58
+ gate: 8, // 测试部署 Gate
59
+ reason: '需要执行测试验证',
60
+ skills: ['harness-eng', 'harness-eng-test'],
61
+ result: '[Gate 8 - 测试] 建议添加单元测试覆盖边界情况'
62
+ };
63
+ }
64
+ if (currentKeywords.some(k => ['架构', '设计', '方案', '结构'].includes(k))) {
65
+ return {
66
+ shouldCall: true,
67
+ gate: 1, // 架构设计 Gate
68
+ reason: '涉及架构设计,需要架构检查',
69
+ skills: ['arch', 'lead'],
70
+ result: '[Gate 1 - 架构设计] 建议采用分层架构,核心业务与基础设施分离'
71
+ };
72
+ }
73
+ if (currentKeywords.some(k => ['安全', '权限', '认证'].includes(k))) {
74
+ return {
75
+ shouldCall: true,
76
+ gate: 4, // 安全验证 Gate
77
+ reason: '涉及安全需求,需要安全检查',
78
+ skills: ['arch', 'guardian-fixer'],
79
+ result: '[Gate 4 - 安全检查] 建议实现 JWT token 过期机制和刷新策略'
80
+ };
81
+ }
82
+ return {
83
+ shouldCall: false,
84
+ gate: 0,
85
+ reason: '普通对话,无需 Harness',
86
+ skills: [],
87
+ result: ''
88
+ };
89
+ }
90
+ extractKeywords(content) {
91
+ const keywords = [
92
+ '分析', '架构', '设计', '检查', '审核', 'review', '分解',
93
+ '任务', '计划', '分配', '实现', '写代码', '开发',
94
+ '测试', '验证', '优化', '改进', '安全', '权限', '认证',
95
+ '开始', '执行', '完成', '方案', '结构'
96
+ ];
97
+ return keywords.filter(k => content.includes(k));
98
+ }
99
+ record(agent, content, gate) {
100
+ this.conversationHistory.push({ agent, content, gate });
101
+ }
102
+ getHistory() {
103
+ return [...this.conversationHistory];
104
+ }
105
+ }
106
+ class Agent {
107
+ id = crypto.randomUUID();
108
+ name;
109
+ port;
110
+ harness = new HarnessCore();
111
+ dialogHistory = [];
112
+ peerPort = null;
113
+ constructor(name, port) {
114
+ this.name = name;
115
+ this.port = port;
116
+ }
117
+ async start() {
118
+ const app = express();
119
+ app.use(express.json());
120
+ app.get('/health', (req, res) => {
121
+ res.json({
122
+ id: this.id,
123
+ name: this.name,
124
+ port: this.port,
125
+ dialogCount: this.dialogHistory.length
126
+ });
127
+ });
128
+ app.get('/discovery', (req, res) => {
129
+ res.json({ id: this.id, name: this.name, port: this.port });
130
+ });
131
+ app.get('/dialog', (req, res) => {
132
+ res.json(this.dialogHistory);
133
+ });
134
+ app.post('/message', async (req, res) => {
135
+ const { fromName, content, context } = req.body;
136
+ console.log(`\n📨 [${this.name}] 收到 [${fromName}]: "${content}"`);
137
+ // 构建对话上下文
138
+ const conversationContext = this.dialogHistory
139
+ .slice(-5)
140
+ .map(d => `[${d.speaker}]: ${d.content}`)
141
+ .join(' | ');
142
+ // 做判断
143
+ const decision = this.harness.decide(content, this.dialogHistory.map(d => d.content));
144
+ let response = '';
145
+ let harnessCalled = false;
146
+ if (decision.shouldCall) {
147
+ console.log(`\n🧠 [${this.name}] 判断: 需要调用 Harness`);
148
+ console.log(` 原因: ${decision.reason}`);
149
+ console.log(` Gate: ${decision.gate}, Skills: ${decision.skills.join(', ')}`);
150
+ harnessCalled = true;
151
+ response = this.generateHarnessResponse(decision, fromName);
152
+ // 记录到 Harness 历史
153
+ this.harness.record(this.name, content, decision.gate);
154
+ }
155
+ else {
156
+ console.log(`\n🧠 [${this.name}] 判断: 无需 Harness (${decision.reason})`);
157
+ response = this.generateNaturalResponse(content, fromName);
158
+ }
159
+ // 记录对话
160
+ this.dialogHistory.push({
161
+ speaker: fromName,
162
+ content,
163
+ requiresHarness: harnessCalled,
164
+ harnessDecision: harnessCalled ? decision : undefined,
165
+ timestamp: Date.now()
166
+ });
167
+ this.dialogHistory.push({
168
+ speaker: this.name,
169
+ content: response,
170
+ requiresHarness: harnessCalled,
171
+ harnessDecision: harnessCalled ? decision : undefined,
172
+ timestamp: Date.now()
173
+ });
174
+ // 发送回复
175
+ if (this.peerPort) {
176
+ await this.sendToPeer(this.peerPort, this.name, response, this.dialogHistory.map(d => d.content));
177
+ }
178
+ res.json({
179
+ ok: true,
180
+ response,
181
+ requiresHarness: harnessCalled,
182
+ gate: decision.gate,
183
+ skills: decision.skills
184
+ });
185
+ });
186
+ const server = createServer(app);
187
+ return new Promise(resolve => {
188
+ server.listen(this.port, () => {
189
+ console.log(`✓ [${this.name}] 启动 on port ${this.port}`);
190
+ resolve();
191
+ });
192
+ });
193
+ }
194
+ generateHarnessResponse(decision, fromName) {
195
+ const responses = {
196
+ 1: [
197
+ `关于架构设计,我调用了 Harness 进行分析。\n${decision.result}\n\n建议我们采用分层架构,将业务逻辑、数据访问和接口层分离。`,
198
+ `Harness Gate 1 分析完成:\n${decision.result}\n\n我们可以使用依赖注入来降低耦合度。`
199
+ ],
200
+ 2: [
201
+ `正在进行代码审查,调用 Harness...\n${decision.result}\n\n建议添加错误边界处理。`,
202
+ `Harness Gate 2 代码审查:\n${decision.result}\n\n需要优化命名规范和添加注释。`
203
+ ],
204
+ 4: [
205
+ `安全检查启动,Harness 分析中...\n${decision.result}\n\n建议实现双因素认证。`,
206
+ `Harness Gate 4 安全评估:\n${decision.result}\n\n需要加强输入验证。`
207
+ ],
208
+ 5: [
209
+ `任务分解中,Harness 分析...\n${decision.result}\n\n子任务 1: 登录页面\n子任务 2: 认证服务\n子任务 3: 数据库设计\n子任务 4: API 集成`,
210
+ `Harness Gate 5 任务规划:\n${decision.result}\n\n优先级已分配。`
211
+ ],
212
+ 7: [
213
+ `代码优化建议来自 Harness:\n${decision.result}\n\n我现在开始重构代码。`,
214
+ `Harness Gate 7 执行建议:\n${decision.result}\n\n正在应用这些改进...`
215
+ ],
216
+ 8: [
217
+ `测试策略由 Harness 制定:\n${decision.result}\n\n建议先写单元测试再写集成测试。`,
218
+ `Harness Gate 8 测试计划:\n${decision.result}\n\n测试覆盖率目标 80%。`
219
+ ]
220
+ };
221
+ const responsesForGate = responses[decision.gate] || [decision.result];
222
+ return responsesForGate[Math.floor(Math.random() * responsesForGate.length)];
223
+ }
224
+ generateNaturalResponse(content, fromName) {
225
+ const lower = content.toLowerCase();
226
+ if (lower.includes('你好') || lower.includes('hi') || lower.includes('hello')) {
227
+ return `你好 ${fromName}!我是 ${this.name},有什么我可以帮你的吗?`;
228
+ }
229
+ if (lower.includes('好的') || lower.includes('同意') || lower.includes('可以')) {
230
+ return `好的,我明白了。继续吧!`;
231
+ }
232
+ if (lower.includes('?') || lower.includes('?')) {
233
+ return `这是个有趣的问题。让我想想...目前我还没有足够的信息来回答,但我们可以继续讨论。`;
234
+ }
235
+ const casualResponses = [
236
+ `嗯,我理解你的意思。`,
237
+ `好的,继续说说你的想法。`,
238
+ `明白了,还有什么要补充的吗?`,
239
+ `有道理,我们继续。`,
240
+ `好的,听起来不错。`
241
+ ];
242
+ return casualResponses[Math.floor(Math.random() * casualResponses.length)];
243
+ }
244
+ async sendToPeer(port, fromName, content, context) {
245
+ try {
246
+ await fetch(`http://localhost:${port}/message`, {
247
+ method: 'POST',
248
+ headers: { 'Content-Type': 'application/json' },
249
+ body: JSON.stringify({ fromName, content, context })
250
+ });
251
+ }
252
+ catch (err) {
253
+ console.log(`[${this.name}] 发送失败`);
254
+ }
255
+ }
256
+ setPeer(port) {
257
+ this.peerPort = port;
258
+ }
259
+ getDialogHistory() {
260
+ return [...this.dialogHistory];
261
+ }
262
+ }
263
+ // ============================================================================
264
+ // 复杂对话场景
265
+ // ============================================================================
266
+ async function runComplexDialogue() {
267
+ console.log('\n========================================');
268
+ console.log(' P2P Agent 复杂多轮对话测试');
269
+ console.log(' 场景: 智能体协作完成项目需求分析');
270
+ console.log('========================================\n');
271
+ const alice = new Agent('Alice', PORT_ALICE);
272
+ const bob = new Agent('Bob', PORT_BOB);
273
+ // 设置邻居关系
274
+ alice.setPeer(PORT_BOB);
275
+ bob.setPeer(PORT_ALICE);
276
+ console.log('━━━ 启动智能体 ━━━\n');
277
+ await alice.start();
278
+ await bob.start();
279
+ // 定义对话脚本
280
+ const dialogueScript = [
281
+ { from: 'Alice', to: 'Bob', content: 'Bob,我们需要为新项目设计一个用户认证系统。', expectHarness: false },
282
+ { from: 'Bob', to: 'Alice', content: '好的,让我们先分析需求。包含哪些功能?', expectHarness: false },
283
+ { from: 'Alice', to: 'Bob', content: '需要登录、注册、找回密码,还有权限管理。', expectHarness: false },
284
+ { from: 'Bob', to: 'Alice', content: '明白了,这些功能需要什么级别的安全性?', expectHarness: false },
285
+ { from: 'Alice', to: 'Bob', content: '需要处理敏感数据,所以安全性很重要。帮我检查一下架构设计。', expectHarness: true },
286
+ { from: 'Bob', to: 'Alice', content: '我来分析一下架构设计,看看有没有安全风险。', expectHarness: true },
287
+ { from: 'Alice', to: 'Bob', content: '架构看起来不错。现在帮我 review 一下登录模块的代码。', expectHarness: true },
288
+ { from: 'Bob', to: 'Alice', content: '好的,让我检查登录模块的代码实现。', expectHarness: true },
289
+ { from: 'Alice', to: 'Bob', content: '代码审查发现了一些问题,需要优化错误处理。', expectHarness: false },
290
+ { from: 'Bob', to: 'Alice', content: '同意,错误处理需要改进。', expectHarness: false },
291
+ { from: 'Alice', to: 'Bob', content: '好的,现在我们来分解任务,制定开发计划。', expectHarness: true },
292
+ { from: 'Bob', to: 'Alice', content: '我来帮你把任务分解成可执行的小块。', expectHarness: true },
293
+ { from: 'Alice', to: 'Bob', content: '任务分解得很好。我们开始实现第一个任务吧。', expectHarness: false },
294
+ { from: 'Bob', to: 'Alice', content: '好的,开始实现。完成后记得写测试。', expectHarness: false },
295
+ { from: 'Alice', to: 'Bob', content: '实现完成。帮我验证一下代码质量。', expectHarness: true },
296
+ { from: 'Bob', to: 'Alice', content: '我来执行测试验证代码质量。', expectHarness: true },
297
+ { from: 'Alice', to: 'Bob', content: '测试通过了!项目进展顺利。', expectHarness: false },
298
+ { from: 'Bob', to: 'Alice', content: '太好了!继续加油。', expectHarness: false },
299
+ ];
300
+ console.log('━━━ 开始多轮对话 ━━━\n');
301
+ for (let i = 0; i < dialogueScript.length; i++) {
302
+ const { from, to, content, expectHarness } = dialogueScript[i];
303
+ // 判断当前消息由哪个智能体处理
304
+ const targetPort = from === 'Alice' ? PORT_BOB : PORT_ALICE;
305
+ console.log(`━━━ 第 ${Math.floor(i / 2) + 1} 轮 ━━━`);
306
+ console.log(`[${from}] >>> ${content}`);
307
+ try {
308
+ const resp = await fetch(`http://localhost:${targetPort}/message`, {
309
+ method: 'POST',
310
+ headers: { 'Content-Type': 'application/json' },
311
+ body: JSON.stringify({
312
+ fromName: from,
313
+ content,
314
+ context: []
315
+ })
316
+ });
317
+ const result = await resp.json();
318
+ console.log(`\n[${to}] 处理结果:`);
319
+ if (result.requiresHarness) {
320
+ console.log(` 🧠 调用 Harness: Gate ${result.gate}`);
321
+ console.log(` 📋 Skills: ${result.skills?.join(', ') || '无'}`);
322
+ }
323
+ else {
324
+ console.log(` 🧠 普通对话`);
325
+ }
326
+ console.log(` 📤 回复: ${result.response?.substring(0, 80)}...`);
327
+ // 如果是 Harness 调用,等待一下再继续
328
+ if (result.requiresHarness) {
329
+ await new Promise(r => setTimeout(r, 500));
330
+ }
331
+ }
332
+ catch (err) {
333
+ console.log(` ❌ 发送失败:`, err);
334
+ }
335
+ // 轮次之间稍作停顿
336
+ await new Promise(r => setTimeout(r, 300));
337
+ }
338
+ console.log('\n━━━ 对话汇总 ━━━\n');
339
+ const aliceHistory = alice.getDialogHistory();
340
+ const bobHistory = bob.getDialogHistory();
341
+ console.log(`[Alice] 对话数: ${aliceHistory.length}`);
342
+ console.log(`[Bob] 对话数: ${bobHistory.length}`);
343
+ // 统计 Harness 调用
344
+ const harnessCalls = [...aliceHistory, ...bobHistory].filter(d => d.requiresHarness);
345
+ console.log(`\nHarness 调用次数: ${harnessCalls.length}`);
346
+ console.log('\nHarness 调用详情:');
347
+ harnessCalls.forEach((call, i) => {
348
+ console.log(` ${i + 1}. [${call.speaker}] Gate ${call.harnessDecision?.gate}`);
349
+ console.log(` 原因: ${call.harnessDecision?.reason}`);
350
+ console.log(` Skills: ${call.harnessDecision?.skills?.join(', ')}`);
351
+ });
352
+ // 显示对话流程图
353
+ console.log('\n━━━ 对话流程图 ━━━\n');
354
+ const uniqueTurns = Math.floor(dialogueScript.length / 2);
355
+ for (let i = 0; i < uniqueTurns; i++) {
356
+ const userMsg = aliceHistory.find((d, idx) => idx === i * 2);
357
+ const botMsg = bobHistory.find((d, idx) => idx === i * 2 + 1);
358
+ if (userMsg) {
359
+ const harnessIcon = userMsg.requiresHarness ? '🧠' : ' ';
360
+ console.log(`${harnessIcon} [Alice]: ${userMsg.content.substring(0, 40)}...`);
361
+ }
362
+ if (botMsg) {
363
+ const harnessIcon = botMsg.requiresHarness ? '🧠' : ' ';
364
+ console.log(`${harnessIcon} [Bob]: ${botMsg.content.substring(0, 40)}...`);
365
+ }
366
+ console.log('');
367
+ }
368
+ // 健康检查
369
+ console.log('━━━ 最终状态 ━━━\n');
370
+ const aliceHealth = await fetch(`http://localhost:${PORT_ALICE}/health`).then(r => r.json());
371
+ const bobHealth = await fetch(`http://localhost:${PORT_BOB}/health`).then(r => r.json());
372
+ console.log(`[Alice] 对话数: ${aliceHealth.dialogCount}`);
373
+ console.log(`[Bob] 对话数: ${bobHealth.dialogCount}`);
374
+ // 判断测试成功
375
+ const expectedHarnessCalls = 6; // 期望至少 6 次 Harness 调用
376
+ const success = harnessCalls.length >= expectedHarnessCalls;
377
+ console.log('\n========================================');
378
+ console.log(` ${success ? '✅ 测试成功' : '⚠️ 测试部分成功'}`);
379
+ console.log(` Harness 调用: ${harnessCalls.length} / ${expectedHarnessCalls} (期望值)`);
380
+ console.log('========================================\n');
381
+ }
382
+ runComplexDialogue().catch(err => {
383
+ console.error('测试失败:', err);
384
+ process.exit(1);
385
+ });