@olane/o-leader 0.6.13 → 0.7.2

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.
package/README.md CHANGED
@@ -1,86 +1,1164 @@
1
- TLDR; we created a forked MCP version that is faster, better, and cheaper. [Link to get started]
1
+ # o-leader README.md Outline
2
2
 
3
- ## What is MCP Missing?
3
+ ## 1. Overview (30 seconds)
4
4
 
5
- ### **Today / Problem Description**
5
+ ### What is o-leader?
6
+ - **One-line definition**: The root coordinator node for Olane OS agent networks
7
+ - **Business value statement**: Provides centralized coordination and discovery for distributed agent networks
8
+ - **Key differentiator**: Self-organizing agent networks without manual infrastructure configuration
6
9
 
7
- MCP servers are built to enable LLM / AI systems to synthesize workflows from complex tasks. This means MCPs will work great if…
10
+ ### When to use o-leader
11
+ - Building multi-agent systems requiring coordination
12
+ - Creating discoverable agent networks
13
+ - Implementing hierarchical agent architectures
14
+ - Scaling from single-agent to multi-agent systems
8
15
 
9
- 1. You have built your MCP well (example: *as an intention-based tool, not as an API wrapper)*
10
- 1. *You actively maintain* documentation to support *how* to use your services
11
- 2. LLM / AI understands how to synthesize plans around small workflows using the tools provided
12
- 2. You pay for intelligent models that can reason / do chain of thought processing.
16
+ ### Core capabilities at a glance
17
+ - **Network Coordination**: Entry point for agents joining the network
18
+ - **Agent Discovery**: Registry service for finding and connecting to agents
19
+ - **Network Intelligence**: Indexing and mapping of agent capabilities
20
+ - **Fault Tolerance**: Automatic failover and recovery coordination
13
21
 
14
- Every LLM / AI system will need to rerun this, every time. Today it has no working memory on the workflows/plans it runs.
22
+ ---
15
23
 
16
- We asked ourselves…”why are these plans and workflows being thrown out?”
24
+ ## 2. Quick Start (5 minutes)
17
25
 
18
- ### **Olane + MCP = oMCP**
26
+ ### Prerequisites
27
+ - Node.js 20.x or higher
28
+ - Basic understanding of Olane OS concepts
29
+ - An o-core installation
19
30
 
20
- We have forked the MCP client & server to capture and re-use these workflows, reducing intelligence requirements and improving MCP completion by X%. [Link to the repo]
31
+ ### Installation
32
+ ```bash
33
+ npm install @olane/o-leader
34
+ ```
35
+
36
+ ### Basic Leader Node Setup
37
+ ```typescript
38
+ import { oLeaderNode } from '@olane/o-leader';
39
+ import { RegistryMemoryTool } from '@olane/o-leader';
40
+
41
+ // Create a leader node
42
+ const leader = new oLeaderNode({
43
+ networkName: 'my-agent-network',
44
+ // configuration options
45
+ });
46
+
47
+ // Start the leader
48
+ await leader.start();
49
+
50
+ // Leader is now ready to coordinate your agent network
51
+ ```
52
+
53
+ ### Expected Output
54
+ - Leader node running at `o://leader`
55
+ - Registry service available at `o://registry`
56
+ - Network ready to accept agent join requests
57
+
58
+ ### Next Steps
59
+ - [Add agents to your network](#joining-agents-to-network)
60
+ - [Configure network policies](#network-policies)
61
+ - [Implement custom validation](#custom-join-validation)
62
+
63
+ ---
64
+
65
+ ## 3. Core Concepts
66
+
67
+ ### Leader Node Architecture
68
+
69
+ #### What is a Leader Node?
70
+ The leader node is the **root coordinator** of an Olane OS agent network. Unlike traditional orchestrators, it enables **emergent coordination** rather than explicit control.
71
+
72
+ #### Key Responsibilities
73
+ 1. **Network Entry Point**: First contact for agents joining the network
74
+ 2. **Registry Management**: Maintains live directory of agents and capabilities
75
+ 3. **Discovery Coordination**: Helps agents find each other via `o://` addressing
76
+ 4. **Network Intelligence**: Tracks and indexes agent capabilities across the network
77
+
78
+ #### Leader vs Traditional Orchestration
79
+ | Traditional Orchestrators | o-leader Node |
80
+ |--------------------------|---------------|
81
+ | Pre-defined workflows | Emergent workflows |
82
+ | Centralized control | Distributed coordination |
83
+ | Manual scaling | Self-organizing |
84
+ | Fixed topology | Dynamic hierarchy |
85
+
86
+ ### The Registry Service
87
+
88
+ #### Purpose
89
+ The registry is the **discovery mechanism** for your agent network - a dynamic directory where agents register their capabilities and find other agents.
90
+
91
+ #### Registry Operations
92
+ - **`commit`**: Register an agent and its capabilities
93
+ - **`search`**: Find agents by address, protocol, or capability
94
+ - **find_all`**: List all registered agents
95
+ - **`remove`**: Deregister an agent from the network
96
+
97
+ #### How Agents Use the Registry
98
+ ```typescript
99
+ // Agent searches for specialized capabilities
100
+ const agents = await leader.use(new oAddress('o://registry'), {
101
+ method: 'search',
102
+ params: {
103
+ protocols: ['payment-processing', 'tax-calculation']
104
+ }
105
+ });
106
+
107
+ // Returns all agents with these capabilities
108
+ ```
109
+
110
+ ### Network Joining Flow
111
+
112
+ #### The Join Process
113
+ 1. New agent makes join request to leader (`o://leader`)
114
+ 2. Leader validates the join request (customizable)
115
+ 3. Leader updates parent-child relationships
116
+ 4. Agent is registered in the registry
117
+ 5. Agent receives network configuration
118
+ 6. Agent can now discover and communicate with other agents
119
+
120
+ #### Join Request Structure
121
+ ```typescript
122
+ {
123
+ caller: 'o://company/finance/analyst',
124
+ parent: 'o://company/finance',
125
+ transports: ['webrtc', 'websocket']
126
+ }
127
+ ```
128
+
129
+ ### Network Indexing
130
+
131
+ #### What is Network Indexing?
132
+ Periodic crawling of all registered agents to build a **comprehensive map** of network capabilities, enabling intelligent routing and discovery.
133
+
134
+ #### Why Indexing Matters
135
+ - **Capability Discovery**: Agents can find specialized tools across the network
136
+ - **Intelligent Routing**: Requests automatically routed to capable agents
137
+ - **Network Health**: Identify disconnected or unresponsive agents
138
+ - **Knowledge Mapping**: Build network-wide capability graph
139
+
140
+ ---
141
+
142
+ ## 4. Integration Guide
143
+
144
+ ### Setting Up Your Leader Node
145
+
146
+ #### Basic Configuration
147
+ ```typescript
148
+ import { oLeaderNode } from '@olane/o-leader';
149
+ import { RegistryMemoryTool } from '@olane/o-leader';
150
+
151
+ const leader = new oLeaderNode({
152
+ networkName: 'production-agents',
153
+ address: oAddress.leader(), // o://leader
154
+ type: NodeType.LEADER,
155
+ // Optional: custom registry implementation
156
+ registry: new RegistryMemoryTool(config)
157
+ });
158
+
159
+ await leader.start();
160
+ ```
161
+
162
+ #### Configuration Options
163
+ - `networkName`: Identifier for your agent network
164
+ - `address`: Network address (defaults to `o://leader`)
165
+ - `type`: Node type (always `NodeType.LEADER`)
166
+ - `methods`: Custom methods exposed by the leader
167
+ - `registry`: Registry implementation (memory or persistent)
168
+
169
+ ### Joining Agents to Network
170
+
171
+ #### From an Agent Node
172
+ ```typescript
173
+ import { oNode } from '@olane/o-node';
174
+
175
+ const agent = new oNode({
176
+ address: 'o://company/sales/analyst',
177
+ parent: 'o://company/sales'
178
+ });
179
+
180
+ // Join the network via leader
181
+ await agent.use(oAddress.leader(), {
182
+ method: 'join_network',
183
+ params: {
184
+ caller: agent.address.toString(),
185
+ parent: 'o://company/sales',
186
+ transports: ['webrtc']
187
+ }
188
+ });
189
+ ```
190
+
191
+ #### Join Request Validation
192
+ Customize validation logic for network access control:
193
+
194
+ ```typescript
195
+ class CustomLeader extends oLeaderNode {
196
+ async validateJoinRequest(request: oRequest): Promise<boolean> {
197
+ const { caller, parent } = request.params;
198
+
199
+ // Custom validation logic
200
+ if (!this.isAuthorizedParent(parent)) {
201
+ throw new Error('Unauthorized parent address');
202
+ }
203
+
204
+ if (!this.meetsSecurityRequirements(caller)) {
205
+ throw new Error('Agent does not meet security requirements');
206
+ }
207
+
208
+ return true;
209
+ }
210
+ }
211
+ ```
212
+
213
+ ### Using the Registry
214
+
215
+ #### Registering Agent Capabilities
216
+ ```typescript
217
+ // Commit agent to registry
218
+ await leader.use(new oAddress('o://registry'), {
219
+ method: 'commit',
220
+ params: {
221
+ peerId: 'QmXxxx...', // libp2p peer ID
222
+ address: 'o://company/finance/analyst',
223
+ staticAddress: 'analyst-prod-01',
224
+ protocols: [
225
+ 'financial-analysis',
226
+ 'report-generation',
227
+ 'data-visualization'
228
+ ],
229
+ transports: ['webrtc', 'websocket']
230
+ }
231
+ });
232
+ ```
233
+
234
+ #### Searching for Agents
235
+ ```typescript
236
+ // Find agents by capability
237
+ const analysts = await leader.use(new oAddress('o://registry'), {
238
+ method: 'search',
239
+ params: {
240
+ protocols: ['financial-analysis']
241
+ }
242
+ });
243
+
244
+ // Find agent by address
245
+ const agent = await leader.use(new oAddress('o://registry'), {
246
+ method: 'search',
247
+ params: {
248
+ address: 'o://company/finance/analyst'
249
+ }
250
+ });
251
+
252
+ // Find by static address (for stable references)
253
+ const stable = await leader.use(new oAddress('o://registry'), {
254
+ method: 'search',
255
+ params: {
256
+ staticAddress: 'analyst-prod-01'
257
+ }
258
+ });
259
+ ```
260
+
261
+ #### Listing All Agents
262
+ ```typescript
263
+ const allAgents = await leader.use(new oAddress('o://registry'), {
264
+ method: 'find_all',
265
+ params: {}
266
+ });
21
267
 
22
- ## How did we do this?
268
+ console.log(`Network has ${allAgents.result.length} active agents`);
269
+ ```
270
+
271
+ ### Network Indexing
272
+
273
+ #### Triggering Network Index
274
+ ```typescript
275
+ // Index entire network
276
+ await leader.use(oAddress.leader(), {
277
+ method: 'index_network',
278
+ params: {}
279
+ });
280
+
281
+ // This crawls all registered agents and indexes their capabilities
282
+ ```
283
+
284
+ #### Custom Indexing Logic
285
+ Extend the leader to implement custom indexing:
286
+
287
+ ```typescript
288
+ class CustomLeader extends oLeaderNode {
289
+ async _tool_index_network(request: oRequest): Promise<any> {
290
+ // Get all registered nodes
291
+ const nodes = await this.use(
292
+ new oAddress(RestrictedAddresses.REGISTRY),
293
+ { method: 'find_all', params: {} }
294
+ );
295
+
296
+ // Custom indexing per node
297
+ for (const node of nodes.result.data) {
298
+ const capabilities = await this.indexNodeCapabilities(node);
299
+ await this.storeCapabilities(node.address, capabilities);
300
+ }
301
+
302
+ return { message: 'Network indexed with custom logic!' };
303
+ }
304
+ }
305
+ ```
306
+
307
+ ---
308
+
309
+ ## 5. Advanced Topics
310
+
311
+ ### Custom Registry Implementations
312
+
313
+ #### Why Custom Registries?
314
+ The default `RegistryMemoryTool` stores registrations in memory, which is great for development but not persistent. For production, implement a persistent registry.
315
+
316
+ #### Persistent Registry Example
317
+ ```typescript
318
+ import { RegistryTool } from '@olane/o-leader';
319
+ import { oRequest } from '@olane/o-core';
23
320
 
24
- We centered our focus on these problems:
321
+ class PostgresRegistryTool extends RegistryTool {
322
+ constructor(config: oNodeToolConfig, private db: Database) {
323
+ super(config);
324
+ }
25
325
 
26
- 1. How can we enable smaller models to succeed just like bigger ones?
27
- 2. How can we reduce waste / reduce token usage?
28
- 3. How can we make AI - MCP usage more deterministic?
29
- 4. How can we improve the speed of MCP usage?
326
+ async _tool_commit(request: oRequest): Promise<any> {
327
+ const params = request.params as oRegistrationParams;
328
+
329
+ await this.db.query(`
330
+ INSERT INTO agent_registry (peer_id, address, protocols, transports)
331
+ VALUES ($1, $2, $3, $4)
332
+ ON CONFLICT (peer_id) DO UPDATE SET
333
+ address = EXCLUDED.address,
334
+ protocols = EXCLUDED.protocols,
335
+ transports = EXCLUDED.transports,
336
+ updated_at = NOW()
337
+ `, [params.peerId, params.address, params.protocols, params.transports]);
338
+
339
+ return { success: true };
340
+ }
341
+
342
+ async _tool_search(request: oRequest): Promise<any> {
343
+ const params = request.params as oRegistrySearchParams;
344
+ // Implement database search logic
345
+ }
346
+
347
+ // Implement other methods...
348
+ }
349
+ ```
30
350
 
31
- Like teaching a small child, we learned that by simply following the KISS model (KISS → “keep it simple stupid”), we achieved all of this and more.
351
+ #### Using Custom Registry
352
+ ```typescript
353
+ const db = new Database(dbConfig);
354
+ const registry = new PostgresRegistryTool(config, db);
32
355
 
33
- > Smaller AI models need less noise and more clear instruction to succeed. In other words, “spell it out for them”
34
- >
356
+ const leader = new oLeaderNode({
357
+ ...config,
358
+ registry: registry
359
+ });
360
+ ```
35
361
 
36
- <aside>
37
- 💡
362
+ ### Multi-Leader Networks
38
363
 
39
- *Engaging / thoughtful hook? Brendon scratchpad*
364
+ #### When to Use Multiple Leaders
365
+ - **Geographic Distribution**: Leader per region for latency
366
+ - **Organizational Boundaries**: Leader per department or team
367
+ - **Fault Tolerance**: Backup leaders for high availability
368
+ - **Scale**: Distribute coordination load across leaders
40
369
 
41
- How do you get the *right* context from an MCP server to complete your task?
370
+ #### Federation Pattern
371
+ ```typescript
372
+ // Primary leader
373
+ const primaryLeader = new oLeaderNode({
374
+ networkName: 'global-network',
375
+ address: new oAddress('o://leader/primary')
376
+ });
42
377
 
43
- - Do you just throw everything at it? → No, this is wasteful
44
- - Do you try to condense the knowledge to cost optimize? → Maybe…but how without data loss
45
- - Do you try to organize MCP usage and learn from similar use-cases? Let’s try it and see what happens…
46
- </aside>
378
+ // Regional leaders
379
+ const usLeader = new oLeaderNode({
380
+ networkName: 'us-network',
381
+ address: new oAddress('o://leader/us'),
382
+ parent: 'o://leader/primary'
383
+ });
47
384
 
48
- ![normal-mcp.png](./docs/assets/normal-mcp.png)
385
+ const euLeader = new oLeaderNode({
386
+ networkName: 'eu-network',
387
+ address: new oAddress('o://leader/eu'),
388
+ parent: 'o://leader/primary'
389
+ });
49
390
 
50
- ![o-mcp-flow.png](./docs/assets/o-mcp-flow.png)
391
+ // Each regional leader manages its own registry
392
+ // but can query primary leader for global discovery
393
+ ```
51
394
 
52
- ### Breaking it down further…
395
+ ### Security and Access Control
53
396
 
54
- We combine large model successes + failures + a little search to help give small models a helping hand in achieving their dreams.
397
+ #### Network Access Policies
398
+ ```typescript
399
+ class SecureLeader extends oLeaderNode {
400
+ private allowedNetworks = new Set(['o://company/*']);
401
+ private requiresAuth = true;
402
+
403
+ async validateJoinRequest(request: oRequest): Promise<boolean> {
404
+ const { caller, authToken } = request.params;
405
+
406
+ // Verify authentication
407
+ if (this.requiresAuth && !this.verifyToken(authToken)) {
408
+ throw new Error('Authentication required');
409
+ }
410
+
411
+ // Check network authorization
412
+ const isAllowed = Array.from(this.allowedNetworks).some(pattern =>
413
+ this.matchesPattern(caller, pattern)
414
+ );
415
+
416
+ if (!isAllowed) {
417
+ throw new Error(`Address ${caller} not authorized for this network`);
418
+ }
419
+
420
+ // Rate limiting
421
+ if (this.exceedsJoinRateLimit(request.metadata.peerId)) {
422
+ throw new Error('Join rate limit exceeded');
423
+ }
424
+
425
+ return true;
426
+ }
427
+ }
428
+ ```
55
429
 
56
- <aside>
57
- 💡
430
+ #### Registry Access Control
431
+ ```typescript
432
+ class ProtectedRegistry extends RegistryTool {
433
+ async _tool_search(request: oRequest): Promise<any> {
434
+ // Verify requesting agent has permission
435
+ const requester = request.metadata.caller;
436
+ if (!this.canSearch(requester)) {
437
+ throw new Error('Insufficient permissions for registry search');
438
+ }
439
+
440
+ // Filter results based on permissions
441
+ const results = await this.performSearch(request.params);
442
+ return this.filterByPermissions(results, requester);
443
+ }
444
+ }
445
+ ```
58
446
 
59
- We learn from past successes & failures to create few shot RL guidelines on how to best utilize the MCP server.
447
+ ### Network Health Monitoring
60
448
 
61
- </aside>
449
+ #### Health Check Implementation
450
+ ```typescript
451
+ class MonitoredLeader extends oLeaderNode {
452
+ async getNetworkHealth(): Promise<NetworkHealth> {
453
+ const allAgents = await this.use(
454
+ new oAddress('o://registry'),
455
+ { method: 'find_all', params: {} }
456
+ );
457
+
458
+ const health = {
459
+ totalAgents: allAgents.result.length,
460
+ activeAgents: 0,
461
+ unhealthyAgents: [],
462
+ timestamp: Date.now()
463
+ };
464
+
465
+ // Check each agent
466
+ for (const agent of allAgents.result) {
467
+ const isHealthy = await this.checkAgentHealth(agent);
468
+ if (isHealthy) {
469
+ health.activeAgents++;
470
+ } else {
471
+ health.unhealthyAgents.push(agent.address);
472
+ }
473
+ }
474
+
475
+ return health;
476
+ }
477
+ }
478
+ ```
62
479
 
63
- **Example**:
480
+ ### Performance Optimization
64
481
 
482
+ #### Registry Caching
483
+ ```typescript
484
+ class CachedRegistry extends RegistryTool {
485
+ private cache = new Map<string, CacheEntry>();
486
+ private cacheTTL = 60000; // 1 minute
487
+
488
+ async _tool_search(request: oRequest): Promise<any> {
489
+ const cacheKey = this.getCacheKey(request.params);
490
+ const cached = this.cache.get(cacheKey);
491
+
492
+ if (cached && !this.isExpired(cached)) {
493
+ return cached.data;
494
+ }
495
+
496
+ const results = await this.performSearch(request.params);
497
+ this.cache.set(cacheKey, {
498
+ data: results,
499
+ timestamp: Date.now()
500
+ });
501
+
502
+ return results;
503
+ }
504
+ }
65
505
  ```
66
- “Get my latest pull requests”
67
- Results in the following steps:
68
506
 
69
- 1. Client connects to MCP server with an “intent” + “model”
70
- 2. The MCP server searches for past success, failure and relevant tool methods
71
- 3. Client receives the package and creates new "workflow" tool uses
72
- 4. Execute!
507
+ #### Protocol Indexing Optimization
508
+ ```typescript
509
+ class OptimizedRegistry extends RegistryMemoryTool {
510
+ // Maintain protocol -> agents mapping for O(1) lookups
511
+ private protocolIndex = new Map<string, Set<string>>();
512
+
513
+ async _tool_commit(request: oRequest): Promise<any> {
514
+ const result = await super._tool_commit(request);
515
+
516
+ // Update protocol index
517
+ const { peerId, protocols } = request.params;
518
+ protocols.forEach(protocol => {
519
+ if (!this.protocolIndex.has(protocol)) {
520
+ this.protocolIndex.set(protocol, new Set());
521
+ }
522
+ this.protocolIndex.get(protocol)!.add(peerId);
523
+ });
524
+
525
+ return result;
526
+ }
527
+
528
+ async _tool_search(request: oRequest): Promise<any> {
529
+ const { protocols } = request.params;
530
+
531
+ if (protocols) {
532
+ // Fast lookup using index
533
+ const peerIds = this.findByProtocolIndex(protocols);
534
+ return peerIds.map(id => this.registry.get(id));
535
+ }
536
+
537
+ return super._tool_search(request);
538
+ }
539
+ }
73
540
  ```
74
541
 
75
- ### So how does this meet our goals?
542
+ ---
543
+
544
+ ## 6. Best Practices
76
545
 
77
- 1. Smaller model support → more relevant / clear context is now achieved
78
- 2. Reduce token usage → avoid sending irrelevant context when possible / refine tool offerings & also reduce model size requirements
79
- 3. More deterministic → by learning from past failures & successes, we know how to stay within the bounds of success with clear guardrails
80
- 4. Speed improvement → less tokens to process = more speed
546
+ ### Network Design Patterns
547
+
548
+ #### 1. Hierarchical Organization
549
+ Structure your network to mirror your business domains:
550
+ ```
551
+ o://leader # Root coordinator
552
+ └── o://company # Company root
553
+ ├── o://company/finance # Finance department
554
+ │ ├── o://company/finance/analyst
555
+ │ └── o://company/finance/reporting
556
+ └── o://company/engineering # Engineering department
557
+ ├── o://company/engineering/backend
558
+ └── o://company/engineering/frontend
559
+ ```
560
+
561
+ #### 2. Capability-Based Discovery
562
+ Register agents with clear, specific capabilities:
563
+ ```typescript
564
+ // Good: Specific capabilities
565
+ protocols: ['payment-processing', 'stripe-api', 'refund-handling']
566
+
567
+ // Avoid: Generic capabilities
568
+ protocols: ['payments', 'api', 'processing']
569
+ ```
570
+
571
+ #### 3. Static Addresses for Stability
572
+ Use static addresses for production agents that need stable references:
573
+ ```typescript
574
+ {
575
+ address: 'o://company/finance/analyst', // Dynamic
576
+ staticAddress: 'analyst-prod-01' // Stable reference
577
+ }
578
+ ```
579
+
580
+ ### Operational Guidelines
581
+
582
+ #### Registry Maintenance
583
+ - **TTL Strategy**: Implement time-to-live for registry entries to auto-cleanup stale agents
584
+ - **Health Checks**: Periodically verify registered agents are still responsive
585
+ - **Cleanup**: Remove inactive agents to keep registry performant
586
+
587
+ #### Network Indexing
588
+ - **Scheduled Indexing**: Run network indexing on a schedule (e.g., every 5 minutes)
589
+ - **Event-Driven**: Trigger indexing when significant network changes occur
590
+ - **Incremental**: For large networks, implement incremental indexing
591
+
592
+ #### Monitoring and Observability
593
+ ```typescript
594
+ // Log key network events
595
+ leader.on('agent:joined', (agent) => {
596
+ logger.info('Agent joined network', {
597
+ address: agent.address,
598
+ capabilities: agent.protocols,
599
+ timestamp: Date.now()
600
+ });
601
+ });
602
+
603
+ leader.on('agent:removed', (agent) => {
604
+ logger.info('Agent removed from network', {
605
+ address: agent.address,
606
+ timestamp: Date.now()
607
+ });
608
+ });
609
+
610
+ // Metrics collection
611
+ const metrics = {
612
+ totalAgents: await registry.count(),
613
+ joinRate: calculateJoinRate(),
614
+ searchLatency: measureSearchLatency(),
615
+ networkHealth: await leader.getNetworkHealth()
616
+ };
617
+ ```
618
+
619
+ ### Security Best Practices
620
+
621
+ 1. **Always validate join requests** with business logic
622
+ 2. **Use authentication tokens** for production networks
623
+ 3. **Implement rate limiting** on join requests
624
+ 4. **Filter registry results** based on caller permissions
625
+ 5. **Monitor for unusual patterns** (e.g., rapid joins, suspicious addresses)
626
+ 6. **Use encrypted transports** (prefer webrtc over websocket for sensitive data)
627
+
628
+ ---
629
+
630
+ ## 7. Troubleshooting
631
+
632
+ ### Common Issues
633
+
634
+ #### Agents Can't Join Network
635
+ **Symptoms**: Join requests fail or timeout
636
+ **Solutions**:
637
+ - Verify leader is running and accessible
638
+ - Check network connectivity between agent and leader
639
+ - Review `validateJoinRequest` logic for rejections
640
+ - Ensure parent address exists in hierarchy
641
+
642
+ #### Registry Search Returns No Results
643
+ **Symptoms**: Search returns empty array when agents should exist
644
+ **Solutions**:
645
+ - Verify agents committed to registry successfully
646
+ - Check search parameters match registered protocols/addresses
647
+ - Inspect registry state: `await registry.find_all()`
648
+ - Look for typos in protocol names or addresses
649
+
650
+ #### Network Indexing Fails
651
+ **Symptoms**: Index operation throws errors or never completes
652
+ **Solutions**:
653
+ - Check for agents that are unresponsive or disconnected
654
+ - Implement timeout logic for indexing individual agents
655
+ - Add error handling to continue indexing after failures
656
+ - Monitor agent count vs indexed count
657
+
658
+ #### Memory Issues with Large Networks
659
+ **Symptoms**: Registry memory grows unbounded
660
+ **Solutions**:
661
+ - Implement persistent registry instead of in-memory
662
+ - Add TTL for registry entries
663
+ - Implement cleanup for disconnected agents
664
+ - Consider registry sharding for very large networks
665
+
666
+ ### Debugging Tips
667
+
668
+ #### Enable Debug Logging
669
+ ```bash
670
+ DEBUG=o-protocol:*,o-leader:* node your-app.js
671
+ ```
672
+
673
+ #### Inspect Registry State
674
+ ```typescript
675
+ const allAgents = await leader.use(
676
+ new oAddress('o://registry'),
677
+ { method: 'find_all', params: {} }
678
+ );
679
+ console.log('Registry state:', JSON.stringify(allAgents, null, 2));
680
+ ```
681
+
682
+ #### Monitor Join Requests
683
+ ```typescript
684
+ class DebugLeader extends oLeaderNode {
685
+ async _tool_join_network(request: oRequest): Promise<any> {
686
+ console.log('Join request received:', {
687
+ caller: request.params.caller,
688
+ parent: request.params.parent,
689
+ transports: request.params.transports,
690
+ timestamp: Date.now()
691
+ });
692
+
693
+ try {
694
+ return await super._tool_join_network(request);
695
+ } catch (error) {
696
+ console.error('Join request failed:', error);
697
+ throw error;
698
+ }
699
+ }
700
+ }
701
+ ```
702
+
703
+ ---
704
+
705
+ ## 8. API Reference
706
+
707
+ ### oLeaderNode
708
+
709
+ #### Constructor
710
+ ```typescript
711
+ constructor(config: oNodeToolConfig)
712
+ ```
713
+
714
+ **Parameters:**
715
+ - `config.networkName` (string): Network identifier
716
+ - `config.address` (oAddress): Leader node address (default: `o://leader`)
717
+ - `config.type` (NodeType): Must be `NodeType.LEADER`
718
+ - `config.methods` (object): Custom methods to expose
719
+ - Other oNodeToolConfig parameters
720
+
721
+ #### Methods
722
+
723
+ ##### `validateJoinRequest(request: oRequest): Promise<boolean>`
724
+ Override to implement custom join validation logic.
725
+
726
+ **Parameters:**
727
+ - `request`: Join request containing caller, parent, transports
728
+
729
+ **Returns:** Promise resolving to `true` if valid, throws error if invalid
730
+
731
+ **Example:**
732
+ ```typescript
733
+ async validateJoinRequest(request: oRequest): Promise<boolean> {
734
+ if (!isAuthorized(request.params.caller)) {
735
+ throw new Error('Unauthorized');
736
+ }
737
+ return true;
738
+ }
739
+ ```
740
+
741
+ ##### `_tool_join_network(request: oRequest): Promise<any>`
742
+ Processes agent join requests.
743
+
744
+ **Request Parameters:**
745
+ - `caller` (string): Address of joining agent
746
+ - `parent` (string): Parent address in hierarchy
747
+ - `transports` (string[]): Available transport protocols
748
+
749
+ **Returns:** Success message
750
+
751
+ ##### `_tool_index_network(request: oRequest): Promise<any>`
752
+ Indexes all registered agents in the network.
753
+
754
+ **Returns:** Index completion status
755
+
756
+ ##### `_tool_save_plan(request: oRequest): Promise<any>`
757
+ Saves network coordination plans.
758
+
759
+ **Request Parameters:**
760
+ - `plan` (object): Plan to save
761
+
762
+ ---
763
+
764
+ ### RegistryTool
765
+
766
+ #### Abstract Methods
767
+
768
+ ##### `_tool_commit(request: oRequest): Promise<ToolResult>`
769
+ Register an agent in the registry.
770
+
771
+ **Request Parameters:**
772
+ - `peerId` (string, required): Agent's peer ID
773
+ - `address` (string): Agent's o:// address
774
+ - `staticAddress` (string): Stable reference address
775
+ - `protocols` (string[]): Capabilities/protocols
776
+ - `transports` (string[]): Transport protocols
777
+
778
+ **Returns:** Success indicator
779
+
780
+ ##### `_tool_search(request: oRequest): Promise<ToolResult>`
781
+ Search for agents matching criteria.
782
+
783
+ **Request Parameters:**
784
+ - `address` (string, optional): Search by address
785
+ - `staticAddress` (string, optional): Search by static address
786
+ - `protocols` (string[], optional): Search by protocols
787
+
788
+ **Returns:** Array of matching agents
789
+
790
+ ##### `_tool_find_all(request: oRequest): Promise<ToolResult>`
791
+ List all registered agents.
792
+
793
+ **Returns:** Array of all registered agents
794
+
795
+ ##### `_tool_remove(request: oRequest): Promise<ToolResult>`
796
+ Remove an agent from registry.
797
+
798
+ **Request Parameters:**
799
+ - `peerId` (string): Peer ID of agent to remove
800
+
801
+ **Returns:** Success indicator
802
+
803
+ ---
804
+
805
+ ### RegistryMemoryTool
806
+
807
+ Concrete implementation of RegistryTool using in-memory storage.
808
+
809
+ **Usage:**
810
+ ```typescript
811
+ const registry = new RegistryMemoryTool(config);
812
+ ```
813
+
814
+ **Storage:**
815
+ - Uses Map data structures for fast lookups
816
+ - Protocol indexing for efficient searches
817
+ - Not persistent across restarts
818
+
819
+ ---
820
+
821
+ ## 9. Examples
822
+
823
+ ### Example 1: Basic Multi-Agent Network
824
+ ```typescript
825
+ // examples/basic-network.ts
826
+ import { oLeaderNode, RegistryMemoryTool } from '@olane/o-leader';
827
+ import { oNode } from '@olane/o-node';
828
+ import { oAddress } from '@olane/o-core';
829
+
830
+ async function main() {
831
+ // 1. Start leader
832
+ const leader = new oLeaderNode({
833
+ networkName: 'my-agents',
834
+ });
835
+ await leader.start();
836
+
837
+ // 2. Create specialized agents
838
+ const analyst = new oNode({
839
+ address: 'o://agents/financial-analyst',
840
+ protocols: ['financial-analysis', 'report-generation']
841
+ });
842
+
843
+ const dataCollector = new oNode({
844
+ address: 'o://agents/data-collector',
845
+ protocols: ['data-fetching', 'api-integration']
846
+ });
847
+
848
+ // 3. Join agents to network
849
+ await analyst.use(oAddress.leader(), {
850
+ method: 'join_network',
851
+ params: {
852
+ caller: 'o://agents/financial-analyst',
853
+ parent: 'o://agents',
854
+ transports: ['webrtc']
855
+ }
856
+ });
857
+
858
+ await dataCollector.use(oAddress.leader(), {
859
+ method: 'join_network',
860
+ params: {
861
+ caller: 'o://agents/data-collector',
862
+ parent: 'o://agents',
863
+ transports: ['webrtc']
864
+ }
865
+ });
866
+
867
+ // 4. Use registry to find agents
868
+ const agents = await leader.use(new oAddress('o://registry'), {
869
+ method: 'find_all',
870
+ params: {}
871
+ });
872
+
873
+ console.log(`Network has ${agents.result.length} agents`);
874
+ }
875
+ ```
876
+
877
+ ### Example 2: Custom Validation
878
+ ```typescript
879
+ // examples/secure-network.ts
880
+ import { oLeaderNode } from '@olane/o-leader';
881
+ import { oRequest } from '@olane/o-core';
882
+
883
+ class SecureLeader extends oLeaderNode {
884
+ private authorizedDomains = ['o://company', 'o://partners'];
885
+
886
+ async validateJoinRequest(request: oRequest): Promise<boolean> {
887
+ const { caller, authToken } = request.params;
888
+
889
+ // Verify auth token
890
+ if (!this.verifyAuthToken(authToken)) {
891
+ throw new Error('Invalid authentication token');
892
+ }
893
+
894
+ // Check domain authorization
895
+ const isAuthorized = this.authorizedDomains.some(domain =>
896
+ caller.startsWith(domain)
897
+ );
898
+
899
+ if (!isAuthorized) {
900
+ throw new Error(`Domain not authorized: ${caller}`);
901
+ }
902
+
903
+ this.logger.info(`Agent ${caller} authorized to join`);
904
+ return true;
905
+ }
906
+
907
+ private verifyAuthToken(token: string): boolean {
908
+ // Your token verification logic
909
+ return token === 'valid-secret';
910
+ }
911
+ }
912
+
913
+ const leader = new SecureLeader({
914
+ networkName: 'secure-network'
915
+ });
916
+ await leader.start();
917
+ ```
918
+
919
+ ### Example 3: Capability Discovery
920
+ ```typescript
921
+ // examples/capability-discovery.ts
922
+ import { oAddress } from '@olane/o-core';
923
+
924
+ async function findAnalysisAgents(leader: oLeaderNode) {
925
+ // Search for agents with specific capabilities
926
+ const result = await leader.use(new oAddress('o://registry'), {
927
+ method: 'search',
928
+ params: {
929
+ protocols: ['financial-analysis', 'data-visualization']
930
+ }
931
+ });
932
+
933
+ const agents = result.result;
934
+ console.log(`Found ${agents.length} agents with analysis capabilities`);
935
+
936
+ // Connect to first available agent
937
+ if (agents.length > 0) {
938
+ const targetAgent = new oAddress(agents[0].address);
939
+ const analysis = await leader.use(targetAgent, {
940
+ method: 'analyze_portfolio',
941
+ params: { portfolio: 'tech-stocks' }
942
+ });
943
+
944
+ return analysis;
945
+ }
946
+ }
947
+ ```
948
+
949
+ ### Example 4: Network Health Dashboard
950
+ ```typescript
951
+ // examples/health-dashboard.ts
952
+ import { oLeaderNode, RegistryMemoryTool } from '@olane/o-leader';
953
+
954
+ class HealthMonitorLeader extends oLeaderNode {
955
+ async getNetworkDashboard() {
956
+ const allAgents = await this.use(
957
+ new oAddress('o://registry'),
958
+ { method: 'find_all', params: {} }
959
+ );
960
+
961
+ const dashboard = {
962
+ totalAgents: allAgents.result.length,
963
+ byCapability: this.groupByCapability(allAgents.result),
964
+ byDomain: this.groupByDomain(allAgents.result),
965
+ health: await this.checkAllAgentsHealth(allAgents.result)
966
+ };
967
+
968
+ return dashboard;
969
+ }
970
+
971
+ private groupByCapability(agents: any[]) {
972
+ const groups = new Map<string, number>();
973
+ agents.forEach(agent => {
974
+ agent.protocols.forEach(protocol => {
975
+ groups.set(protocol, (groups.get(protocol) || 0) + 1);
976
+ });
977
+ });
978
+ return Object.fromEntries(groups);
979
+ }
980
+
981
+ private groupByDomain(agents: any[]) {
982
+ const groups = new Map<string, number>();
983
+ agents.forEach(agent => {
984
+ const domain = agent.address.split('/').slice(0, 3).join('/');
985
+ groups.set(domain, (groups.get(domain) || 0) + 1);
986
+ });
987
+ return Object.fromEntries(groups);
988
+ }
989
+
990
+ private async checkAllAgentsHealth(agents: any[]) {
991
+ // Implementation for health checks
992
+ return { healthy: agents.length, unhealthy: 0 };
993
+ }
994
+ }
995
+ ```
996
+
997
+ ---
998
+
999
+ ## 10. Migration Guide
1000
+
1001
+ ### From Manual Coordination to o-leader
1002
+
1003
+ #### Before: Manual Agent Management
1004
+ ```typescript
1005
+ // Manually tracking agents
1006
+ const agents = {
1007
+ 'analyst-1': { address: '...', capabilities: [...] },
1008
+ 'collector-1': { address: '...', capabilities: [...] }
1009
+ };
1010
+
1011
+ // Manual discovery
1012
+ function findAgent(capability) {
1013
+ for (const [id, agent] of Object.entries(agents)) {
1014
+ if (agent.capabilities.includes(capability)) {
1015
+ return agent;
1016
+ }
1017
+ }
1018
+ }
1019
+ ```
1020
+
1021
+ #### After: With o-leader
1022
+ ```typescript
1023
+ // Automatic registration and discovery
1024
+ const leader = new oLeaderNode({ networkName: 'agents' });
1025
+
1026
+ // Agents self-register
1027
+ await agent.use(oAddress.leader(), {
1028
+ method: 'join_network',
1029
+ params: { caller: agent.address, parent, transports }
1030
+ });
1031
+
1032
+ // Automatic discovery via registry
1033
+ const agents = await leader.use(new oAddress('o://registry'), {
1034
+ method: 'search',
1035
+ params: { protocols: ['analysis'] }
1036
+ });
1037
+ ```
1038
+
1039
+ ### From Other Frameworks
1040
+
1041
+ #### From LangGraph
1042
+ LangGraph requires explicit graph definitions. With o-leader, agents discover each other:
1043
+
1044
+ ```typescript
1045
+ // LangGraph: Pre-defined graph
1046
+ const graph = new StateGraph({
1047
+ nodes: ['analyst', 'collector', 'reporter'],
1048
+ edges: [['analyst', 'reporter'], ['collector', 'reporter']]
1049
+ });
1050
+
1051
+ // o-leader: Emergent connections
1052
+ const leader = new oLeaderNode({ networkName: 'agents' });
1053
+ // Agents discover each other via registry
1054
+ // No pre-defined connections needed
1055
+ ```
1056
+
1057
+ #### From CrewAI
1058
+ CrewAI uses explicit crew definitions. o-leader enables dynamic crews:
1059
+
1060
+ ```typescript
1061
+ // CrewAI: Static crew
1062
+ const crew = new Crew({
1063
+ agents: [analyst, researcher, writer],
1064
+ tasks: [research_task, analysis_task, writing_task]
1065
+ });
1066
+
1067
+ // o-leader: Dynamic discovery
1068
+ const agents = await leader.use(new oAddress('o://registry'), {
1069
+ method: 'search',
1070
+ params: { protocols: ['research', 'analysis', 'writing'] }
1071
+ });
1072
+ // Agents can form dynamic collaborations
1073
+ ```
1074
+
1075
+ ---
1076
+
1077
+ ## 11. FAQ
1078
+
1079
+ ### General Questions
1080
+
1081
+ **Q: Do I need a leader node for every Olane OS network?**
1082
+ A: Yes, every network needs at least one leader node. It serves as the entry point and coordination hub.
1083
+
1084
+ **Q: Can I have multiple leader nodes?**
1085
+ A: Yes, for large or distributed networks, you can implement a federation pattern with regional leaders.
1086
+
1087
+ **Q: Is the registry required?**
1088
+ A: The registry is built into the leader node and is essential for agent discovery in the network.
1089
+
1090
+ **Q: What happens if the leader node goes down?**
1091
+ A: Existing agent connections remain active, but new agents cannot join. Implement leader failover for high availability.
1092
+
1093
+ ### Technical Questions
1094
+
1095
+ **Q: How does registry search performance scale?**
1096
+ A: In-memory registry is O(n) for searches. For large networks, implement indexed or database-backed registries.
1097
+
1098
+ **Q: Can I customize the registry implementation?**
1099
+ A: Yes, extend `RegistryTool` to implement custom storage backends (database, cache, etc.).
1100
+
1101
+ **Q: What transports does the leader support?**
1102
+ A: The leader supports all libp2p transports: WebRTC, WebSocket, TCP, QUIC, etc.
1103
+
1104
+ **Q: How do I handle registry cleanup?**
1105
+ A: Implement TTL logic in your registry and periodic cleanup of disconnected agents.
1106
+
1107
+ ### Operational Questions
1108
+
1109
+ **Q: How often should I run network indexing?**
1110
+ A: Depends on network dynamics. For stable networks, every 5-10 minutes. For dynamic networks, event-driven indexing.
1111
+
1112
+ **Q: What's the recommended registry backend for production?**
1113
+ A: For production, use a persistent registry (PostgreSQL, Redis, etc.) instead of in-memory.
1114
+
1115
+ **Q: How do I monitor leader health?**
1116
+ A: Implement health check endpoints and monitoring using your observability tools.
1117
+
1118
+ **Q: Can agents join from different networks?**
1119
+ A: Yes, as long as they can reach the leader node and pass validation.
1120
+
1121
+ ---
1122
+
1123
+ ## 12. Support and Resources
1124
+
1125
+ ### Documentation
1126
+ - [Olane OS Overview](/README.md)
1127
+ - [o-core Documentation](/packages/o-core/README.md)
1128
+ - [o-node Documentation](/packages/o-node/README.md)
1129
+ - [Agent Specialization Guide](/docs/specialization.md)
81
1130
 
82
1131
  ### Examples
1132
+ - [Basic Network Setup](/examples/basic-network)
1133
+ - [Secure Network](/examples/secure-network)
1134
+ - [Multi-Region Federation](/examples/multi-region)
1135
+ - [Health Monitoring](/examples/health-monitoring)
1136
+
1137
+ ### Community
1138
+ - GitHub Issues: [Report bugs or request features](https://github.com/olane-labs/olane/issues)
1139
+ - Discussions: [Ask questions and share ideas](https://github.com/olane-labs/olane/discussions)
1140
+ - Discord: [Join our community](https://discord.gg/olane)
1141
+
1142
+ ### Commercial Support
1143
+ For enterprise support, custom implementations, or consulting:
1144
+ - Email: support@olane.io
1145
+ - Website: https://olane.io/enterprise
1146
+
1147
+ ---
1148
+
1149
+ ## 13. Contributing
1150
+
1151
+ We welcome contributions! See [CONTRIBUTING.md](../../CONTRIBUTING.md) for guidelines.
1152
+
1153
+ ### Areas for Contribution
1154
+ - Registry backend implementations (PostgreSQL, Redis, MongoDB)
1155
+ - Performance optimizations
1156
+ - Security enhancements
1157
+ - Documentation improvements
1158
+ - Example projects
1159
+
1160
+ ---
1161
+
1162
+ ## License
83
1163
 
84
- 1. Github example what models can we test / prove to how it works?
85
- 2. Figma example → same as above ^^
86
- 3. Slack / more complex examples → same as above ^
1164
+ ISC License - see [LICENSE](../../LICENSE) for details.
@@ -1,10 +1,11 @@
1
1
  import { oRequest } from '@olane/o-core';
2
- import { oServerTool, oToolConfig } from '@olane/o-tool';
3
- export declare class oLeaderNode extends oServerTool {
4
- constructor(config: oToolConfig);
2
+ import { oLaneTool } from '@olane/o-lane';
3
+ import { oNodeToolConfig } from '@olane/o-node';
4
+ export declare class oLeaderNode extends oLaneTool {
5
+ constructor(config: oNodeToolConfig);
6
+ initialize(): Promise<void>;
5
7
  validateJoinRequest(request: oRequest): Promise<any>;
6
8
  _tool_join_network(request: oRequest): Promise<any>;
7
9
  _tool_save_plan(request: oRequest): Promise<any>;
8
- _tool_index_network(request: oRequest): Promise<any>;
9
10
  }
10
11
  //# sourceMappingURL=leader.node.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"leader.node.d.ts","sourceRoot":"","sources":["../../src/leader.node.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,QAAQ,EAET,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGzD,qBAAa,WAAY,SAAQ,WAAW;gBAC9B,MAAM,EAAE,WAAW;IAWzB,mBAAmB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAIpD,kBAAkB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAuBnD,eAAe,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAUhD,mBAAmB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CA2B3D"}
1
+ {"version":3,"file":"leader.node.d.ts","sourceRoot":"","sources":["../../src/leader.node.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,QAAQ,EAGT,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAe,eAAe,EAAmB,MAAM,eAAe,CAAC;AAG9E,qBAAa,WAAY,SAAQ,SAAS;gBAC5B,MAAM,EAAE,eAAe;IAW7B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B,mBAAmB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAIpD,kBAAkB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAuBnD,eAAe,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CA0CvD"}
@@ -1,17 +1,30 @@
1
- import { LEADER_ADRESS, NodeType, oAddress, } from '@olane/o-core';
2
- import { oServerTool } from '@olane/o-tool';
1
+ import { NodeType, oAddress, } from '@olane/o-core';
3
2
  import { START_METHOD } from './methods/start.method.js';
4
- export class oLeaderNode extends oServerTool {
3
+ import { oLaneTool } from '@olane/o-lane';
4
+ import { oSearchResolver } from '@olane/o-node';
5
+ import { RegistryMemoryTool } from './registry/registry-memory.tool.js';
6
+ export class oLeaderNode extends oLaneTool {
5
7
  constructor(config) {
6
8
  super({
7
9
  ...config,
8
- address: new oAddress(LEADER_ADRESS),
10
+ address: oAddress.leader(),
9
11
  type: NodeType.LEADER,
10
12
  methods: {
11
13
  start: START_METHOD,
12
14
  },
13
15
  });
14
16
  }
17
+ async initialize() {
18
+ await super.initialize();
19
+ this.router.addResolver(new oSearchResolver(this.address));
20
+ const registryTool = new RegistryMemoryTool({
21
+ name: 'registry',
22
+ parent: this.address,
23
+ leader: this.address,
24
+ });
25
+ await registryTool.start();
26
+ this.addChildNode(registryTool);
27
+ }
15
28
  async validateJoinRequest(request) {
16
29
  return true;
17
30
  }
@@ -36,28 +49,9 @@ export class oLeaderNode extends oServerTool {
36
49
  async _tool_save_plan(request) {
37
50
  const { plan } = request.params;
38
51
  this.logger.debug('Adding plan to network: ' + plan);
39
- if (!this.config.networkName) {
52
+ if (!this.config.systemName) {
40
53
  this.logger.warn('No network name provided, cannot update config');
41
54
  return;
42
55
  }
43
56
  }
44
- async _tool_index_network(request) {
45
- // paginate through all the registered nodes and index them
46
- const nodes = await this.use(new oAddress('o://leader/register'), {
47
- method: 'find_all',
48
- params: {},
49
- });
50
- const nodesArray = nodes.result.data;
51
- for (let i = 0; i < nodesArray.length; i++) {
52
- // first let's get the node's tools
53
- const node = nodesArray[i];
54
- const { result } = await this.use(new oAddress(node.address), {
55
- method: 'index_network',
56
- params: {},
57
- });
58
- }
59
- return {
60
- message: 'Network indexed!',
61
- };
62
- }
63
57
  }
@@ -1,10 +1,12 @@
1
- import { oToolConfig, oVirtualTool, ToolResult } from '@olane/o-tool';
1
+ import { ToolResult } from '@olane/o-tool';
2
2
  import { oRegistrationParams } from '@olane/o-protocol';
3
3
  import { oRequest } from '@olane/o-core';
4
- export declare abstract class RegistryTool extends oVirtualTool {
4
+ import { oLaneTool } from '@olane/o-lane';
5
+ import { oNodeToolConfig } from '@olane/o-node';
6
+ export declare abstract class RegistryTool extends oLaneTool {
5
7
  protected readonly registry: Map<string, oRegistrationParams>;
6
8
  protected readonly protocolMapping: Map<string, string[]>;
7
- constructor(config: oToolConfig);
9
+ constructor(config: oNodeToolConfig);
8
10
  abstract _tool_commit(request: oRequest): Promise<ToolResult>;
9
11
  abstract _tool_search(request: oRequest): Promise<ToolResult>;
10
12
  abstract _tool_find_all(request: oRequest): Promise<ToolResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.tool.d.ts","sourceRoot":"","sources":["../../../src/registry/registry.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAY,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGnD,8BAAsB,YAAa,SAAQ,YAAY;IACrD,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAa;IAC1E,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAa;gBAE1D,MAAM,EAAE,WAAW;IAS/B,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAC7D,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAC7D,QAAQ,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAC/D,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;CAC9D"}
1
+ {"version":3,"file":"registry.tool.d.ts","sourceRoot":"","sources":["../../../src/registry/registry.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAY,QAAQ,EAAuB,MAAM,eAAe,CAAC;AAExE,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAe,eAAe,EAAE,MAAM,eAAe,CAAC;AAE7D,8BAAsB,YAAa,SAAQ,SAAS;IAClD,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAa;IAC1E,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAa;gBAE1D,MAAM,EAAE,eAAe;IASnC,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAC7D,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAC7D,QAAQ,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAC/D,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;CAC9D"}
@@ -1,11 +1,11 @@
1
- import { oVirtualTool } from '@olane/o-tool';
2
- import { oAddress } from '@olane/o-core';
1
+ import { oAddress, RestrictedAddresses } from '@olane/o-core';
3
2
  import { REGISTRY_PARAMS } from './methods/registry.methods.js';
4
- export class RegistryTool extends oVirtualTool {
3
+ import { oLaneTool } from '@olane/o-lane';
4
+ export class RegistryTool extends oLaneTool {
5
5
  constructor(config) {
6
6
  super({
7
7
  ...config,
8
- address: new oAddress('o://register'),
8
+ address: new oAddress(RestrictedAddresses.REGISTRY),
9
9
  methods: REGISTRY_PARAMS,
10
10
  description: 'Network registry of tools and their respective addresses',
11
11
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olane/o-leader",
3
- "version": "0.6.13",
3
+ "version": "0.7.2",
4
4
  "type": "module",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -55,10 +55,11 @@
55
55
  "typescript": "5.4.5"
56
56
  },
57
57
  "peerDependencies": {
58
- "@olane/o-config": "^0.6.12",
59
- "@olane/o-core": "^0.6.12",
60
- "@olane/o-protocol": "^0.6.12",
61
- "@olane/o-tool": "^0.6.12"
58
+ "@olane/o-config": "^0.7.1",
59
+ "@olane/o-core": "^0.7.1",
60
+ "@olane/o-lane": "^0.7.1",
61
+ "@olane/o-protocol": "^0.7.1",
62
+ "@olane/o-tool": "^0.7.1"
62
63
  },
63
64
  "dependencies": {
64
65
  "debug": "^4.4.1",