@bolloon/bolloon-agent 0.2.9 โ†’ 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 -160
  223. package/scripts/build-cli.js +215 -215
  224. package/scripts/build-web.ts +125 -125
  225. package/scripts/postinstall.js +152 -152
  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,318 @@
1
+ /**
2
+ * P2P AI ๅฏน่ฏๆต‹่ฏ• - ็ป“ๅˆๅˆคๆ–ญๅŠ›ๆณจๅ…ฅ็š„ๆ™บ่ƒฝไฝ“ๅฏน่ฏ
3
+ *
4
+ * ๅŠŸ่ƒฝ:
5
+ * 1. ้€š่ฟ‡ iroh P2P ๆŽฅๆ”ถๆถˆๆฏ
6
+ * 2. ่ฐƒ็”จ AI ็”Ÿๆˆๅ›žๅค๏ผˆๅธฆๅˆคๆ–ญๅŠ›ๆณจๅ…ฅ๏ผ‰
7
+ * 3. ้€š่ฟ‡ iroh ๅ‘้€ๅ›žๅค
8
+ *
9
+ * ๆต็จ‹:
10
+ * ็”ต่„‘ A: npx tsx src/test/p2p-ai-dialogue-test.ts --publish
11
+ * ็”ต่„‘ B: npx tsx src/test/p2p-ai-dialogue-test.ts --cid=<A็š„CID>
12
+ */
13
+ import { irohTransport } from '../network/iroh-transport.js';
14
+ import { KeyManager } from '@diap/sdk';
15
+ import { createAgentSession } from '../agents/pi-sdk.js';
16
+ import { generateValueInjection } from '../pi-ecosystem-judgment/value-injection.js';
17
+ import { storeHumanJudgment, initializeValueStore } from '../pi-ecosystem-judgment/human-value-store.js';
18
+ const IPFS_ENDPOINT = 'http://127.0.0.1:5001';
19
+ // ๅ…จๅฑ€็Šถๆ€
20
+ let agentSession = null;
21
+ let messageHistory = [];
22
+ let ownNodeId = '';
23
+ // ============================================================
24
+ // AI ๅฏน่ฏๆ ธๅฟƒ
25
+ // ============================================================
26
+ async function initAgentSession() {
27
+ console.log('\n[AI] ๅˆๅง‹ๅŒ– Agent Session...');
28
+ const session = await createAgentSession({
29
+ cwd: process.cwd()
30
+ });
31
+ console.log(' โœ… Agent Session ๅฐฑ็ปช');
32
+ return session;
33
+ }
34
+ async function generateAIResponse(userInput, context) {
35
+ if (!agentSession) {
36
+ agentSession = await initAgentSession();
37
+ }
38
+ console.log('\n[AI] ๅค„็†่พ“ๅ…ฅ...');
39
+ console.log(` ๐Ÿ“ฅ ็”จๆˆท: ${userInput.substring(0, 50)}...`);
40
+ // 1. ็”Ÿๆˆๅˆคๆ–ญๅŠ›ๆณจๅ…ฅ
41
+ console.log('\n[Judgment] ็”Ÿๆˆไปทๅ€ผ่ง‚ๆณจๅ…ฅ...');
42
+ let valueInjection = '';
43
+ try {
44
+ const injection = await generateValueInjection(context || userInput, {
45
+ mode: 'standard',
46
+ maxTokens: 500,
47
+ includeExamples: true,
48
+ includeRules: true
49
+ });
50
+ valueInjection = injection;
51
+ if (injection) {
52
+ console.log(' โœ… ไปทๅ€ผ่ง‚ๆณจๅ…ฅๅทฒ็”Ÿๆˆ');
53
+ }
54
+ else {
55
+ console.log(' โ„น๏ธ ๆ— ๅކๅฒไปทๅ€ผ่ง‚ๆ•ฐๆฎ');
56
+ }
57
+ }
58
+ catch (e) {
59
+ console.log(` โš ๏ธ ไปทๅ€ผ่ง‚ๆณจๅ…ฅๅคฑ่ดฅ: ${e.message}`);
60
+ }
61
+ // 2. ๆž„ๅปบๅธฆๅˆคๆ–ญๅŠ›็š„ prompt
62
+ const fullPrompt = buildPromptWithJudgments(userInput, valueInjection);
63
+ // 3. ่ฐƒ็”จ AI
64
+ console.log('\n[AI] ่ฐƒ็”จ่ฏญ่จ€ๆจกๅž‹...');
65
+ try {
66
+ const response = await agentSession.prompt(fullPrompt);
67
+ console.log(' โœ… AI ๅ›žๅคๅทฒ็”Ÿๆˆ');
68
+ // ไฟๅญ˜ๅฏน่ฏๅކๅฒ
69
+ messageHistory.push({
70
+ from: 'user',
71
+ content: userInput,
72
+ type: 'user',
73
+ timestamp: Date.now()
74
+ });
75
+ messageHistory.push({
76
+ from: 'ai',
77
+ content: response,
78
+ type: 'ai',
79
+ timestamp: Date.now()
80
+ });
81
+ return response;
82
+ }
83
+ catch (e) {
84
+ console.error(' โŒ AI ่ฐƒ็”จๅคฑ่ดฅ:', e);
85
+ return `ๆŠฑๆญ‰๏ผŒAI ๆœๅŠกๆš‚ๆ—ถไธๅฏ็”จ: ${e.message}`;
86
+ }
87
+ }
88
+ function buildPromptWithJudgments(userInput, valueInjection) {
89
+ // ๆž„ๅปบๅŒ…ๅซๅˆคๆ–ญๅŠ›ๆณจๅ…ฅ็š„ prompt
90
+ let prompt = '';
91
+ if (valueInjection) {
92
+ prompt = `${valueInjection}
93
+
94
+ ---
95
+
96
+ ใ€ๅฝ“ๅ‰ๅฏน่ฏใ€‘
97
+ ็”จๆˆท: ${userInput}
98
+
99
+ ่ฏทๅŸบไบŽไปฅไธŠไปทๅ€ผ่ง‚ๅ’ŒไธŠไธ‹ๆ–‡ๅ›žๅค็”จๆˆทใ€‚`;
100
+ }
101
+ else {
102
+ prompt = `ไฝ ๆ˜ฏไธ€ไธชๆœ‰ๅธฎๅŠฉ็š„ AI ๅŠฉๆ‰‹ใ€‚
103
+
104
+ ใ€ๅฝ“ๅ‰ๅฏน่ฏใ€‘
105
+ ็”จๆˆท: ${userInput}
106
+
107
+ ่ฏทๅ›žๅค็”จๆˆทใ€‚`;
108
+ }
109
+ return prompt;
110
+ }
111
+ // ============================================================
112
+ // ๆถˆๆฏๅค„็†
113
+ // ============================================================
114
+ function setupMessageHandlers() {
115
+ console.log('\n[P2P] ่ฎพ็ฝฎๆถˆๆฏๅค„็†ๅ™จ...');
116
+ // ๅค„็† chat ็ฑปๅž‹ๆถˆๆฏ
117
+ irohTransport.onMessage('chat', async (msg) => {
118
+ const content = new TextDecoder().decode(msg.payload);
119
+ const fromNode = msg.from.substring(0, 12);
120
+ console.log(`\n[ๆ”ถๅˆฐ] ๐Ÿ’ฌ from ${fromNode}...: ${content.substring(0, 50)}...`);
121
+ // ็”Ÿๆˆ AI ๅ›žๅค
122
+ const response = await generateAIResponse(content, 'p2p-dialogue');
123
+ // ๅ‘้€ๅ›žๅค
124
+ const replyPayload = JSON.stringify({
125
+ type: 'ai-response',
126
+ content: response,
127
+ from: ownNodeId,
128
+ timestamp: Date.now()
129
+ });
130
+ await irohTransport.sendMessage(msg.from, 'chat', new TextEncoder().encode(replyPayload));
131
+ console.log(`[ๅ‘้€] โœ… ๅ›žๅคๅทฒๅ‘้€`);
132
+ });
133
+ // ๅค„็† ai-response ็ฑปๅž‹ๆถˆๆฏ
134
+ irohTransport.onMessage('ai-response', (msg) => {
135
+ try {
136
+ const data = JSON.parse(new TextDecoder().decode(msg.payload));
137
+ console.log(`\n[ๆ”ถๅˆฐ] ๐Ÿค– AI ๅ›žๅค from ${data.from?.substring(0, 12)}...`);
138
+ console.log(`\n${'โ”€'.repeat(50)}`);
139
+ console.log(data.content);
140
+ console.log(`${'โ”€'.repeat(50)}\n`);
141
+ }
142
+ catch {
143
+ console.log(`\n[ๆ”ถๅˆฐ] ๅŽŸๅง‹ๆถˆๆฏ: ${new TextDecoder().decode(msg.payload)}`);
144
+ }
145
+ });
146
+ // ๅค„็† feedback ็ฑปๅž‹ๆถˆๆฏ๏ผˆ็”จๆˆทๅ้ฆˆ๏ผ‰
147
+ irohTransport.onMessage('feedback', async (msg) => {
148
+ try {
149
+ const data = JSON.parse(new TextDecoder().decode(msg.payload));
150
+ console.log(`\n[ๆ”ถๅˆฐ] ๐Ÿ“ ็”จๆˆทๅ้ฆˆ: ${JSON.stringify(data)}`);
151
+ // ๅญ˜ๅ‚จๅ้ฆˆไฝœไธบๅˆคๆ–ญๅŠ›ๅญฆไน 
152
+ if (data.judgment) {
153
+ await storeHumanJudgment({
154
+ decision: data.content || 'N/A',
155
+ decision_type: data.type || 'approve',
156
+ reasons: [data.reason || ''],
157
+ values_derived: data.values || [],
158
+ context: {
159
+ domain: 'p2p-dialogue',
160
+ complexity: 'moderate',
161
+ stakes: 'low',
162
+ time_pressure: 'low'
163
+ },
164
+ outcome: { approved: data.type === 'approve' },
165
+ metadata: {
166
+ source: 'p2p-feedback',
167
+ confidence: 0.8,
168
+ revisable: true
169
+ }
170
+ });
171
+ console.log(' โœ… ๅ้ฆˆๅทฒๅญ˜ๅ‚จไธบๅˆคๆ–ญๅŠ›ๆ•ฐๆฎ');
172
+ }
173
+ }
174
+ catch (e) {
175
+ console.log(` โš ๏ธ ๅ้ฆˆ่งฃๆžๅคฑ่ดฅ: ${e.message}`);
176
+ }
177
+ });
178
+ console.log(' โœ… ๆถˆๆฏๅค„็†ๅ™จๅทฒ่ฎพ็ฝฎ');
179
+ }
180
+ // ============================================================
181
+ // DID ๅ‘ๅธƒ
182
+ // ============================================================
183
+ async function publishDID() {
184
+ console.log('\n[DID] ๅ‘ๅธƒ่บซไปฝๅˆฐ IPFS...');
185
+ const keyPair = KeyManager.generate();
186
+ const did = keyPair.did;
187
+ const nodeId = irohTransport.getNodeId() || '';
188
+ console.log(` โœ… DID: ${did}`);
189
+ console.log(` โœ… iroh Node ID: ${nodeId}`);
190
+ // ๆž„ๅปบ DID ๆ–‡ๆกฃ๏ผˆๅŒ…ๅซ iroh ไฟกๆฏ๏ผ‰
191
+ const agentDoc = {
192
+ id: did,
193
+ name: `bolloon-ai-${Date.now()}`,
194
+ version: '1.0',
195
+ capabilities: ['chat', 'reasoning', 'judgment-injection', 'ai-dialogue'],
196
+ interests: ['ai', 'p2p', 'judgment-system'],
197
+ irohNodeId: nodeId,
198
+ publicKey: Buffer.from(keyPair.publicKey).toString('hex'),
199
+ channels: [{ id: 'main', name: 'ไธปๅฏน่ฏ' }],
200
+ createdAt: new Date().toISOString()
201
+ };
202
+ // ๅ‘ๅธƒๅˆฐ IPFS
203
+ const formData = new FormData();
204
+ const blob = new Blob([JSON.stringify(agentDoc)], { type: 'application/json' });
205
+ formData.append('file', blob, 'agent-doc.json');
206
+ const response = await fetch(`${IPFS_ENDPOINT}/api/v0/add`, {
207
+ method: 'POST',
208
+ body: formData
209
+ });
210
+ const result = await response.text();
211
+ const cidMatch = result.match(/"Hash":"([^"]+)"/);
212
+ const cid = cidMatch ? cidMatch[1] : '';
213
+ console.log(` โœ… IPFS CID: ${cid}`);
214
+ return { did, cid, nodeId };
215
+ }
216
+ // ============================================================
217
+ // ่งฃๆž CID
218
+ // ============================================================
219
+ async function resolveCID(cid) {
220
+ console.log('\n[IPFS] ่งฃๆž CID...');
221
+ try {
222
+ const response = await fetch(`${IPFS_ENDPOINT}/api/v0/cat?arg=${cid}`, {
223
+ method: 'POST'
224
+ });
225
+ const content = await response.text();
226
+ const doc = JSON.parse(content);
227
+ console.log(` โœ… ่งฃๆžๆˆๅŠŸ`);
228
+ console.log(` DID: ${doc.id}`);
229
+ console.log(` ๅ็งฐ: ${doc.name || 'N/A'}`);
230
+ return { did: doc.id, name: doc.name || 'Unknown' };
231
+ }
232
+ catch (e) {
233
+ console.log(` โŒ ่งฃๆžๅคฑ่ดฅ: ${e.message}`);
234
+ return null;
235
+ }
236
+ }
237
+ // ============================================================
238
+ // ไธปๆต็จ‹
239
+ // ============================================================
240
+ async function main() {
241
+ console.log('โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—');
242
+ console.log('โ•‘ P2P AI ๅฏน่ฏๆต‹่ฏ• - ๅˆคๆ–ญๅŠ›ๆณจๅ…ฅ + ๆ™บ่ƒฝไฝ“ๅฏน่ฏ โ•‘');
243
+ console.log('โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•');
244
+ const args = process.argv.slice(2);
245
+ const isPublisher = args.includes('--publish');
246
+ const targetCid = args.find(a => a.startsWith('--cid='))?.split('=')[1];
247
+ const targetNode = args.find(a => a.startsWith('--node='))?.split('=')[1];
248
+ // 1. ๅˆๅง‹ๅŒ–
249
+ console.log('\n[ๅˆๅง‹ๅŒ–] ๅฏๅŠจ iroh...');
250
+ await irohTransport.start();
251
+ ownNodeId = irohTransport.getNodeId() || '';
252
+ console.log(` โœ… iroh ๅทฒๅฏๅŠจ: ${ownNodeId.substring(0, 20)}...`);
253
+ // 2. ๅˆๅง‹ๅŒ–ไปทๅ€ผ่ง‚ๅญ˜ๅ‚จ
254
+ try {
255
+ await initializeValueStore();
256
+ console.log(' โœ… ๅˆคๆ–ญๅŠ›ๅญ˜ๅ‚จๅทฒๅˆๅง‹ๅŒ–');
257
+ }
258
+ catch (e) {
259
+ console.log(` โš ๏ธ ๅˆคๆ–ญๅŠ›ๅญ˜ๅ‚จๅˆๅง‹ๅŒ–ๅคฑ่ดฅ: ${e.message}`);
260
+ }
261
+ // 3. ่ฎพ็ฝฎๆถˆๆฏๅค„็†ๅ™จ
262
+ setupMessageHandlers();
263
+ // ๅ‘ๅธƒๆจกๅผ
264
+ if (isPublisher) {
265
+ const { did, cid, nodeId } = await publishDID();
266
+ console.log('\nโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•');
267
+ console.log(' ๐Ÿ“‹ ่ฟžๆŽฅไฟกๆฏ๏ผˆๅˆ†ไบซ็ป™ๅฆไธ€ๅฐ็”ต่„‘๏ผ‰:');
268
+ console.log('โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•');
269
+ console.log(` CID: ${cid}`);
270
+ console.log(` Node ID: ${nodeId}`);
271
+ console.log('โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•\n');
272
+ console.log('็”จๆณ•:');
273
+ console.log(` npx tsx src/test/p2p-ai-dialogue-test.ts --cid=${cid} --node=${nodeId}`);
274
+ console.log('\n ็ญ‰ๅพ…ๆถˆๆฏ...\n');
275
+ await new Promise(() => { });
276
+ }
277
+ // ่ฟžๆŽฅๆจกๅผ
278
+ else if (targetCid && targetNode) {
279
+ const resolved = await resolveCID(targetCid);
280
+ if (resolved) {
281
+ console.log(`\n ๐ŸŽฏ ๅ‡†ๅค‡่ฟžๆŽฅๅˆฐ ${resolved.name}...`);
282
+ }
283
+ // ๅ‘้€ๆต‹่ฏ•ๆถˆๆฏ
284
+ const testMessage = JSON.stringify({
285
+ type: 'chat',
286
+ content: 'ไฝ ๅฅฝ๏ผ่ฟ™ๆ˜ฏ P2P AI ๅฏน่ฏๆต‹่ฏ•ๆถˆๆฏใ€‚่ฏท้—ฎไฝ ่ƒฝๅค„็†ไป€ไนˆไปปๅŠก๏ผŸ',
287
+ from: ownNodeId,
288
+ timestamp: Date.now()
289
+ });
290
+ console.log('\n[ๅ‘้€] ๆต‹่ฏ•ๆถˆๆฏ...');
291
+ const success = await irohTransport.sendMessage(targetNode, 'chat', new TextEncoder().encode(testMessage));
292
+ if (success) {
293
+ console.log(' โœ… ๆถˆๆฏๅ‘้€ๆˆๅŠŸ๏ผŒ็ญ‰ๅพ…ๅ›žๅค...\n');
294
+ }
295
+ else {
296
+ console.log(' โš ๏ธ ๆถˆๆฏๅ‘้€ๅคฑ่ดฅ\n');
297
+ }
298
+ console.log(' ็ญ‰ๅพ…ๆถˆๆฏ... (30็ง’ๅŽ้€€ๅ‡บ)\n');
299
+ await new Promise(resolve => setTimeout(resolve, 30000));
300
+ }
301
+ // ๅธฎๅŠฉไฟกๆฏ
302
+ else {
303
+ console.log('\n็”จๆณ•:');
304
+ console.log('');
305
+ console.log(' ็”ต่„‘ A (ๅ‘ๅธƒๆ–น):');
306
+ console.log(' npx tsx src/test/p2p-ai-dialogue-test.ts --publish');
307
+ console.log('');
308
+ console.log(' ็”ต่„‘ B (่ฟžๆŽฅๆ–น):');
309
+ console.log(' npx tsx src/test/p2p-ai-dialogue-test.ts --cid=<CID> --node=<NodeID>');
310
+ console.log('');
311
+ console.log('ๆต‹่ฏ•ๆต็จ‹:');
312
+ console.log(' 1. A ่ฟ่กŒ --publish๏ผŒ่ฎฐๅฝ•ๆ˜พ็คบ็š„ CID ๅ’Œ NodeID');
313
+ console.log(' 2. B ไฝฟ็”จ --cid ๅ’Œ --node ่ฟžๆŽฅ A');
314
+ console.log(' 3. A ๆ”ถๅˆฐๆถˆๆฏๅŽ๏ผŒ่ฐƒ็”จ AI ็”Ÿๆˆๅ›žๅค๏ผˆๅธฆๅˆคๆ–ญๅŠ›ๆณจๅ…ฅ๏ผ‰');
315
+ console.log(' 4. ๅ›žๅค้€š่ฟ‡ P2P ๅ‘้€ๅ›ž B');
316
+ }
317
+ }
318
+ main().catch(console.error);
@@ -0,0 +1,195 @@
1
+ /**
2
+ * P2P CID ่ฟžๆŽฅๆต‹่ฏ• - ้ชŒ่ฏ้€š่ฟ‡ CID ่‡ชๅŠจ่งฃๆž DID ๆ–‡ๆกฃๅนถๅปบ็ซ‹่ฟžๆŽฅ
3
+ *
4
+ * ๆต็จ‹:
5
+ * 1. ็”ต่„‘ A: ็”Ÿๆˆ DID โ†’ ๅ‘ๅธƒๅˆฐ IPFS โ†’ ่Žทๅพ— CID โ†’ ๅˆ†ไบซ็ป™ B
6
+ * 2. ็”ต่„‘ B: ๆŽฅๆ”ถ CID โ†’ ไปŽ IPFS ่งฃๆž DID ๆ–‡ๆกฃ โ†’ ๆๅ–่ฟžๆŽฅไฟกๆฏ โ†’ ๅปบ็ซ‹ P2P
7
+ */
8
+ import crypto from 'node:crypto';
9
+ import { KeyManager, IpfsClient } from '@diap/sdk';
10
+ import { createHyperswarmCommunicator, createTopic } from '@diap/sdk';
11
+ const IPFS_ENDPOINT = 'http://127.0.0.1:5001';
12
+ const P2P_TOPIC = 'bolloon-test-v2'; // ๆต‹่ฏ•็”จไธป้ข˜
13
+ // ============================================================
14
+ // ๆญฅ้ชค 1: ๅ‘ๅธƒ DID ๅˆฐ IPFS๏ผˆ็”ต่„‘ A๏ผ‰
15
+ // ============================================================
16
+ async function publishDIDToIPFS(name) {
17
+ console.log('\n[ๆญฅ้ชค 1] ๅ‘ๅธƒ DID ๅˆฐ IPFS...');
18
+ // ็”Ÿๆˆ DID
19
+ const keyPair = KeyManager.generate();
20
+ const did = keyPair.did;
21
+ console.log(` โœ… DID ็”Ÿๆˆ: ${did}`);
22
+ // ๆž„ๅปบ DID ๆ–‡ๆกฃ๏ผˆๆ ‡ๅ‡† DIAP ๆ ผๅผ๏ผ‰
23
+ const didDoc = {
24
+ '@context': [
25
+ 'https://www.w3.org/ns/did/v1',
26
+ 'https://w3id.org/security/suites/ed25519-2020/v1'
27
+ ],
28
+ id: did,
29
+ verificationMethod: [{
30
+ id: `${did}#key-1`,
31
+ type: 'Ed25519VerificationKey2020',
32
+ controller: did,
33
+ publicKeyMultibase: `did:key:${Buffer.from(keyPair.publicKey).toString('base64url')}`
34
+ }],
35
+ authentication: [`${did}#key-1`],
36
+ capabilityInvocation: [`${did}#key-1`],
37
+ capabilityDelegation: [`${did}#key-1`],
38
+ // ๆ‰ฉๅฑ•ๅญ—ๆฎต๏ผšๆ™บ่ƒฝไฝ“ไฟกๆฏ
39
+ name: name,
40
+ capabilities: ['chat', 'reasoning', 'judgment-injection'],
41
+ interests: ['ai', 'p2p'],
42
+ channels: [{ id: 'main', name: 'ไธปๅฏน่ฏ' }]
43
+ };
44
+ // ไธŠไผ ๅˆฐ IPFS
45
+ const ipfs = new IpfsClient(IPFS_ENDPOINT, null);
46
+ const docJson = JSON.stringify(didDoc);
47
+ const formData = new FormData();
48
+ const blob = new Blob([docJson], { type: 'application/json' });
49
+ formData.append('file', blob, 'did-doc.json');
50
+ const response = await fetch(`${IPFS_ENDPOINT}/api/v0/add`, {
51
+ method: 'POST',
52
+ body: formData
53
+ });
54
+ const result = await response.text();
55
+ const cidMatch = result.match(/"Hash":"([^"]+)"/);
56
+ const cid = cidMatch ? cidMatch[1] : '';
57
+ console.log(` โœ… DID ๆ–‡ๆกฃๅ‘ๅธƒๅˆฐ IPFS: ${cid}`);
58
+ return { did, cid, keyPair };
59
+ }
60
+ // ============================================================
61
+ // ๆญฅ้ชค 2: ไปŽ IPFS ่งฃๆž DID ๆ–‡ๆกฃ๏ผˆ็”ต่„‘ B๏ผ‰
62
+ // ============================================================
63
+ async function resolveDIDFromIPFS(cid) {
64
+ console.log('\n[ๆญฅ้ชค 2] ไปŽ IPFS ่งฃๆž DID ๆ–‡ๆกฃ...');
65
+ const ipfs = new IpfsClient(IPFS_ENDPOINT, null);
66
+ try {
67
+ const content = await ipfs.get(cid);
68
+ const doc = JSON.parse(content);
69
+ console.log(` โœ… DID ๆ–‡ๆกฃ่งฃๆžๆˆๅŠŸ`);
70
+ console.log(` DID: ${doc.id}`);
71
+ console.log(` ๅ็งฐ: ${doc.name || 'N/A'}`);
72
+ console.log(` ่ƒฝๅŠ›: ${(doc.capabilities || []).join(', ') || 'N/A'}`);
73
+ return {
74
+ did: doc.id,
75
+ name: doc.name || 'Unknown',
76
+ capabilities: doc.capabilities || []
77
+ };
78
+ }
79
+ catch (e) {
80
+ console.log(` โŒ ่งฃๆžๅคฑ่ดฅ: ${e.message}`);
81
+ return null;
82
+ }
83
+ }
84
+ // ============================================================
85
+ // ๆญฅ้ชค 3: ๅปบ็ซ‹ P2P ่ฟžๆŽฅ
86
+ // ============================================================
87
+ async function establishP2PConnection() {
88
+ console.log('\n[ๆญฅ้ชค 3] ๅˆๅง‹ๅŒ– P2P ็ฝ‘็ปœ...');
89
+ const seed = crypto.getRandomValues(new Uint8Array(32));
90
+ const comm = createHyperswarmCommunicator({
91
+ server: true,
92
+ client: true,
93
+ autoConnect: true,
94
+ maxConnections: 5,
95
+ seed: seed
96
+ });
97
+ // ๅ…ˆๅฏๅŠจ
98
+ await comm.start();
99
+ console.log(' โœ… P2P ็ฝ‘็ปœๅทฒๅฏๅŠจ');
100
+ const topic = createTopic(P2P_TOPIC);
101
+ await comm.joinTopic(topic);
102
+ console.log(` โœ… ๅทฒๅŠ ๅ…ฅ P2P ไธป้ข˜: ${P2P_TOPIC}`);
103
+ // ่Žทๅ–ๆœฌๆœบๅ…ฌ้’ฅ
104
+ const publicKey = comm.publicKey || '';
105
+ console.log(` โœ… ๆœฌๆœบ่Š‚็‚น ID: ${publicKey.substring(0, 16)}...`);
106
+ return { comm, publicKey };
107
+ }
108
+ // ============================================================
109
+ // ๆญฅ้ชค 4: ๅ‘้€/ๆŽฅๆ”ถๆถˆๆฏ
110
+ // ============================================================
111
+ async function testMessaging(comm, isInitiator) {
112
+ console.log('\n[ๆญฅ้ชค 4] ๆต‹่ฏ•ๆถˆๆฏๆ”ถๅ‘...');
113
+ const messageLog = [];
114
+ comm.on('message', (msg, conn) => {
115
+ const content = new TextDecoder().decode(msg.content);
116
+ console.log(` ๐Ÿ“ฉ ๆ”ถๅˆฐๆถˆๆฏ: ${content}`);
117
+ messageLog.push(`ๆ”ถๅˆฐ: ${content}`);
118
+ // ๅ›žๅค
119
+ const reply = isInitiator
120
+ ? `ACK: ๅทฒๆ”ถๅˆฐ "${content}"`
121
+ : `ๅ“ๅบ”: ไฝ ๅฅฝ๏ผŒๆˆ‘ๆ˜ฏๆŽฅๆ”ถๆ–น`;
122
+ conn.send(new TextEncoder().encode(reply));
123
+ console.log(` ๐Ÿ“ค ๅ‘้€ๅ›žๅค: ${reply}`);
124
+ });
125
+ comm.on('connection', (conn) => {
126
+ console.log(` ๐Ÿ”Œ ๆ–ฐ่ฟžๆŽฅ: ${conn.publicKey.substring(0, 8)}...`);
127
+ // ๅ‘่ตทๆ–นๅ‘้€ๆต‹่ฏ•ๆถˆๆฏ
128
+ if (isInitiator && messageLog.length === 0) {
129
+ setTimeout(() => {
130
+ const testMsg = `Hello from ${isInitiator ? 'Initiator' : 'Receiver'} at ${new Date().toISOString()}`;
131
+ conn.send(new TextEncoder().encode(testMsg));
132
+ console.log(` ๐Ÿ“ค ๅ‘้€ๆต‹่ฏ•ๆถˆๆฏ: ${testMsg}`);
133
+ }, 1000);
134
+ }
135
+ });
136
+ return messageLog;
137
+ }
138
+ // ============================================================
139
+ // ไธปๆต‹่ฏ•ๆต็จ‹
140
+ // ============================================================
141
+ async function main() {
142
+ console.log('โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—');
143
+ console.log('โ•‘ P2P CID ่ฟžๆŽฅๆต‹่ฏ• - ้ชŒ่ฏ DID ๆ–‡ๆกฃ่งฃๆžไธŽ่‡ชๅŠจ่ฟžๆŽฅ โ•‘');
144
+ console.log('โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•');
145
+ const args = process.argv.slice(2);
146
+ const isInitiator = args.includes('--initiator');
147
+ const shareCid = args.find(a => a.startsWith('--cid='))?.split('=')[1];
148
+ // ็”ต่„‘ A: ๅ‘ๅธƒ DID ๅˆฐ IPFS
149
+ if (isInitiator) {
150
+ const agentName = `test-agent-${Date.now()}`;
151
+ const { did, cid } = await publishDIDToIPFS(agentName);
152
+ // ๅปบ็ซ‹ P2P
153
+ const { comm, publicKey } = await establishP2PConnection();
154
+ console.log('\nโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•');
155
+ console.log(' ๐Ÿ“‹ ๅˆ†ไบซ็ป™ๅฆไธ€ๅฐ็”ต่„‘็š„ไฟกๆฏ:');
156
+ console.log('โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•');
157
+ console.log(` CID: ${cid}`);
158
+ console.log(` ไธป้ข˜: ${P2P_TOPIC}`);
159
+ console.log(` ไฝ ็š„่Š‚็‚น ID: ${publicKey.substring(0, 20)}...`);
160
+ console.log('โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•\n');
161
+ await testMessaging(comm, true);
162
+ console.log('\n ็ญ‰ๅพ…ๆถˆๆฏ... (Ctrl+C ้€€ๅ‡บ)');
163
+ }
164
+ // ็”ต่„‘ B: ไปŽ CID ่งฃๆžๅนถ่ฟžๆŽฅ
165
+ else if (shareCid) {
166
+ const resolved = await resolveDIDFromIPFS(shareCid);
167
+ if (!resolved) {
168
+ console.log('โŒ ๆ— ๆณ•่งฃๆž DID ๆ–‡ๆกฃ');
169
+ return;
170
+ }
171
+ console.log(`\n ๅ‡†ๅค‡่ฟžๆŽฅๅˆฐ ${resolved.name}...`);
172
+ // ๅปบ็ซ‹ P2P๏ผˆๅŠ ๅ…ฅๅŒไธ€ไธป้ข˜๏ผ‰
173
+ const { comm, publicKey } = await establishP2PConnection();
174
+ console.log('\nโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•');
175
+ console.log(' ๐Ÿ“‹ ๆœฌๆœบไฟกๆฏ:');
176
+ console.log('โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•');
177
+ console.log(` DID: ${resolved.did}`);
178
+ console.log(` ๅ็งฐ: ${resolved.name}`);
179
+ console.log(` ไธป้ข˜: ${P2P_TOPIC}`);
180
+ console.log(` ไฝ ็š„่Š‚็‚น ID: ${publicKey.substring(0, 20)}...`);
181
+ console.log('โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•\n');
182
+ await testMessaging(comm, false);
183
+ console.log('\n ็ญ‰ๅพ…ๆถˆๆฏ... (Ctrl+C ้€€ๅ‡บ)');
184
+ }
185
+ else {
186
+ console.log('\n็”จๆณ•:');
187
+ console.log(' ็”ต่„‘ A (ๅ‘่ตทๆ–น): npx tsx src/test/p2p-cid-connect-test.ts --initiator');
188
+ console.log(' ็”ต่„‘ B (ๆŽฅๆ”ถๆ–น): npx tsx src/test/p2p-cid-connect-test.ts --cid=<CID>');
189
+ console.log('\nๆต‹่ฏ•ๆญฅ้ชค:');
190
+ console.log(' 1. ๅœจ็”ต่„‘ A ่ฟ่กŒ --initiator๏ผŒ่ฎฐๅฝ•ๆ˜พ็คบ็š„ CID');
191
+ console.log(' 2. ๅœจ็”ต่„‘ B ่ฟ่กŒ --cid=<ไธŠไธ€ๆญฅ็š„CID>');
192
+ console.log(' 3. ่ง‚ๅฏŸ P2P ่ฟžๆŽฅๅ’Œๆถˆๆฏๆ”ถๅ‘');
193
+ }
194
+ }
195
+ main().catch(console.error);
@@ -0,0 +1,69 @@
1
+ /**
2
+ * P2P ๆŽฅๆ”ถ็ซฏๆต‹่ฏ• - ็”ต่„‘ B ไฝฟ็”จ CID ่งฃๆžๅนถ่ฟžๆŽฅ
3
+ */
4
+ import { irohTransport } from '../network/iroh-transport.js';
5
+ async function main() {
6
+ console.log('โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—');
7
+ console.log('โ•‘ P2P ๆŽฅๆ”ถ็ซฏ - ่งฃๆž CID ๅนถ่ฟžๆŽฅ โ•‘');
8
+ console.log('โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•');
9
+ // ไปŽๅ‘ฝไปค่กŒ่Žทๅ–ๅ‚ๆ•ฐ
10
+ const args = process.argv.slice(2);
11
+ const cid = args.find(a => a.startsWith('--cid='))?.split('=')[1];
12
+ const nodeId = args.find(a => a.startsWith('--node='))?.split('=')[1];
13
+ if (!cid || !nodeId) {
14
+ console.log('\n็”จๆณ•:');
15
+ console.log(' npx tsx src/test/p2p-connect-receiver.ts --cid=<CID> --node=<iroh-node-id>');
16
+ console.log('\n็คบไพ‹:');
17
+ console.log(' npx tsx src/test/p2p-connect-receiver.ts \\');
18
+ console.log(' --cid=QmXjU6RJZRgBphuMAD9gka2JMuEKvSutTLwsfHbrBb4JGQ \\');
19
+ console.log(' --node=327914b4744c67e0dbe3307175b22d893e14413cd9ca7f1a5667d565702575b4');
20
+ return;
21
+ }
22
+ console.log(`\n๐Ÿ“ก CID: ${cid}`);
23
+ console.log(`๐Ÿ”— ็›ฎๆ ‡่Š‚็‚น: ${nodeId.substring(0, 20)}...`);
24
+ // 1. ๅฏๅŠจ iroh
25
+ console.log('\n[1] ๅฏๅŠจ iroh...');
26
+ await irohTransport.start();
27
+ const myNodeId = irohTransport.getNodeId();
28
+ console.log(` โœ… ๆˆ‘็š„่Š‚็‚น ID: ${myNodeId}`);
29
+ // 2. ่งฃๆž CID
30
+ console.log('\n[2] ่งฃๆž DID ๆ–‡ๆกฃ...');
31
+ try {
32
+ const response = await fetch(`http://127.0.0.1:5001/api/v0/cat?arg=${cid}`, {
33
+ method: 'POST'
34
+ });
35
+ const content = await response.text();
36
+ const doc = JSON.parse(content);
37
+ console.log(` โœ… ่งฃๆžๆˆๅŠŸ!`);
38
+ console.log(` DID: ${doc.id}`);
39
+ console.log(` ๅ็งฐ: ${doc.name || 'N/A'}`);
40
+ }
41
+ catch (e) {
42
+ console.log(` โš ๏ธ ่งฃๆžๅคฑ่ดฅ๏ผˆๅฏ่ƒฝๅฏนๆ–น็ฆป็บฟ๏ผ‰: ${e.message}`);
43
+ }
44
+ // 3. ่ฎพ็ฝฎๆถˆๆฏ็›‘ๅฌ
45
+ console.log('\n[3] ่ฎพ็ฝฎๆถˆๆฏ็›‘ๅฌ...');
46
+ irohTransport.onMessage('chat', (msg) => {
47
+ console.log(`\n ๐Ÿ’ฌ ๆ”ถๅˆฐๆถˆๆฏ from ${msg.from.substring(0, 16)}...`);
48
+ console.log(` ๅ†…ๅฎน: ${new TextDecoder().decode(msg.payload)}`);
49
+ // ๅ›žๅค
50
+ const reply = `ACK from ${myNodeId?.substring(0, 8)}: ๅทฒๆ”ถๅˆฐ!`;
51
+ irohTransport.sendMessage(msg.from, 'chat', new TextEncoder().encode(reply));
52
+ console.log(` ๐Ÿ“ค ๅ‘้€ๅ›žๅค`);
53
+ });
54
+ console.log(' โœ… ็ญ‰ๅพ…ๆถˆๆฏ...');
55
+ // 4. ๅฐ่ฏ•่ฟžๆŽฅๅนถๅ‘้€ๆถˆๆฏ
56
+ console.log('\n[4] ๅฐ่ฏ•่ฟžๆŽฅ็›ฎๆ ‡่Š‚็‚น...');
57
+ const success = await irohTransport.sendMessage(nodeId, 'chat', new TextEncoder().encode(`Hello from receiver at ${Date.now()}!`));
58
+ if (success) {
59
+ console.log(' โœ… ๆถˆๆฏๅ‘้€ๆˆๅŠŸ!');
60
+ }
61
+ else {
62
+ console.log(' โš ๏ธ ๆถˆๆฏๅ‘้€ๅคฑ่ดฅ๏ผˆ็›ฎๆ ‡ๅฏ่ƒฝ็ฆป็บฟ๏ผ‰');
63
+ console.log(' ๆถˆๆฏๅฐ†ๅœจๅฏนๆ–นไธŠ็บฟๆ—ถ่‡ชๅŠจ้€่พพ');
64
+ }
65
+ console.log('\n ็ญ‰ๅพ…ๆถˆๆฏ... (Ctrl+C ้€€ๅ‡บ)\n');
66
+ // ไฟๆŒ่ฟ่กŒ
67
+ await new Promise(() => { });
68
+ }
69
+ main().catch(console.error);