@olane/o-node 0.7.1

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 (92) hide show
  1. package/README.md +1024 -0
  2. package/dist/src/connection/index.d.ts +5 -0
  3. package/dist/src/connection/index.d.ts.map +1 -0
  4. package/dist/src/connection/index.js +4 -0
  5. package/dist/src/connection/interfaces/o-node-connection-manager.config.d.ts +6 -0
  6. package/dist/src/connection/interfaces/o-node-connection-manager.config.d.ts.map +1 -0
  7. package/dist/src/connection/interfaces/o-node-connection-manager.config.js +1 -0
  8. package/dist/src/connection/interfaces/o-node-connection.config.d.ts +6 -0
  9. package/dist/src/connection/interfaces/o-node-connection.config.d.ts.map +1 -0
  10. package/dist/src/connection/interfaces/o-node-connection.config.js +1 -0
  11. package/dist/src/connection/o-node-connection.d.ts +13 -0
  12. package/dist/src/connection/o-node-connection.d.ts.map +1 -0
  13. package/dist/src/connection/o-node-connection.js +51 -0
  14. package/dist/src/connection/o-node-connection.manager.d.ts +17 -0
  15. package/dist/src/connection/o-node-connection.manager.d.ts.map +1 -0
  16. package/dist/src/connection/o-node-connection.manager.js +68 -0
  17. package/dist/src/index.d.ts +10 -0
  18. package/dist/src/index.d.ts.map +1 -0
  19. package/dist/src/index.js +9 -0
  20. package/dist/src/interfaces/o-node.config.d.ts +7 -0
  21. package/dist/src/interfaces/o-node.config.d.ts.map +1 -0
  22. package/dist/src/interfaces/o-node.config.js +1 -0
  23. package/dist/src/interfaces/o-node.tool-config.d.ts +4 -0
  24. package/dist/src/interfaces/o-node.tool-config.d.ts.map +1 -0
  25. package/dist/src/interfaces/o-node.tool-config.js +1 -0
  26. package/dist/src/lib/network-activity.lib.d.ts +1 -0
  27. package/dist/src/lib/network-activity.lib.d.ts.map +1 -0
  28. package/dist/src/lib/network-activity.lib.js +34 -0
  29. package/dist/src/nodes/client.node.d.ts +7 -0
  30. package/dist/src/nodes/client.node.d.ts.map +1 -0
  31. package/dist/src/nodes/client.node.js +16 -0
  32. package/dist/src/nodes/index.d.ts +4 -0
  33. package/dist/src/nodes/index.d.ts.map +1 -0
  34. package/dist/src/nodes/index.js +3 -0
  35. package/dist/src/nodes/server.node.d.ts +7 -0
  36. package/dist/src/nodes/server.node.d.ts.map +1 -0
  37. package/dist/src/nodes/server.node.js +20 -0
  38. package/dist/src/nodes/websocket.node.d.ts +7 -0
  39. package/dist/src/nodes/websocket.node.d.ts.map +1 -0
  40. package/dist/src/nodes/websocket.node.js +18 -0
  41. package/dist/src/o-node.d.ts +42 -0
  42. package/dist/src/o-node.d.ts.map +1 -0
  43. package/dist/src/o-node.hierarchy-manager.d.ts +15 -0
  44. package/dist/src/o-node.hierarchy-manager.d.ts.map +1 -0
  45. package/dist/src/o-node.hierarchy-manager.js +15 -0
  46. package/dist/src/o-node.js +242 -0
  47. package/dist/src/o-node.tool.d.ts +16 -0
  48. package/dist/src/o-node.tool.d.ts.map +1 -0
  49. package/dist/src/o-node.tool.js +48 -0
  50. package/dist/src/router/index.d.ts +6 -0
  51. package/dist/src/router/index.d.ts.map +1 -0
  52. package/dist/src/router/index.js +5 -0
  53. package/dist/src/router/interfaces/o-node-router.config.d.ts +3 -0
  54. package/dist/src/router/interfaces/o-node-router.config.d.ts.map +1 -0
  55. package/dist/src/router/interfaces/o-node-router.config.js +1 -0
  56. package/dist/src/router/interfaces/o-node-router.response.d.ts +8 -0
  57. package/dist/src/router/interfaces/o-node-router.response.d.ts.map +1 -0
  58. package/dist/src/router/interfaces/o-node-router.response.js +1 -0
  59. package/dist/src/router/o-node.address.d.ts +18 -0
  60. package/dist/src/router/o-node.address.d.ts.map +1 -0
  61. package/dist/src/router/o-node.address.js +29 -0
  62. package/dist/src/router/o-node.router.d.ts +12 -0
  63. package/dist/src/router/o-node.router.d.ts.map +1 -0
  64. package/dist/src/router/o-node.router.js +109 -0
  65. package/dist/src/router/o-node.transport.d.ts +11 -0
  66. package/dist/src/router/o-node.transport.d.ts.map +1 -0
  67. package/dist/src/router/o-node.transport.js +18 -0
  68. package/dist/src/router/resolvers/index.d.ts +4 -0
  69. package/dist/src/router/resolvers/index.d.ts.map +1 -0
  70. package/dist/src/router/resolvers/index.js +3 -0
  71. package/dist/src/router/resolvers/o-node.child-resolver.d.ts +11 -0
  72. package/dist/src/router/resolvers/o-node.child-resolver.d.ts.map +1 -0
  73. package/dist/src/router/resolvers/o-node.child-resolver.js +58 -0
  74. package/dist/src/router/resolvers/o-node.leader-resolver-fallback.d.ts +8 -0
  75. package/dist/src/router/resolvers/o-node.leader-resolver-fallback.d.ts.map +1 -0
  76. package/dist/src/router/resolvers/o-node.leader-resolver-fallback.js +35 -0
  77. package/dist/src/router/resolvers/o-node.resolver.d.ts +11 -0
  78. package/dist/src/router/resolvers/o-node.resolver.d.ts.map +1 -0
  79. package/dist/src/router/resolvers/o-node.resolver.js +41 -0
  80. package/dist/src/router/resolvers/o-node.search-resolver.d.ts +8 -0
  81. package/dist/src/router/resolvers/o-node.search-resolver.d.ts.map +1 -0
  82. package/dist/src/router/resolvers/o-node.search-resolver.js +60 -0
  83. package/dist/src/router/route.request.d.ts +14 -0
  84. package/dist/src/router/route.request.d.ts.map +1 -0
  85. package/dist/src/router/route.request.js +1 -0
  86. package/dist/src/utils/network.utils.d.ts +20 -0
  87. package/dist/src/utils/network.utils.d.ts.map +1 -0
  88. package/dist/src/utils/network.utils.js +74 -0
  89. package/dist/test/o-node.spec.d.ts +2 -0
  90. package/dist/test/o-node.spec.d.ts.map +1 -0
  91. package/dist/test/o-node.spec.js +20 -0
  92. package/package.json +68 -0
package/README.md ADDED
@@ -0,0 +1,1024 @@
1
+ # @olane/o-node
2
+
3
+ The production distribution layer of Olane OS - build tool nodes that AI agents use, with real P2P networking via libp2p.
4
+
5
+ [![npm version](https://badge.fury.io/js/%40olane%2Fo-node.svg)](https://www.npmjs.com/package/@olane/o-node)
6
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
7
+
8
+ ## What is o-node?
9
+
10
+ **o-node** is the **production-ready distribution layer** of Olane OS - like Ubuntu is to the Linux kernel. While [@olane/o-core](../o-core) defines the abstract kernel, o-node is the actual working OS that uses [libp2p](https://libp2p.io/) for real peer-to-peer networking, discovery, and distributed communication.
11
+
12
+ ### The Three-Layer Model
13
+
14
+ ```
15
+ ┌─────────────────────────────────────────────┐
16
+ │ USERS: AI Agents (LLMs) │
17
+ │ - GPT-4, Claude, Gemini, etc. │
18
+ │ - Natural language interfaces │
19
+ │ - Intelligent reasoning brains │
20
+ └─────────────────────────────────────────────┘
21
+ ⬇ use
22
+ ┌─────────────────────────────────────────────┐
23
+ │ APPLICATIONS: Tool Nodes (you build) │
24
+ │ - Domain-specific capabilities │
25
+ │ - Business integrations (APIs, DBs) │
26
+ │ - Specialized tools and services │
27
+ └─────────────────────────────────────────────┘
28
+ ⬇ run on
29
+ ┌─────────────────────────────────────────────┐
30
+ │ OPERATING SYSTEM: Olane Runtime (o-node) │
31
+ │ - P2P networking (libp2p) │
32
+ │ - Tool node discovery │
33
+ │ - IPC & routing │
34
+ │ - Process management │
35
+ └─────────────────────────────────────────────┘
36
+ ```
37
+
38
+ **Key Insight**: You build **tool nodes** (specialized applications) using o-node, which **AI agents** (LLMs) use as intelligent users to accomplish tasks.
39
+
40
+ ## Key Features
41
+
42
+ - 🌐 **Peer-to-Peer Networking** - Built on libp2p for true decentralized communication
43
+ - 🔍 **Automatic Discovery** - DHT-based tool node discovery and routing
44
+ - 🔒 **Secure by Default** - Encrypted connections with connection gating
45
+ - 🚀 **Production Ready** - Battle-tested libp2p stack with NAT traversal
46
+ - 🏗️ **Multiple Node Types** - Server, client, and WebSocket-optimized variants
47
+ - 📡 **Network Registration** - Automatic registration with leader nodes
48
+ - 🔄 **Persistent Identity** - Seed-based peer IDs for consistent tool node identity
49
+ - 🛡️ **Hierarchical Security** - Parent-child access control built-in
50
+ - 🧠 **Generalist-Specialist Architecture** - One LLM brain serves many specialized tool nodes
51
+
52
+ ## Relationship to o-core
53
+
54
+ ```
55
+ ┌─────────────────────────────────────┐
56
+ │ o-node (This Package) │
57
+ │ Production Distribution Layer │
58
+ │ │
59
+ │ • Real P2P networking (libp2p) │
60
+ │ • Tool node discovery & routing │
61
+ │ • Network registration │
62
+ │ • Ready-to-use variants │
63
+ └─────────────────────────────────────┘
64
+ ⬇ implements
65
+ ┌─────────────────────────────────────┐
66
+ │ @olane/o-core │
67
+ │ Abstract Kernel │
68
+ │ │
69
+ │ • Abstract base classes │
70
+ │ • Router & connection interfaces │
71
+ │ • Transport-agnostic design │
72
+ │ • Core lifecycle management │
73
+ └─────────────────────────────────────┘
74
+ ```
75
+
76
+ **Think of it as**: o-core is the **Linux kernel**, o-node is the **Ubuntu distribution**
77
+
78
+ **Use o-node when:** Building tool nodes that AI agents will use (production systems)
79
+ **Use o-core when:** Building custom transport implementations or experimental architectures
80
+
81
+ ## Installation
82
+
83
+ ```bash
84
+ npm install @olane/o-node @olane/o-core @olane/o-protocol @olane/o-config @olane/o-tool
85
+ ```
86
+
87
+ ## Quick Start
88
+
89
+ ### Creating Your First P2P Tool Node
90
+
91
+ ```typescript
92
+ import { oServerNode, oNodeAddress } from '@olane/o-node';
93
+ import { NodeType, oRequest } from '@olane/o-core';
94
+
95
+ // Create a server node (listens for connections)
96
+ class MyToolNode extends oServerNode {
97
+ constructor(address: string) {
98
+ super({
99
+ address: new oNodeAddress(address),
100
+ type: NodeType.AGENT,
101
+ description: 'My first tool node for AI agents',
102
+ leader: null, // We'll be our own network for now
103
+ parent: null,
104
+ methods: {
105
+ greet: {
106
+ name: 'greet',
107
+ description: 'Greets the caller',
108
+ parameters: {
109
+ name: { type: 'string', required: true }
110
+ }
111
+ }
112
+ }
113
+ });
114
+ }
115
+
116
+ // Implement your tool node's logic
117
+ async execute(request: oRequest): Promise<any> {
118
+ const { method, params } = request;
119
+
120
+ if (method === 'greet') {
121
+ return {
122
+ message: `Hello, ${params.name}! I'm a tool node that AI agents can use.`,
123
+ peerId: this.peerId.toString()
124
+ };
125
+ }
126
+
127
+ throw new Error(`Unknown method: ${method}`);
128
+ }
129
+ }
130
+
131
+ // Start the tool node
132
+ const toolNode = new MyToolNode('o://my-tool');
133
+ await toolNode.start();
134
+
135
+ console.log('Tool node running at:', toolNode.transports);
136
+ console.log('Peer ID:', toolNode.peerId.toString());
137
+
138
+ // AI agents can now use this tool node via its o:// address
139
+ const response = await toolNode.use(
140
+ toolNode.address,
141
+ { method: 'greet', params: { name: 'World' } }
142
+ );
143
+
144
+ console.log(response.result);
145
+ // { message: "Hello, World! I'm a tool node that AI agents can use.", peerId: "..." }
146
+
147
+ await toolNode.stop();
148
+ ```
149
+
150
+ ### Creating a Network of Tool Nodes
151
+
152
+ ```typescript
153
+ import { oServerNode, oNodeAddress } from '@olane/o-node';
154
+ import { NodeType } from '@olane/o-core';
155
+
156
+ // 1. Create a leader node (network coordinator for tool nodes)
157
+ const leader = new oServerNode({
158
+ address: new oNodeAddress('o://leader'),
159
+ type: NodeType.LEADER,
160
+ description: 'Network coordinator',
161
+ leader: null,
162
+ parent: null
163
+ });
164
+
165
+ await leader.start();
166
+ console.log('Leader started:', leader.transports[0].toString());
167
+
168
+ // 2. Create tool nodes that connect to the leader
169
+ const salesTool = new oServerNode({
170
+ address: new oNodeAddress('o://sales-tool'),
171
+ type: NodeType.AGENT,
172
+ description: 'Sales analysis tool for AI agents',
173
+ leader: new oNodeAddress('o://leader', leader.transports),
174
+ parent: new oNodeAddress('o://leader', leader.transports)
175
+ });
176
+
177
+ const analyticsTool = new oServerNode({
178
+ address: new oNodeAddress('o://analytics-tool'),
179
+ type: NodeType.AGENT,
180
+ description: 'Data analytics tool for AI agents',
181
+ leader: new oNodeAddress('o://leader', leader.transports),
182
+ parent: new oNodeAddress('o://leader', leader.transports)
183
+ });
184
+
185
+ await salesTool.start();
186
+ await analyticsTool.start();
187
+
188
+ // 3. Tool nodes can now communicate (and AI agents can discover them)!
189
+ const response = await salesTool.use(
190
+ new oNodeAddress('o://analytics-tool'),
191
+ { method: 'analyze', params: { data: 'sales-data' } }
192
+ );
193
+
194
+ console.log('Tool node IPC successful! AI agents can now use these tools.');
195
+ ```
196
+
197
+ ### Persistent Tool Node Identity with Seeds
198
+
199
+ ```typescript
200
+ import { oServerNode, oNodeAddress } from '@olane/o-node';
201
+
202
+ // Create a tool node with a seed for consistent peer ID
203
+ const toolNode = new oServerNode({
204
+ address: new oNodeAddress('o://my-service-tool'),
205
+ type: NodeType.AGENT,
206
+ leader: leaderAddress,
207
+ parent: leaderAddress,
208
+ seed: 'my-secure-seed-string' // Same seed = same peer ID every restart
209
+ });
210
+
211
+ await toolNode.start();
212
+
213
+ // This peer ID will be the same every time with this seed
214
+ // Critical for tool nodes that agents depend on finding reliably
215
+ console.log('Consistent Peer ID:', toolNode.peerId.toString());
216
+
217
+ // Important: Secure your seed in production!
218
+ // Use environment variables or secure key management
219
+ ```
220
+
221
+ ## Core Concepts
222
+
223
+ ### libp2p Networking
224
+
225
+ o-node uses libp2p for all networking, providing:
226
+
227
+ - **Multiple Transports**: TCP, WebSocket, WebRTC, QUIC
228
+ - **Peer Discovery**: DHT, mDNS, bootstrap nodes
229
+ - **Content Routing**: Distributed hash table (DHT)
230
+ - **NAT Traversal**: Automatic hole-punching and relaying
231
+ - **Multiplexing**: Multiple streams over single connection
232
+ - **Security**: Noise protocol encryption by default
233
+
234
+ ```typescript
235
+ // libp2p transports are automatically configured
236
+ const node = new oServerNode(config);
237
+ await node.start();
238
+
239
+ // Access the libp2p node directly if needed
240
+ console.log('Protocols:', node.p2pNode.getProtocols());
241
+ console.log('Connections:', node.p2pNode.getConnections());
242
+ console.log('Multiaddrs:', node.p2pNode.getMultiaddrs());
243
+ ```
244
+
245
+ ### Multiaddresses
246
+
247
+ o-node uses libp2p multiaddresses for network addressing:
248
+
249
+ ```typescript
250
+ // A multiaddress contains all connection info
251
+ const multiaddr = '/ip4/192.168.1.100/tcp/4001/p2p/12D3KooW...';
252
+
253
+ // Multiaddresses are wrapped in oNodeTransport
254
+ const transport = new oNodeTransport(multiaddr);
255
+ const address = new oNodeAddress('o://my-agent', [transport]);
256
+
257
+ // When connecting, o-node uses these multiaddresses
258
+ await agent.use(address, { method: 'ping' });
259
+ ```
260
+
261
+ ### Network Registration
262
+
263
+ Agents automatically register with leader nodes:
264
+
265
+ ```typescript
266
+ class MyAgent extends oServerNode {
267
+ async register(): Promise<void> {
268
+ // Automatically called during start()
269
+ // Registers with leader's registry service
270
+ await this.use(RegistryAddress, {
271
+ method: 'commit',
272
+ params: {
273
+ peerId: this.peerId.toString(),
274
+ address: this.address.toString(),
275
+ protocols: this.p2pNode.getProtocols(),
276
+ transports: this.transports,
277
+ staticAddress: this.staticAddress.toString()
278
+ }
279
+ });
280
+ }
281
+ }
282
+ ```
283
+
284
+ ### Hierarchical Addressing
285
+
286
+ Agents can be organized hierarchically with automatic address encapsulation:
287
+
288
+ ```typescript
289
+ // Parent address
290
+ const parent = new oNodeAddress('o://company');
291
+
292
+ // Child address will be encapsulated
293
+ const child = new oNodeAddress('o://sales');
294
+
295
+ // When child starts with parent, address becomes: o://company/sales
296
+ const childAgent = new oServerNode({
297
+ address: child,
298
+ parent: new oNodeAddress('o://company', parentTransports),
299
+ leader: leaderAddress
300
+ });
301
+
302
+ await childAgent.start();
303
+ console.log(childAgent.address.toString()); // "o://company/sales"
304
+ ```
305
+
306
+ ### Connection Security
307
+
308
+ o-node implements connection gating for hierarchical security:
309
+
310
+ ```typescript
311
+ // Child nodes only accept connections from their parent
312
+ connectionGater: {
313
+ denyInboundEncryptedConnection: (peerId, maConn) => {
314
+ // Only parent can call us
315
+ if (this.parentPeerId === peerId.toString()) {
316
+ return false; // Allow
317
+ }
318
+ // Deny all others
319
+ return true;
320
+ }
321
+ }
322
+ ```
323
+
324
+ ## Node Types
325
+
326
+ o-node provides specialized node implementations for different use cases:
327
+
328
+ ### 1. oServerNode - Full-Featured Server
329
+
330
+ Best for: Long-running services, leader nodes, infrastructure agents
331
+
332
+ ```typescript
333
+ import { oServerNode } from '@olane/o-node';
334
+
335
+ const server = new oServerNode({
336
+ address: new oNodeAddress('o://my-service'),
337
+ type: NodeType.AGENT,
338
+ leader: leaderAddress,
339
+ parent: parentAddress
340
+ });
341
+
342
+ await server.start();
343
+
344
+ // Listens on multiple transports:
345
+ // - TCP (IPv4 and IPv6)
346
+ // - WebSocket (IPv4 and IPv6)
347
+ // - Memory transport (for testing)
348
+ ```
349
+
350
+ Features:
351
+ - ✅ Accepts incoming connections
352
+ - ✅ Full DHT participation
353
+ - ✅ Network advertising
354
+ - ✅ Suitable for 24/7 operation
355
+
356
+ ### 2. oNode - Base Implementation
357
+
358
+ Best for: Custom configurations, specialized transports
359
+
360
+ ```typescript
361
+ import { oNode } from '@olane/o-node';
362
+
363
+ class CustomNode extends oNode {
364
+ configureTransports(): any[] {
365
+ // Customize your transport configuration
366
+ return [customTransport1, customTransport2];
367
+ }
368
+ }
369
+ ```
370
+
371
+ ### 3. Client & WebSocket Variants
372
+
373
+ ```typescript
374
+ // Client node (lightweight, dial-only)
375
+ import { oClientNode } from '@olane/o-node';
376
+
377
+ const client = new oClientNode({
378
+ address: new oNodeAddress('o://client'),
379
+ leader: leaderAddress
380
+ });
381
+
382
+ // WebSocket-only node (browser-compatible)
383
+ import { oWebSocketNode } from '@olane/o-node';
384
+
385
+ const wsNode = new oWebSocketNode({
386
+ address: new oNodeAddress('o://ws-agent'),
387
+ leader: leaderAddress
388
+ });
389
+ ```
390
+
391
+ ## Advanced Usage
392
+
393
+ ### Custom Network Configuration
394
+
395
+ ```typescript
396
+ import { oServerNode } from '@olane/o-node';
397
+ import { tcp, webSockets } from '@olane/o-config';
398
+
399
+ const agent = new oServerNode({
400
+ address: new oNodeAddress('o://custom'),
401
+ type: NodeType.AGENT,
402
+ leader: leaderAddress,
403
+ parent: parentAddress,
404
+ network: {
405
+ // Custom listeners
406
+ listeners: [
407
+ '/ip4/0.0.0.0/tcp/4001',
408
+ '/ip4/0.0.0.0/tcp/4002/ws'
409
+ ],
410
+
411
+ // Custom transports
412
+ transports: [tcp(), webSockets()],
413
+
414
+ // Connection management
415
+ connectionManager: {
416
+ minConnections: 5,
417
+ maxConnections: 50,
418
+ pollInterval: 2000,
419
+ autoDialInterval: 10000,
420
+ dialTimeout: 30000
421
+ },
422
+
423
+ // Peer discovery
424
+ peerDiscovery: [
425
+ bootstrap({
426
+ list: ['/dnsaddr/bootstrap.libp2p.io/p2p/...']
427
+ })
428
+ ]
429
+ }
430
+ });
431
+
432
+ await agent.start();
433
+ ```
434
+
435
+ ### Custom Connection Gating
436
+
437
+ ```typescript
438
+ const agent = new oServerNode({
439
+ address: new oNodeAddress('o://secure'),
440
+ type: NodeType.AGENT,
441
+ leader: leaderAddress,
442
+ parent: parentAddress,
443
+ network: {
444
+ connectionGater: {
445
+ // Who can connect to us?
446
+ denyInboundEncryptedConnection: (peerId, maConn) => {
447
+ // Allow parent
448
+ if (peerId.toString() === parentPeerId) {
449
+ return false;
450
+ }
451
+
452
+ // Allow whitelisted peers
453
+ if (whitelist.includes(peerId.toString())) {
454
+ return false;
455
+ }
456
+
457
+ // Deny everyone else
458
+ return true;
459
+ },
460
+
461
+ // Who can we connect to?
462
+ denyOutboundEncryptedConnection: (peerId, maConn) => {
463
+ // Custom outbound logic
464
+ return false; // Allow all outbound
465
+ }
466
+ }
467
+ }
468
+ });
469
+ ```
470
+
471
+ ### Network Utilities
472
+
473
+ ```typescript
474
+ import { NetworkUtils } from '@olane/o-node';
475
+
476
+ // Advertise your service on the network
477
+ await NetworkUtils.advertiseToNetwork(
478
+ address,
479
+ staticAddress,
480
+ p2pNode
481
+ );
482
+
483
+ // Find a peer on the network
484
+ const peer = await NetworkUtils.findPeer(p2pNode, peerId);
485
+
486
+ // Find a node by address
487
+ const { transports } = await NetworkUtils.findNode(p2pNode, address);
488
+ ```
489
+
490
+ ### Direct libp2p Access
491
+
492
+ When you need low-level control:
493
+
494
+ ```typescript
495
+ const agent = new oServerNode(config);
496
+ await agent.start();
497
+
498
+ // Access the underlying libp2p node
499
+ const libp2p = agent.p2pNode;
500
+
501
+ // Direct libp2p operations
502
+ const connections = libp2p.getConnections();
503
+ const peers = await libp2p.peerStore.all();
504
+ const protocols = libp2p.getProtocols();
505
+
506
+ // Listen for libp2p events
507
+ libp2p.addEventListener('peer:connect', (evt) => {
508
+ console.log('Peer connected:', evt.detail.toString());
509
+ });
510
+
511
+ libp2p.addEventListener('peer:disconnect', (evt) => {
512
+ console.log('Peer disconnected:', evt.detail.toString());
513
+ });
514
+
515
+ // Manual dialing
516
+ const connection = await libp2p.dial(multiaddr);
517
+ const stream = await connection.newStream('/my-protocol/1.0.0');
518
+ ```
519
+
520
+ ### Implementing Custom Protocols
521
+
522
+ ```typescript
523
+ import { oServerNode } from '@olane/o-node';
524
+ import { pipe } from '@olane/o-config';
525
+
526
+ class CustomProtocolNode extends oServerNode {
527
+ async initialize(): Promise<void> {
528
+ await super.initialize();
529
+
530
+ // Register custom protocol handler
531
+ await this.p2pNode.handle('/my-custom-protocol/1.0.0', async ({ stream }) => {
532
+ pipe(
533
+ stream,
534
+ async function* (source) {
535
+ for await (const msg of source) {
536
+ // Process incoming messages
537
+ const data = new TextDecoder().decode(msg.subarray());
538
+ const response = await handleCustomMessage(data);
539
+ yield new TextEncoder().encode(response);
540
+ }
541
+ },
542
+ stream
543
+ );
544
+ });
545
+ }
546
+ }
547
+ ```
548
+
549
+ ### Memory Transport for Testing
550
+
551
+ ```typescript
552
+ import { oServerNode, oNodeAddress } from '@olane/o-node';
553
+
554
+ // Create nodes with memory transport (no network required)
555
+ const agent1 = new oServerNode({
556
+ address: new oNodeAddress('o://agent1'),
557
+ type: NodeType.AGENT,
558
+ leader: null,
559
+ parent: null,
560
+ network: {
561
+ listeners: ['/memory/test-network']
562
+ }
563
+ });
564
+
565
+ const agent2 = new oServerNode({
566
+ address: new oNodeAddress('o://agent2'),
567
+ type: NodeType.AGENT,
568
+ leader: new oNodeAddress('o://agent1', agent1.transports),
569
+ parent: new oNodeAddress('o://agent1', agent1.transports)
570
+ });
571
+
572
+ await agent1.start();
573
+ await agent2.start();
574
+
575
+ // Agents can communicate in-memory (perfect for tests!)
576
+ const response = await agent1.use(agent2.address, {
577
+ method: 'test',
578
+ params: {}
579
+ });
580
+ ```
581
+
582
+ ## API Reference
583
+
584
+ ### oNode Class
585
+
586
+ Extends `oToolBase` from `@olane/o-tool`, which extends `oCore` from `@olane/o-core`.
587
+
588
+ #### Constructor
589
+
590
+ ```typescript
591
+ new oNode(config: oNodeConfig)
592
+ ```
593
+
594
+ #### Configuration
595
+
596
+ ```typescript
597
+ interface oNodeConfig extends oCoreConfig {
598
+ leader: oNodeAddress | null; // Leader node address with transports
599
+ parent: oNodeAddress | null; // Parent node address with transports
600
+ seed?: string; // Seed for consistent peer ID
601
+ network?: Libp2pConfig; // libp2p configuration
602
+ }
603
+ ```
604
+
605
+ #### Properties
606
+
607
+ | Property | Type | Description |
608
+ |----------|------|-------------|
609
+ | `p2pNode` | `Libp2p` | Underlying libp2p node instance |
610
+ | `peerId` | `PeerId` | This node's libp2p peer ID |
611
+ | `transports` | `oNodeTransport[]` | Available network transports |
612
+ | `address` | `oNodeAddress` | Full hierarchical address |
613
+ | `staticAddress` | `oNodeAddress` | Static (non-hierarchical) address |
614
+ | `leader` | `oNodeAddress \| null` | Leader node reference |
615
+ | `hierarchyManager` | `oNodeHierarchyManager` | Hierarchy management |
616
+
617
+ #### Methods
618
+
619
+ | Method | Purpose | Returns |
620
+ |--------|---------|---------|
621
+ | `async start()` | Start the node and join network | `Promise<void>` |
622
+ | `async stop()` | Stop the node gracefully | `Promise<void>` |
623
+ | `async initialize()` | Initialize libp2p and connections | `Promise<void>` |
624
+ | `async register()` | Register with leader node | `Promise<void>` |
625
+ | `async unregister()` | Unregister from leader | `Promise<void>` |
626
+ | `async connect(nextHop, target)` | Connect to another node | `Promise<oNodeConnection>` |
627
+ | `configureTransports()` | Configure libp2p transports | `any[]` |
628
+
629
+ ### oNodeAddress Class
630
+
631
+ Extends `oAddress` from `@olane/o-core` with libp2p transport support.
632
+
633
+ ```typescript
634
+ // Create with transports
635
+ const address = new oNodeAddress(
636
+ 'o://my-agent',
637
+ [transport1, transport2]
638
+ );
639
+
640
+ // Get libp2p-specific transports
641
+ const libp2pTransports = address.libp2pTransports;
642
+
643
+ // Convert to multiaddresses
644
+ const multiaddrs = libp2pTransports.map(t => t.toMultiaddr());
645
+ ```
646
+
647
+ ### oNodeConnection Class
648
+
649
+ Extends `oConnection` from `@olane/o-core` with libp2p stream support.
650
+
651
+ ```typescript
652
+ // Connection uses libp2p streams
653
+ class oNodeConnection extends oConnection {
654
+ protected p2pConnection: Connection;
655
+
656
+ async transmit(request: oRequest): Promise<oResponse> {
657
+ // Creates new stream, sends request, waits for response
658
+ }
659
+ }
660
+ ```
661
+
662
+ ### oNodeRouter Class
663
+
664
+ Extends `oRouter` from `@olane/o-core` with libp2p routing.
665
+
666
+ ```typescript
667
+ class oNodeRouter extends oRouter {
668
+ async translate(address, node): Promise<RouteResponse> {
669
+ // Resolves address to next hop with libp2p transports
670
+ }
671
+
672
+ isInternal(address, node): boolean {
673
+ // Determines if address is in local network
674
+ }
675
+ }
676
+ ```
677
+
678
+ ## Network Architecture Patterns
679
+
680
+ ### Hub-and-Spoke (Star) Network
681
+
682
+ Best for: Centralized control, simple management
683
+
684
+ ```typescript
685
+ // Leader (hub)
686
+ const leader = new oServerNode({
687
+ address: new oNodeAddress('o://leader'),
688
+ type: NodeType.LEADER,
689
+ leader: null,
690
+ parent: null
691
+ });
692
+
693
+ await leader.start();
694
+
695
+ // Spokes (all connect to leader)
696
+ const agents = await Promise.all([
697
+ createAgent('o://agent1', leader.transports),
698
+ createAgent('o://agent2', leader.transports),
699
+ createAgent('o://agent3', leader.transports)
700
+ ]);
701
+
702
+ // All communication routes through leader
703
+ ```
704
+
705
+ ### Hierarchical Network
706
+
707
+ Best for: Large-scale deployments, organizational structure
708
+
709
+ ```typescript
710
+ // Root leader
711
+ const root = await createLeader('o://company');
712
+
713
+ // Department leaders
714
+ const finance = await createAgent('o://company/finance', root);
715
+ const engineering = await createAgent('o://company/engineering', root);
716
+
717
+ // Team agents
718
+ const financeTeam1 = await createAgent('o://company/finance/accounting', finance);
719
+ const financeTeam2 = await createAgent('o://company/finance/payroll', finance);
720
+
721
+ // Agents inherit hierarchy automatically
722
+ ```
723
+
724
+ ### Mesh Network
725
+
726
+ Best for: High availability, redundancy
727
+
728
+ ```typescript
729
+ // All agents connect to multiple peers
730
+ const agents = await Promise.all([
731
+ createAgent('o://agent1'),
732
+ createAgent('o://agent2'),
733
+ createAgent('o://agent3')
734
+ ]);
735
+
736
+ // Configure each agent to know about all others
737
+ // libp2p will handle mesh routing automatically
738
+ ```
739
+
740
+ ## Best Practices
741
+
742
+ ### 1. Always Use Seeds in Production
743
+
744
+ ```typescript
745
+ // ✅ Good - Consistent peer ID
746
+ const agent = new oServerNode({
747
+ address: new oNodeAddress('o://service'),
748
+ seed: process.env.AGENT_SEED, // From secure source
749
+ leader: leaderAddress
750
+ });
751
+
752
+ // ❌ Bad - Peer ID changes on every restart
753
+ const agent = new oServerNode({
754
+ address: new oNodeAddress('o://service'),
755
+ // No seed - temporary peer ID
756
+ leader: leaderAddress
757
+ });
758
+ ```
759
+
760
+ ### 2. Handle Network Events
761
+
762
+ ```typescript
763
+ const agent = new oServerNode(config);
764
+ await agent.start();
765
+
766
+ // Monitor connection health
767
+ agent.p2pNode.addEventListener('peer:connect', (evt) => {
768
+ console.log('Connected to:', evt.detail.toString());
769
+ });
770
+
771
+ agent.p2pNode.addEventListener('peer:disconnect', (evt) => {
772
+ console.warn('Disconnected from:', evt.detail.toString());
773
+ // Implement reconnection logic if needed
774
+ });
775
+
776
+ agent.p2pNode.addEventListener('connection:prune', () => {
777
+ console.log('Pruned inactive connections');
778
+ });
779
+ ```
780
+
781
+ ### 3. Configure Connection Limits
782
+
783
+ ```typescript
784
+ const agent = new oServerNode({
785
+ address: new oNodeAddress('o://service'),
786
+ leader: leaderAddress,
787
+ network: {
788
+ connectionManager: {
789
+ minConnections: 10, // Stay connected to at least 10 peers
790
+ maxConnections: 100, // Don't exceed 100 connections
791
+ pollInterval: 2000, // Check every 2 seconds
792
+ autoDialInterval: 10000 // Dial new peers every 10 seconds
793
+ }
794
+ }
795
+ });
796
+ ```
797
+
798
+ ### 4. Implement Graceful Shutdown
799
+
800
+ ```typescript
801
+ import { setupGracefulShutdown } from '@olane/o-core';
802
+
803
+ const agent = new oServerNode(config);
804
+ await agent.start();
805
+
806
+ setupGracefulShutdown(async () => {
807
+ console.log('Shutting down gracefully...');
808
+
809
+ // Unregister from network
810
+ await agent.unregister();
811
+
812
+ // Close connections
813
+ await agent.stop();
814
+
815
+ console.log('Shutdown complete');
816
+ });
817
+ ```
818
+
819
+ ### 5. Use Memory Transport for Tests
820
+
821
+ ```typescript
822
+ // test.spec.ts
823
+ describe('Agent Communication', () => {
824
+ it('should communicate between agents', async () => {
825
+ const agent1 = new oServerNode({
826
+ address: new oNodeAddress('o://test1'),
827
+ network: { listeners: ['/memory/test'] }
828
+ });
829
+
830
+ const agent2 = new oServerNode({
831
+ address: new oNodeAddress('o://test2'),
832
+ leader: new oNodeAddress('o://test1', agent1.transports)
833
+ });
834
+
835
+ await agent1.start();
836
+ await agent2.start();
837
+
838
+ const response = await agent1.use(agent2.address, {
839
+ method: 'test'
840
+ });
841
+
842
+ expect(response.result).toBeDefined();
843
+
844
+ await agent1.stop();
845
+ await agent2.stop();
846
+ });
847
+ });
848
+ ```
849
+
850
+ ### 6. Monitor Network Health
851
+
852
+ ```typescript
853
+ class MonitoredNode extends oServerNode {
854
+ private healthCheckInterval?: NodeJS.Timeout;
855
+
856
+ async start(): Promise<void> {
857
+ await super.start();
858
+
859
+ // Start health monitoring
860
+ this.healthCheckInterval = setInterval(() => {
861
+ const connections = this.p2pNode.getConnections();
862
+ const peers = this.p2pNode.getPeers();
863
+
864
+ console.log('Health Check:', {
865
+ connections: connections.length,
866
+ peers: peers.length,
867
+ protocols: this.p2pNode.getProtocols()
868
+ });
869
+
870
+ // Alert if disconnected
871
+ if (connections.length === 0 && this.leader) {
872
+ console.warn('No active connections! Attempting reconnect...');
873
+ this.reconnectToLeader();
874
+ }
875
+ }, 30000); // Every 30 seconds
876
+ }
877
+
878
+ async stop(): Promise<void> {
879
+ if (this.healthCheckInterval) {
880
+ clearInterval(this.healthCheckInterval);
881
+ }
882
+ await super.stop();
883
+ }
884
+
885
+ private async reconnectToLeader(): Promise<void> {
886
+ if (!this.leader) return;
887
+
888
+ try {
889
+ await this.register();
890
+ console.log('Reconnected to leader');
891
+ } catch (error) {
892
+ console.error('Failed to reconnect:', error);
893
+ }
894
+ }
895
+ }
896
+ ```
897
+
898
+ ## Performance Considerations
899
+
900
+ 1. **Connection Pooling** - o-node manages connection reuse automatically
901
+ 2. **Stream Multiplexing** - Multiple requests over single connection
902
+ 3. **DHT Caching** - Peer information is cached locally
903
+ 4. **NAT Traversal** - Automatic hole-punching and relay fallback
904
+ 5. **Concurrent Requests** - Handle multiple requests simultaneously
905
+
906
+ ## Troubleshooting
907
+
908
+ ### Connection Issues
909
+
910
+ ```typescript
911
+ // Enable debug logging
912
+ import debug from 'debug';
913
+
914
+ debug.enable('libp2p:*');
915
+ debug.enable('o-protocol:*');
916
+
917
+ const agent = new oServerNode(config);
918
+ await agent.start();
919
+ ```
920
+
921
+ ### "Can not dial self" Error
922
+
923
+ ```typescript
924
+ // This means you're trying to connect to your own address
925
+ // Make sure leader/parent addresses have the correct transports
926
+
927
+ // ❌ Wrong
928
+ const agent = new oServerNode({
929
+ address: new oNodeAddress('o://agent'),
930
+ leader: new oNodeAddress('o://leader') // Missing transports!
931
+ });
932
+
933
+ // ✅ Correct
934
+ const agent = new oServerNode({
935
+ address: new oNodeAddress('o://agent'),
936
+ leader: new oNodeAddress('o://leader', leaderTransports)
937
+ });
938
+ ```
939
+
940
+ ### Peer Discovery Issues
941
+
942
+ ```typescript
943
+ // Add bootstrap nodes for better discovery
944
+ const agent = new oServerNode({
945
+ address: new oNodeAddress('o://agent'),
946
+ leader: leaderAddress,
947
+ network: {
948
+ peerDiscovery: [
949
+ bootstrap({
950
+ list: [
951
+ '/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN',
952
+ '/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa'
953
+ ]
954
+ })
955
+ ]
956
+ }
957
+ });
958
+ ```
959
+
960
+ ## Testing
961
+
962
+ ```bash
963
+ # Run tests
964
+ npm test
965
+
966
+ # Run tests in Node.js
967
+ npm run test:node
968
+
969
+ # Run tests in browser
970
+ npm run test:browser
971
+ ```
972
+
973
+ ## Development
974
+
975
+ ```bash
976
+ # Install dependencies
977
+ npm install
978
+
979
+ # Build the package
980
+ npm run build
981
+
982
+ # Run in development mode with debug output
983
+ npm run dev
984
+
985
+ # Update o-core dependency
986
+ npm run update:lib
987
+
988
+ # Lint the code
989
+ npm run lint
990
+ ```
991
+
992
+ ## Related Packages
993
+
994
+ - `@olane/o-core` - Abstract agent runtime (this implements it)
995
+ - `@olane/o-config` - libp2p configuration and utilities
996
+ - `@olane/o-protocol` - Protocol definitions and types
997
+ - `@olane/o-tool` - Tool system for agent capabilities
998
+ - `@olane/o-network-cli` - CLI for managing agent networks
999
+
1000
+ ## Documentation
1001
+
1002
+ - [o-core Documentation](../o-core/README.md) - Understand the abstract runtime
1003
+ - [o-core Router System](../o-core/src/router/README.md) - Deep dive into routing
1004
+ - [o-core Connection System](../o-core/src/connection/README.md) - IPC layer details
1005
+ - [Full Documentation](https://olane.com/docs)
1006
+ - [libp2p Documentation](https://docs.libp2p.io/)
1007
+
1008
+ ## Support
1009
+
1010
+ - [GitHub Issues](https://github.com/olane-labs/olane/issues)
1011
+ - [Community Forum](https://olane.com/community)
1012
+ - [Email Support](mailto:support@olane.com)
1013
+
1014
+ ## Contributing
1015
+
1016
+ We welcome contributions! Please see our [Contributing Guide](../../CONTRIBUTING.md) for details.
1017
+
1018
+ ## License
1019
+
1020
+ ISC © Olane Inc.
1021
+
1022
+ ---
1023
+
1024
+ **Part of the Olane OS ecosystem** - The production distribution layer where you build tool nodes that AI agents use. An agentic operating system where AI agents are the users, tool nodes are the applications, and Olane provides the runtime.