@bolloon/bolloon-agent 0.4.5 → 0.4.6

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 (206) hide show
  1. package/README.md +135 -135
  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/constraint-layer.js +19 -19
  6. package/dist/agents/judgment-protocol.js +14 -14
  7. package/dist/agents/pi-sdk-tools.js +62 -45
  8. package/dist/agents/pi-sdk-types.js +12 -12
  9. package/dist/agents/pi-sdk.js +103 -90
  10. package/dist/agents/skill-organizer.js +19 -19
  11. package/dist/agents/skill-writer.js +15 -3
  12. package/dist/agents/workflow-pivot-loop.js +13 -3
  13. package/dist/bollharness/src/scripts/deploy-guard.js +8 -8
  14. package/dist/bollharness-integration/context-router-judgment.js +4 -4
  15. package/dist/bollharness-integration/context-router.js +292 -292
  16. package/dist/bollharness-integration/gate-state-machine.js +13 -13
  17. package/dist/bollharness-integration/llm-judgment-engine.js +134 -134
  18. package/dist/bollharness-integration/skill-adapter.js +21 -21
  19. package/dist/bootstrap/chat-archiver.js +14 -14
  20. package/dist/bootstrap/context-os.js +24 -24
  21. package/dist/bootstrap/memory-compressor.js +14 -14
  22. package/dist/cli/ink-app.js +18 -0
  23. package/dist/cli-entry.js +36 -36
  24. package/dist/context-compaction/auto-compact.js +7 -7
  25. package/dist/electron/first-run.js +54 -54
  26. package/dist/electron-build/electron/first-run.js +54 -54
  27. package/dist/electron-preload.js.map +1 -1
  28. package/dist/electron.js.map +1 -1
  29. package/dist/index.js +222 -138
  30. package/dist/llm/llm-judgment-client.js +102 -102
  31. package/dist/llm/pi-ai.js +48 -48
  32. package/dist/llm/system-prompt/layers/channel/human-async.md +41 -41
  33. package/dist/llm/system-prompt/layers/channel/local.md +14 -14
  34. package/dist/llm/system-prompt/layers/channel/p2p-agent.md +18 -18
  35. package/dist/llm/system-prompt/layers/channel/p2p-peer-sync.md +51 -51
  36. package/dist/llm/system-prompt/layers/channel/p2p-proactive.md +43 -43
  37. package/dist/llm/system-prompt/layers/channel/p2p-visitor.md +19 -19
  38. package/dist/llm/system-prompt/layers/channel/session-handoff.md +61 -61
  39. package/dist/llm/system-prompt/layers/core/artifacts_storage.md +89 -89
  40. package/dist/llm/system-prompt/layers/core/evenhandedness.md +21 -21
  41. package/dist/llm/system-prompt/layers/core/external-engagement.md +73 -73
  42. package/dist/llm/system-prompt/layers/core/hibs_reminders.md +15 -15
  43. package/dist/llm/system-prompt/layers/core/identity.md +48 -48
  44. package/dist/llm/system-prompt/layers/core/knowledge.md +17 -17
  45. package/dist/llm/system-prompt/layers/core/memory_system.md +12 -12
  46. package/dist/llm/system-prompt/layers/core/network_filesystem.md +28 -28
  47. package/dist/llm/system-prompt/layers/core/refusal.md +37 -37
  48. package/dist/llm/system-prompt/layers/core/tone.md +31 -31
  49. package/dist/llm/system-prompt/layers/core/tools.thin.md +13 -13
  50. package/dist/llm/system-prompt/layers/core/wellbeing.md +41 -41
  51. package/dist/llm/system-prompt/layers/role/architect.md +20 -20
  52. package/dist/llm/system-prompt/layers/role/expert.md +19 -19
  53. package/dist/llm/system-prompt/layers/role/implementer.md +15 -15
  54. package/dist/llm/system-prompt/layers/role/security.md +15 -15
  55. package/dist/llm/system-prompt/layers/tool/artifacts.md +72 -72
  56. package/dist/llm/system-prompt/layers/tool/bash.md +25 -25
  57. package/dist/llm/system-prompt/layers/tool/goal_handoff.md +77 -77
  58. package/dist/llm/system-prompt/layers/tool/hibs_api.md +171 -171
  59. package/dist/llm/system-prompt/layers/tool/image_search.md +70 -70
  60. package/dist/llm/system-prompt/layers/tool/manifest.md +89 -89
  61. package/dist/llm/system-prompt/layers/tool/mcp_apps.md +53 -53
  62. package/dist/llm/system-prompt/layers/tool/p2p_request.md +61 -61
  63. package/dist/llm/system-prompt/layers/tool/web_search.md +83 -83
  64. package/dist/llm/tool-manifest/ask_user_input.js +1 -1
  65. package/dist/llm/tool-manifest/bash.js +3 -3
  66. package/dist/llm/tool-manifest/create_file.js +4 -4
  67. package/dist/llm/tool-manifest/fetch_sports_data.js +3 -3
  68. package/dist/llm/tool-manifest/image_search.js +2 -2
  69. package/dist/llm/tool-manifest/index.js +0 -59
  70. package/dist/llm/tool-manifest/mcp.js +2 -2
  71. package/dist/llm/tool-manifest/message_compose.js +3 -3
  72. package/dist/llm/tool-manifest/places.js +2 -2
  73. package/dist/llm/tool-manifest/present_files.js +1 -1
  74. package/dist/llm/tool-manifest/recipe.js +2 -2
  75. package/dist/llm/tool-manifest/str_replace.js +5 -5
  76. package/dist/llm/tool-manifest/view.js +3 -3
  77. package/dist/llm/tool-manifest/weather.js +4 -4
  78. package/dist/llm/tool-manifest/web.js +4 -4
  79. package/dist/orbitdb/agent-tools.js +139 -0
  80. package/dist/orbitdb/kanban-store.js +259 -0
  81. package/dist/orbitdb/task-store.js +112 -0
  82. package/dist/pi-ecosystem-colony/index.js +365 -0
  83. package/dist/pi-ecosystem-judgment/causal-judge.js +51 -51
  84. package/dist/pi-ecosystem-judgment/distill-prompt.js +42 -42
  85. package/dist/pi-ecosystem-judgment/distillation.js +14 -14
  86. package/dist/pi-ecosystem-judgment/monitor-gate.js +28 -28
  87. package/dist/pi-ecosystem-judgment/value-injection.js +102 -102
  88. package/dist/security/context-router-tool.js +15 -15
  89. package/dist/security/tool-gate.js +2 -0
  90. package/dist/social/ant-colony/AdaptiveHeartbeat.js +101 -0
  91. package/dist/social/ant-colony/PheromoneEngine.js +227 -0
  92. package/dist/social/ant-colony/index.js +6 -0
  93. package/dist/social/ant-colony/types.js +24 -0
  94. package/dist/storage/trajectory.js +101 -0
  95. package/dist/test/ai-judgment-test.js +80 -0
  96. package/dist/test/bollharness-integration.test.js +318 -0
  97. package/dist/test/channel-agent-multi-dialogue.js +205 -0
  98. package/dist/test/channel-heartbeat-agent-test.js +201 -0
  99. package/dist/test/constraint-layer.test.js +164 -0
  100. package/dist/test/diap-identity-test.js +172 -0
  101. package/dist/test/diap-quick-test.js +62 -0
  102. package/dist/test/global-shared-context.test.js +315 -0
  103. package/dist/test/harness-judgment-injection.test.js +246 -0
  104. package/dist/test/harness-workflow-integrator-test.js +228 -0
  105. package/dist/test/human-value-store.test.js +243 -0
  106. package/dist/test/hybrid-integration-test.js +118 -0
  107. package/dist/test/hybrid-messenger-verify.js +55 -0
  108. package/dist/test/iroh-bistream-debug.js +38 -0
  109. package/dist/test/iroh-communication.test.js +66 -0
  110. package/dist/test/iroh-debug-test.js +57 -0
  111. package/dist/test/iroh-diap-test.js +71 -0
  112. package/dist/test/iroh-direct-connect.js +55 -0
  113. package/dist/test/iroh-e2e-fixed.js +89 -0
  114. package/dist/test/iroh-e2e-same-process.js +63 -0
  115. package/dist/test/iroh-e2e.js +66 -0
  116. package/dist/test/iroh-final-e2e.js +72 -0
  117. package/dist/test/iroh-relay-test.js +37 -0
  118. package/dist/test/iroh-simple-test.js +41 -0
  119. package/dist/test/iroh-transport-verify.js +54 -0
  120. package/dist/test/iroh-transport.test.js +37 -0
  121. package/dist/test/iroh-two-nodes.js +70 -0
  122. package/dist/test/iroh-verify.js +44 -0
  123. package/dist/test/judgment-decision.test.js +219 -0
  124. package/dist/test/llm-judgment-integration.test.js +220 -0
  125. package/dist/test/p2p-agent-complex-dialogue.js +385 -0
  126. package/dist/test/p2p-agent-dialogue.js +341 -0
  127. package/dist/test/p2p-agent-full-bidirectional.js +510 -0
  128. package/dist/test/p2p-agent-harness-flow.js +437 -0
  129. package/dist/test/p2p-agent-harness-single.js +143 -0
  130. package/dist/test/p2p-ai-dialogue-test.js +318 -0
  131. package/dist/test/p2p-cid-connect-test.js +195 -0
  132. package/dist/test/p2p-connect-receiver.js +69 -0
  133. package/dist/test/p2p-doc-transfer.js +110 -0
  134. package/dist/test/p2p-identity-page-test.js +77 -0
  135. package/dist/test/p2p-iroh-test.js +171 -0
  136. package/dist/test/p2p-minimal-test.js +241 -0
  137. package/dist/test/p2p-node-1.js +148 -0
  138. package/dist/test/p2p-node-2.js +148 -0
  139. package/dist/test/p2p-server.js +281 -0
  140. package/dist/test/p2p-two-nodes-test.js +438 -0
  141. package/dist/test/pi-sdk.test.js +44 -0
  142. package/dist/test/set-persona.js +40 -0
  143. package/dist/test/simple.test.js +9 -0
  144. package/dist/test/storage-integration.test.js +150 -0
  145. package/dist/test/subagent-manager.test.js +276 -0
  146. package/dist/test/test-gate-flow.test.js +81 -0
  147. package/dist/test/workflow-engine.test.js +87 -0
  148. package/dist/test/workflow-pivot-loop.test.js +246 -0
  149. package/dist/web/api-config.html +779 -779
  150. package/dist/web/client-hearth.js +10 -10
  151. package/dist/web/components/wallet-viem.mjs +118 -118
  152. package/dist/web/index.html +472 -472
  153. package/dist/web/manifest.json +20 -20
  154. package/dist/web/server-storage.js +29 -0
  155. package/dist/web/server.js +30 -14
  156. package/dist/web/style.css +4946 -4946
  157. package/package.json +195 -195
  158. package/scripts/build-cli.js +215 -215
  159. package/scripts/build-web.ts +130 -130
  160. package/scripts/postinstall.js +152 -152
  161. package/bin/bolloon-daemon.sh +0 -207
  162. package/dist/constraint-runtime/reference_data/archive_surface_snapshot.json +0 -63
  163. package/dist/constraint-runtime/reference_data/commands_snapshot.json +0 -1037
  164. package/dist/constraint-runtime/reference_data/subsystems/assistant.json +0 -8
  165. package/dist/constraint-runtime/reference_data/subsystems/bootstrap.json +0 -8
  166. package/dist/constraint-runtime/reference_data/subsystems/bridge.json +0 -32
  167. package/dist/constraint-runtime/reference_data/subsystems/buddy.json +0 -13
  168. package/dist/constraint-runtime/reference_data/subsystems/cli.json +0 -26
  169. package/dist/constraint-runtime/reference_data/subsystems/components.json +0 -32
  170. package/dist/constraint-runtime/reference_data/subsystems/constants.json +0 -28
  171. package/dist/constraint-runtime/reference_data/subsystems/coordinator.json +0 -8
  172. package/dist/constraint-runtime/reference_data/subsystems/entrypoints.json +0 -15
  173. package/dist/constraint-runtime/reference_data/subsystems/hooks.json +0 -32
  174. package/dist/constraint-runtime/reference_data/subsystems/keybindings.json +0 -21
  175. package/dist/constraint-runtime/reference_data/subsystems/memdir.json +0 -15
  176. package/dist/constraint-runtime/reference_data/subsystems/migrations.json +0 -18
  177. package/dist/constraint-runtime/reference_data/subsystems/moreright.json +0 -8
  178. package/dist/constraint-runtime/reference_data/subsystems/native_ts.json +0 -11
  179. package/dist/constraint-runtime/reference_data/subsystems/outputStyles.json +0 -8
  180. package/dist/constraint-runtime/reference_data/subsystems/plugins.json +0 -9
  181. package/dist/constraint-runtime/reference_data/subsystems/remote.json +0 -11
  182. package/dist/constraint-runtime/reference_data/subsystems/schemas.json +0 -8
  183. package/dist/constraint-runtime/reference_data/subsystems/screens.json +0 -10
  184. package/dist/constraint-runtime/reference_data/subsystems/server.json +0 -10
  185. package/dist/constraint-runtime/reference_data/subsystems/services.json +0 -32
  186. package/dist/constraint-runtime/reference_data/subsystems/skills.json +0 -27
  187. package/dist/constraint-runtime/reference_data/subsystems/state.json +0 -13
  188. package/dist/constraint-runtime/reference_data/subsystems/types.json +0 -18
  189. package/dist/constraint-runtime/reference_data/subsystems/upstreamproxy.json +0 -9
  190. package/dist/constraint-runtime/reference_data/subsystems/utils.json +0 -32
  191. package/dist/constraint-runtime/reference_data/subsystems/vim.json +0 -12
  192. package/dist/constraint-runtime/reference_data/subsystems/voice.json +0 -8
  193. package/dist/constraint-runtime/reference_data/tools_snapshot.json +0 -922
  194. package/dist/electron/config.js.map +0 -1
  195. package/dist/electron/dialogs.js.map +0 -1
  196. package/dist/electron/first-run.js.map +0 -1
  197. package/dist/electron/ipc.js.map +0 -1
  198. package/dist/electron/logger.js.map +0 -1
  199. package/dist/electron/main.js.map +0 -1
  200. package/dist/electron/menu.js.map +0 -1
  201. package/dist/electron/paths.js.map +0 -1
  202. package/dist/electron/server.js.map +0 -1
  203. package/dist/electron/tray.js.map +0 -1
  204. package/dist/electron/window.js.map +0 -1
  205. package/dist/utils/auto-update.js.map +0 -1
  206. package/dist/web/client.js.map +0 -7
@@ -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
+ });