@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,66 @@
1
+ import { irohTransport } from '../network/iroh-transport.js';
2
+ async function testTwoNodesCommunication() {
3
+ console.log('=== Two Node Communication Test ===\n');
4
+ // 启动第一个节点 (server)
5
+ console.log('[Node1] Starting...');
6
+ const node1 = await irohTransport.start();
7
+ console.log('[Node1] Node ID:', node1.nodeId.substring(0, 16) + '...');
8
+ console.log('[Node1] Addr:', node1.addr.substring(0, 32) + '...\n');
9
+ // 注册消息处理器
10
+ let messageCount = 0;
11
+ const messages = [];
12
+ irohTransport.onMessage('hello', (msg) => {
13
+ messageCount++;
14
+ messages.push(msg);
15
+ console.log(`[Node1] Received message #${messageCount} from ${msg.from.substring(0, 8)}...`);
16
+ console.log(`[Node1] Payload: ${new TextDecoder().decode(msg.payload)}`);
17
+ });
18
+ // 模拟第二个节点连接并发送消息
19
+ // 注意: 在实际场景中,两个节点需要在不同进程/机器上运行
20
+ // 这里我们测试的是单节点的消息处理能力
21
+ console.log('[Node1] Listening for incoming connections...\n');
22
+ // 等待一段时间看是否有连接
23
+ await new Promise(resolve => setTimeout(resolve, 2000));
24
+ console.log(`[Node1] Messages received: ${messageCount}`);
25
+ // 测试发送消息 API (模拟)
26
+ console.log('\n[Node1] Testing sendMessage API...');
27
+ const fakeTargetId = 'c0b07356bcf4a505000000000000000000000000';
28
+ // 注意: 这会失败因为目标节点不存在,但测试 API 是否正常调用
29
+ try {
30
+ await irohTransport.sendMessage(fakeTargetId, 'test', new TextEncoder().encode('test'));
31
+ }
32
+ catch (e) {
33
+ console.log('[Node1] Expected failure:', e.message);
34
+ }
35
+ await irohTransport.shutdown();
36
+ console.log('\n=== Test Complete ===');
37
+ }
38
+ async function testMessageParsing() {
39
+ console.log('=== Message Parsing Test ===\n');
40
+ await irohTransport.start();
41
+ // 测试不同的消息格式
42
+ const testCases = [
43
+ { type: 'task', payload: '{"id":"1","type":"summarize"}' },
44
+ { type: 'relay', payload: 'forward-data' },
45
+ { type: 'blob', payload: 'binary-data-here' },
46
+ ];
47
+ for (const tc of testCases) {
48
+ const encoded = new TextEncoder().encode(tc.payload);
49
+ const formatted = tc.type + ':' + tc.payload;
50
+ console.log(`Parsed: type=${tc.type}, payload_len=${encoded.length}`);
51
+ }
52
+ await irohTransport.shutdown();
53
+ console.log('\n=== Parsing Test Complete ===');
54
+ }
55
+ runTests();
56
+ async function runTests() {
57
+ try {
58
+ await testTwoNodesCommunication();
59
+ await testMessageParsing();
60
+ console.log('\n✅ All communication tests passed');
61
+ }
62
+ catch (e) {
63
+ console.error('❌ Test failed:', e);
64
+ process.exit(1);
65
+ }
66
+ }
@@ -0,0 +1,57 @@
1
+ import { Endpoint } from '@rayhanadev/iroh';
2
+ const IROH_ALPN = 'bolloon/iroh/1';
3
+ async function testConnection() {
4
+ console.log('=== iroh Connection Debug Test ===\n');
5
+ console.log('[1] Starting server...');
6
+ const server = await Endpoint.createWithOptions({ alpns: [IROH_ALPN] });
7
+ await server.online();
8
+ console.log(` Server ID: ${server.nodeId()}`);
9
+ console.log(` Server addr: ${server.addr()}`);
10
+ let acceptResult = null;
11
+ const acceptPromise = server.accept().then(conn => {
12
+ acceptResult = conn;
13
+ console.log('[Server] ✅ Connection accepted!');
14
+ return conn;
15
+ }).catch(e => {
16
+ console.log('[Server] ❌ Accept error:', e.message || e);
17
+ });
18
+ console.log('\n[2] Starting client...');
19
+ const client = await Endpoint.createWithOptions({ alpns: [IROH_ALPN] });
20
+ await client.online();
21
+ console.log(` Client ID: ${client.nodeId()}`);
22
+ console.log('\n[3] Client connecting to server...');
23
+ const connectPromise = client.connect(server.nodeId(), IROH_ALPN)
24
+ .then(conn => {
25
+ console.log('[Client] ✅ Connected!');
26
+ return conn;
27
+ })
28
+ .catch(e => {
29
+ console.log('[Client] ❌ Connection error:', e.message || e);
30
+ return null;
31
+ });
32
+ console.log(' Waiting 20s for connection...');
33
+ const timeout = new Promise(r => setTimeout(r, 20000));
34
+ const result = await Promise.race([connectPromise, timeout]);
35
+ if (result && result !== timeout) {
36
+ console.log('\n[4] Connection established, testing message...');
37
+ const { send, recv } = await result.openBi();
38
+ await send.writeAll(Buffer.from('test:hello'));
39
+ await send.finish();
40
+ console.log(' Message sent');
41
+ await new Promise(r => setTimeout(r, 2000));
42
+ if (acceptResult) {
43
+ const data = await recv.readToEnd(1024);
44
+ console.log(` ✅ Received: "${new TextDecoder().decode(data)}"`);
45
+ console.log('\n✅ TEST PASSED');
46
+ }
47
+ }
48
+ else if (!result) {
49
+ console.log('\n❌ Connection failed');
50
+ }
51
+ else {
52
+ console.log('\n⏳ Connection timed out');
53
+ }
54
+ await server.close().catch(() => { });
55
+ await client.close().catch(() => { });
56
+ }
57
+ testConnection().catch(console.error);
@@ -0,0 +1,71 @@
1
+ import { AgentAuthManager, KeyManager } from '@diap/sdk';
2
+ import { initIrohIntegration } from '../network/iroh-integration.js';
3
+ const IPFS_API = 'http://127.0.0.1:5001';
4
+ const IPFS_GATEWAY = 'http://127.0.0.1:8080';
5
+ async function main() {
6
+ console.log('╔═══════════════════════════════════════════╗');
7
+ console.log('║ iroh + DIAP Integration Test ║');
8
+ console.log('╚═══════════════════════════════════════════╝\n');
9
+ console.log('[1] Generating DIAP identity...');
10
+ const keyPair = KeyManager.generate();
11
+ console.log(` DID: ${keyPair.did}`);
12
+ console.log(` Name: test-agent-${keyPair.did.substring(0, 4)}`);
13
+ console.log('\n[2] Creating AgentAuthManager...');
14
+ const authManager = await AgentAuthManager.newWithRemoteIpfs(IPFS_API, IPFS_GATEWAY);
15
+ console.log(' AuthManager ready');
16
+ console.log('\n[3] Initializing iroh integration...');
17
+ const integration = await initIrohIntegration({
18
+ agentAuthManager: authManager,
19
+ keyPair: keyPair,
20
+ agentName: `test-agent-${keyPair.did.substring(0, 4)}`,
21
+ agentDescription: 'Test agent with iroh P2P transport',
22
+ agentTags: ['test', 'iroh'],
23
+ refreshIntervalMs: 5 * 60 * 1000,
24
+ discoveryIntervalMs: 30 * 1000,
25
+ });
26
+ const nodeId = integration.getNodeId();
27
+ console.log(`\n ✅ Iroh Node ID: ${nodeId}`);
28
+ const registration = integration.getRegistration();
29
+ if (registration) {
30
+ console.log(` ✅ DIAP CID: ${registration.cid}`);
31
+ }
32
+ console.log('\n[4] Setting up message handlers...');
33
+ integration.onMessage('ping', (msg, from) => {
34
+ console.log(`\n 📥 Ping from ${from.substring(0, 12)}...`);
35
+ console.log(` Payload: "${new TextDecoder().decode(msg.payload)}"`);
36
+ console.log(' 📤 Sending pong...');
37
+ integration.sendTo(from, 'pong', new TextEncoder().encode('pong from ' + nodeId?.substring(0, 8)));
38
+ });
39
+ integration.onMessage('task', (msg, from) => {
40
+ console.log(`\n 📥 Task from ${from.substring(0, 12)}...`);
41
+ const taskData = new TextDecoder().decode(msg.payload);
42
+ console.log(` Task: ${taskData.substring(0, 80)}...`);
43
+ });
44
+ integration.onMessage('response', (msg, from) => {
45
+ console.log(`\n 📥 Response from ${from.substring(0, 12)}...`);
46
+ console.log(` Response: "${new TextDecoder().decode(msg.payload)}"`);
47
+ });
48
+ console.log(' Handlers registered for: ping, task, response');
49
+ console.log('\n[5] Connection info for other peers:');
50
+ console.log(' ───────────────────────────────────────');
51
+ console.log(` Node ID: ${nodeId}`);
52
+ console.log(' ───────────────────────────────────────');
53
+ console.log('\n To connect another peer, use this Node ID.');
54
+ console.log('\n[6] Waiting for connections (60s)...');
55
+ let tick = 0;
56
+ const ticker = setInterval(() => {
57
+ tick++;
58
+ const peers = integration.getDiscoveredPeers();
59
+ const connected = integration.getConnectedPeers();
60
+ process.stdout.write(`\r [${tick}s] Discovered: ${peers.length}, Connected: ${connected.length} `);
61
+ }, 1000);
62
+ await new Promise(resolve => setTimeout(resolve, 60000));
63
+ clearInterval(ticker);
64
+ console.log('\n\n[7] Shutting down...');
65
+ await integration.shutdown();
66
+ console.log('Done');
67
+ }
68
+ main().catch(e => {
69
+ console.error('Error:', e);
70
+ process.exit(1);
71
+ });
@@ -0,0 +1,55 @@
1
+ import { Endpoint } from '@rayhanadev/iroh';
2
+ const IROH_ALPN = 'bolloon/iroh/1';
3
+ async function testConnection() {
4
+ console.log('=== Direct Connection Test ===\n');
5
+ // Server
6
+ console.log('[1] Starting server...');
7
+ const server = await Endpoint.createWithOptions({ alpns: [IROH_ALPN] });
8
+ await server.online();
9
+ const serverId = server.nodeId();
10
+ console.log(` Server ID: ${serverId}`);
11
+ console.log(` Server addr: ${server.addr()}`);
12
+ // Accept in background
13
+ let acceptedConn = null;
14
+ server.accept().then((conn) => {
15
+ console.log('[Server] Connection accepted!');
16
+ acceptedConn = conn;
17
+ });
18
+ // Client
19
+ console.log('\n[2] Starting client...');
20
+ const client = await Endpoint.createWithOptions({ alpns: [IROH_ALPN] });
21
+ await client.online();
22
+ const clientId = client.nodeId();
23
+ console.log(` Client ID: ${clientId}`);
24
+ console.log('\n[3] Client connecting to server...');
25
+ try {
26
+ const conn = await client.connect(serverId, IROH_ALPN);
27
+ console.log('[Client] Connected!');
28
+ console.log(` Remote: ${conn.remoteNodeId()}`);
29
+ // Send message
30
+ console.log('\n[4] Client sending message...');
31
+ const { send, recv } = await conn.openBi();
32
+ await send.writeAll(Buffer.from('hello:world'));
33
+ await send.finish();
34
+ console.log('[5] Waiting for server to receive...');
35
+ await new Promise(r => setTimeout(r, 2000));
36
+ if (acceptedConn) {
37
+ console.log('[Server] Reading message...');
38
+ const data = await recv.readToEnd(1024);
39
+ console.log(` Received: "${new TextDecoder().decode(data)}"`);
40
+ console.log('✅ CONNECTION TEST PASSED');
41
+ }
42
+ else {
43
+ console.log('❌ Server did not accept connection');
44
+ }
45
+ conn.close();
46
+ }
47
+ catch (e) {
48
+ console.log('[Client] Connection failed:', e);
49
+ console.log('❌ CONNECTION TEST FAILED');
50
+ }
51
+ await server.close();
52
+ await client.close();
53
+ console.log('\nDone');
54
+ }
55
+ testConnection().catch(console.error);
@@ -0,0 +1,89 @@
1
+ import { Endpoint } from '@rayhanadev/iroh';
2
+ const IROH_ALPN = 'bolloon/iroh/1';
3
+ async function testConnection() {
4
+ console.log('=== iroh E2E Test ===\n');
5
+ console.log('[1] Starting server...');
6
+ const server = await Endpoint.createWithOptions({ alpns: [IROH_ALPN] });
7
+ await server.online();
8
+ console.log(` Server ID: ${server.nodeId()}`);
9
+ let serverConn = null;
10
+ server.accept().then((conn) => {
11
+ serverConn = conn;
12
+ console.log('[Server] ✅ Connection accepted!');
13
+ }).catch((e) => {
14
+ console.log('[Server] ❌ Accept error:', e.message || e);
15
+ });
16
+ console.log('\n[2] Starting client...');
17
+ const client = await Endpoint.createWithOptions({ alpns: [IROH_ALPN] });
18
+ await client.online();
19
+ console.log(` Client ID: ${client.nodeId()}`);
20
+ console.log('\n[3] Client connecting to server...');
21
+ let clientConn = null;
22
+ try {
23
+ clientConn = await client.connect(server.nodeId(), IROH_ALPN);
24
+ console.log('[Client] ✅ Connected!');
25
+ }
26
+ catch (e) {
27
+ console.log('[Client] ❌ Connection failed:', e.message || e);
28
+ await server.close();
29
+ await client.close();
30
+ return;
31
+ }
32
+ console.log('\n[4] Waiting for server to accept connection...');
33
+ let waitCount = 0;
34
+ while (!serverConn && waitCount < 20) {
35
+ await new Promise(r => setTimeout(r, 500));
36
+ waitCount++;
37
+ process.stdout.write(` Waiting... ${waitCount}/20\r`);
38
+ }
39
+ console.log('');
40
+ if (!serverConn) {
41
+ console.log('❌ Server did not accept connection');
42
+ await server.close();
43
+ await client.close();
44
+ return;
45
+ }
46
+ console.log('[5] Client opening bi-stream...');
47
+ const clientStreams = await clientConn.openBi();
48
+ console.log(' Bi-stream opened');
49
+ console.log('[6] Server accepting bi-stream...');
50
+ let serverStreams = null;
51
+ try {
52
+ serverStreams = await serverConn.acceptBi();
53
+ console.log(' Bi-stream accepted');
54
+ }
55
+ catch (e) {
56
+ console.log('[Server] ❌ Accept bi error:', e.message || e);
57
+ }
58
+ if (!serverStreams) {
59
+ console.log('❌ Server could not accept bi-stream');
60
+ clientConn.close();
61
+ await server.close();
62
+ await client.close();
63
+ return;
64
+ }
65
+ console.log('\n[7] Client sending message...');
66
+ const { send: clientSend, recv: clientRecv } = clientStreams;
67
+ const message = 'hello:this is a test message';
68
+ await clientSend.writeAll(Buffer.from(message));
69
+ await clientSend.finish();
70
+ console.log(` Sent: "${message}"`);
71
+ console.log('[8] Server receiving message...');
72
+ const { recv: serverRecv } = serverStreams;
73
+ const received = await serverRecv.readToEnd(1024);
74
+ console.log(` ✅ Received: "${new TextDecoder().decode(received)}"`);
75
+ console.log('\n[9] Server sending response...');
76
+ const { send: serverSend } = serverStreams;
77
+ const response = 'response:hello from server';
78
+ await serverSend.writeAll(Buffer.from(response));
79
+ await serverSend.finish();
80
+ console.log(` Sent: "${response}"`);
81
+ console.log('[10] Client receiving response...');
82
+ const resp = await clientRecv.readToEnd(1024);
83
+ console.log(` ✅ Received: "${new TextDecoder().decode(resp)}"`);
84
+ console.log('\n✅✅✅ FULL E2E TEST PASSED ✅✅✅');
85
+ clientConn.close();
86
+ await server.close();
87
+ await client.close();
88
+ }
89
+ testConnection().catch(console.error);
@@ -0,0 +1,63 @@
1
+ import { irohTransport } from '../network/iroh-transport.js';
2
+ async function testTwoNodes() {
3
+ console.log('╔═══════════════════════════════════════════╗');
4
+ console.log('║ iroh Two-Node E2E Test ║');
5
+ console.log('╚═══════════════════════════════════════════╝\n');
6
+ let serverNodeId = null;
7
+ let clientNodeId = null;
8
+ let messagesReceived = 0;
9
+ console.log('[1] Starting server node...');
10
+ const server = await irohTransport.start();
11
+ serverNodeId = server.nodeId;
12
+ console.log(` Server Node ID: ${serverNodeId}`);
13
+ console.log('');
14
+ irohTransport.onMessage('ping', (msg) => {
15
+ messagesReceived++;
16
+ console.log(` [Server] Got ping: "${new TextDecoder().decode(msg.payload)}"`);
17
+ irohTransport.sendMessage(msg.from, 'pong', new TextEncoder().encode('pong'));
18
+ });
19
+ irohTransport.onMessage('request', async (msg) => {
20
+ messagesReceived++;
21
+ console.log(` [Server] Got request: "${new TextDecoder().decode(msg.payload)}"`);
22
+ const response = await irohTransport.requestResponse(msg.from, 'response', new TextEncoder().encode('response data'));
23
+ if (response) {
24
+ console.log(` [Server] Response sent`);
25
+ }
26
+ });
27
+ console.log('[2] Starting client node...');
28
+ const clientTransport = new (await import('../network/iroh-transport.js')).IrohTransport();
29
+ const client = await clientTransport.start();
30
+ clientNodeId = client.node;
31
+ console.log(` Client Node ID: ${clientNodeId}`);
32
+ console.log('');
33
+ let clientPongs = 0;
34
+ let clientResponses = 0;
35
+ clientTransport.onMessage('pong', (msg) => {
36
+ clientPongs++;
37
+ console.log(` [Client] Got pong: "${new TextDecoder().decode(msg.payload)}"`);
38
+ });
39
+ clientTransport.onMessage('response', (msg) => {
40
+ clientResponses++;
41
+ console.log(` [Client] Got response: "${new TextDecoder().decode(msg.payload)}"`);
42
+ });
43
+ await new Promise(r => setTimeout(r, 500));
44
+ console.log('[3] Client sending ping to server...');
45
+ await clientTransport.sendMessage(serverNodeId, 'ping', new TextEncoder().encode('hello'));
46
+ await new Promise(r => setTimeout(r, 500));
47
+ console.log('[4] Client sending request (with response)...');
48
+ await clientTransport.sendMessage(serverNodeId, 'request', new TextEncoder().encode('need data'));
49
+ await new Promise(r => setTimeout(r, 2000));
50
+ console.log('\n[5] Results:');
51
+ console.log(` Messages received by server: ${messagesReceived}`);
52
+ console.log(` Pongs received by client: ${clientPongs}`);
53
+ console.log(` Responses received by client: ${clientResponses}`);
54
+ const success = messagesReceived >= 2 && clientPongs >= 1 && clientResponses >= 1;
55
+ console.log('\n' + (success ? '✅ E2E TEST PASSED' : '❌ E2E TEST FAILED'));
56
+ await clientTransport.shutdown();
57
+ await irohTransport.shutdown();
58
+ process.exit(success ? 0 : 1);
59
+ }
60
+ testTwoNodes().catch(e => {
61
+ console.error('Test failed:', e);
62
+ process.exit(1);
63
+ });
@@ -0,0 +1,66 @@
1
+ import { irohTransport } from '../network/iroh-transport.js';
2
+ const args = process.argv.slice(2);
3
+ const role = args[0];
4
+ const targetNodeId = args[1];
5
+ if (!role || !['server', 'client'].includes(role)) {
6
+ console.log('Usage:');
7
+ console.log(' Server: npx tsx src/test/iroh-e2e.ts server');
8
+ console.log(' Client: npx tsx src/test/iroh-e2e.ts client <server-node-id>');
9
+ process.exit(1);
10
+ }
11
+ async function runServer() {
12
+ console.log('[Server] Starting iroh transport...');
13
+ const node = await irohTransport.start();
14
+ console.log('[Server] Node ID:', node.nodeId);
15
+ console.log('[Server] Waiting for connections...\n');
16
+ let msgCount = 0;
17
+ irohTransport.onMessage('ping', (msg) => {
18
+ msgCount++;
19
+ console.log(`[Server] #${msgCount} Ping from ${msg.from.substring(0, 16)}...`);
20
+ console.log(`[Server] Payload: "${new TextDecoder().decode(msg.payload)}"`);
21
+ irohTransport.sendMessage(msg.from, 'pong', new TextEncoder().encode('pong from server'));
22
+ });
23
+ irohTransport.onMessage('task', (msg) => {
24
+ msgCount++;
25
+ console.log(`[Server] #${msgCount} Task from ${msg.from.substring(0, 16)}...`);
26
+ const task = new TextDecoder().decode(msg.payload);
27
+ console.log(`[Server] Task: ${task.substring(0, 60)}...`);
28
+ irohTransport.sendMessage(msg.from, 'response', new TextEncoder().encode('task received'));
29
+ });
30
+ console.log('[Server] Ready. Press Ctrl+C to stop.');
31
+ await new Promise(() => { });
32
+ }
33
+ async function runClient(targetId) {
34
+ if (!targetId) {
35
+ console.error('[Client] Error: target node ID required');
36
+ process.exit(1);
37
+ }
38
+ console.log('[Client] Starting iroh transport...');
39
+ const node = await irohTransport.start();
40
+ console.log('[Client] Node ID:', node.nodeId);
41
+ console.log('[Client] Target:', targetId);
42
+ console.log('');
43
+ irohTransport.onMessage('pong', (msg) => {
44
+ console.log(`[Client] Pong from ${msg.from.substring(0, 16)}...: "${new TextDecoder().decode(msg.payload)}"`);
45
+ });
46
+ irohTransport.onMessage('response', (msg) => {
47
+ console.log(`[Client] Response from ${msg.from.substring(0, 16)}...: "${new TextDecoder().decode(msg.payload)}"`);
48
+ });
49
+ await new Promise(resolve => setTimeout(resolve, 500));
50
+ console.log('[Client] Sending ping...');
51
+ await irohTransport.sendMessage(targetId, 'ping', new TextEncoder().encode('hello server'));
52
+ await new Promise(resolve => setTimeout(resolve, 300));
53
+ console.log('[Client] Sending task...');
54
+ const task = JSON.stringify({ id: '123', type: 'summarize', documentPath: '/test.pdf' });
55
+ await irohTransport.sendMessage(targetId, 'task', new TextEncoder().encode(task));
56
+ console.log('[Client] Waiting for responses...');
57
+ await new Promise(resolve => setTimeout(resolve, 5000));
58
+ await irohTransport.shutdown();
59
+ console.log('[Client] Done');
60
+ }
61
+ if (role === 'server') {
62
+ runServer();
63
+ }
64
+ else {
65
+ runClient(targetNodeId);
66
+ }
@@ -0,0 +1,72 @@
1
+ import { Endpoint } from '@rayhanadev/iroh';
2
+ const IROH_ALPN = 'bolloon/iroh/1';
3
+ async function main() {
4
+ console.log('=== iroh E2E Final Test ===\n');
5
+ const serverEndpoint = await Endpoint.createWithOptions({ alpns: [IROH_ALPN] });
6
+ await serverEndpoint.online();
7
+ console.log('[Server] Started, ID:', serverEndpoint.nodeId().substring(0, 16) + '...');
8
+ const clientEndpoint = await Endpoint.createWithOptions({ alpns: [IROH_ALPN] });
9
+ await clientEndpoint.online();
10
+ console.log('[Client] Started, ID:', clientEndpoint.nodeId().substring(0, 16) + '...');
11
+ let serverConn = null;
12
+ let serverConnPromise = serverEndpoint.accept().then(c => { serverConn = c; return c; });
13
+ console.log('[Client] Connecting to server...');
14
+ let clientConn = null;
15
+ try {
16
+ clientConn = await clientEndpoint.connect(serverEndpoint.nodeId(), IROH_ALPN);
17
+ console.log('[Client] ✅ Connected!');
18
+ }
19
+ catch (e) {
20
+ console.log('[Client] ❌ Failed:', e.message);
21
+ return;
22
+ }
23
+ console.log('[Server] Waiting for accept...');
24
+ try {
25
+ await serverConnPromise;
26
+ console.log('[Server] ✅ Connection accepted!');
27
+ }
28
+ catch (e) {
29
+ console.log('[Server] ❌ Accept failed:', e.message);
30
+ return;
31
+ }
32
+ console.log('[Client] Opening bi-stream...');
33
+ let clientBi = null;
34
+ try {
35
+ clientBi = await clientConn.openBi();
36
+ console.log('[Client] ✅ Bi-stream opened');
37
+ }
38
+ catch (e) {
39
+ console.log('[Client] ❌ openBi failed:', e.message);
40
+ return;
41
+ }
42
+ console.log('[Server] Accepting bi-stream...');
43
+ let serverBi = null;
44
+ try {
45
+ serverBi = await serverConn.acceptBi();
46
+ console.log('[Server] ✅ Bi-stream accepted');
47
+ }
48
+ catch (e) {
49
+ console.log('[Server] ❌ acceptBi failed:', e.message);
50
+ return;
51
+ }
52
+ console.log('\n[Test] Sending message client → server...');
53
+ const { send: cSend, recv: cRecv } = clientBi;
54
+ await cSend.writeAll(Buffer.from('hello from client'));
55
+ await cSend.finish();
56
+ const { recv: sRecv, send: sSend } = serverBi;
57
+ const msg = await sRecv.readToEnd(1024);
58
+ console.log('[Server] ✅ Received:', new TextDecoder().decode(msg));
59
+ console.log('[Server] Sending response...');
60
+ await sSend.writeAll(Buffer.from('hello from server'));
61
+ await sSend.finish();
62
+ const resp = await cRecv.readToEnd(1024);
63
+ console.log('[Client] ✅ Received:', new TextDecoder().decode(resp));
64
+ console.log('\n✅✅✅ E2E TEST PASSED ✅✅✅');
65
+ clientConn.close();
66
+ await serverEndpoint.close();
67
+ await clientEndpoint.close();
68
+ }
69
+ main().catch(e => {
70
+ console.error('Error:', e);
71
+ process.exit(1);
72
+ });
@@ -0,0 +1,37 @@
1
+ import { Endpoint } from '@rayhanadev/iroh';
2
+ const IROH_ALPN = 'bolloon/iroh/1';
3
+ async function testConnection() {
4
+ console.log('=== iroh Relay Connection Test ===\n');
5
+ console.log('[1] Starting server...');
6
+ const server = await Endpoint.createWithOptions({ alpns: [IROH_ALPN] });
7
+ await server.online();
8
+ console.log(` Server ID: ${server.nodeId()}`);
9
+ console.log(` Server addr: ${server.addr()}`);
10
+ console.log('\n[2] Starting client...');
11
+ const client = await Endpoint.createWithOptions({ alpns: [IROH_ALPN] });
12
+ await client.online();
13
+ console.log(` Client ID: ${client.nodeId()}`);
14
+ console.log('\n[3] Client connecting to server via relay...');
15
+ try {
16
+ console.log(' Waiting for connection (relay may take time)...');
17
+ const conn = await client.connect(server.nodeId(), IROH_ALPN);
18
+ console.log('[Client] ✅ Connected!');
19
+ console.log(` Remote: ${conn.remoteNodeId()}`);
20
+ console.log('\n[4] Client sending message...');
21
+ const { send, recv } = await conn.openBi();
22
+ await send.writeAll(Buffer.from('hello:test message'));
23
+ await send.finish();
24
+ console.log(' Message sent');
25
+ console.log('\n[5] Server receiving...');
26
+ const data = await recv.readToEnd(1024);
27
+ console.log(` ✅ Received: "${new TextDecoder().decode(data)}"`);
28
+ console.log('\n✅ FULL E2E TEST PASSED');
29
+ conn.close();
30
+ }
31
+ catch (e) {
32
+ console.log('[Client] ❌ Connection failed:', e.message || e);
33
+ }
34
+ await server.close();
35
+ await client.close();
36
+ }
37
+ testConnection().catch(console.error);
@@ -0,0 +1,41 @@
1
+ import { Endpoint } from '@rayhanadev/iroh';
2
+ const IROH_ALPN = 'bolloon/iroh/1';
3
+ async function testConnection() {
4
+ console.log('=== iroh E2E Test (Simple) ===\n');
5
+ console.log('[1] Starting server...');
6
+ const server = await Endpoint.createWithOptions({ alpns: [IROH_ALPN] });
7
+ await server.online();
8
+ console.log(` Server ID: ${server.nodeId()}`);
9
+ console.log('[2] Starting client...');
10
+ const client = await Endpoint.createWithOptions({ alpns: [IROH_ALPN] });
11
+ await client.online();
12
+ console.log(` Client ID: ${client.nodeId()}`);
13
+ console.log('\n[3] Client connecting...');
14
+ let clientConn = null;
15
+ try {
16
+ clientConn = await client.connect(server.nodeId(), IROH_ALPN);
17
+ console.log('[Client] ✅ Connected!');
18
+ }
19
+ catch (e) {
20
+ console.log('[Client] ❌ Failed:', e.message || e);
21
+ await server.close();
22
+ await client.close();
23
+ return;
24
+ }
25
+ console.log('[4] Client sending datagram...');
26
+ try {
27
+ clientConn.sendDatagram(Buffer.from('hello:test datagram'));
28
+ console.log(' Datagram sent');
29
+ }
30
+ catch (e) {
31
+ console.log('[Client] ❌ Datagram failed:', e.message || e);
32
+ }
33
+ console.log('[5] Waiting 3s...');
34
+ await new Promise(r => setTimeout(r, 3000));
35
+ console.log('[6] Closing connections...');
36
+ clientConn.close();
37
+ await server.close();
38
+ await client.close();
39
+ console.log('\n✅ Connection test completed');
40
+ }
41
+ testConnection().catch(console.error);