@olane/o-node 0.8.2 → 0.8.4
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 +140 -21
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -81,7 +81,7 @@ The production distribution layer of Olane OS - build tool nodes that AI agents
|
|
|
81
81
|
## Installation
|
|
82
82
|
|
|
83
83
|
```bash
|
|
84
|
-
|
|
84
|
+
pnpm install @olane/o-node @olane/o-core @olane/o-protocol @olane/o-config @olane/o-tool
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
## Quick Start
|
|
@@ -141,8 +141,14 @@ const response = await toolNode.use(
|
|
|
141
141
|
{ method: 'greet', params: { name: 'World' } }
|
|
142
142
|
);
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
//
|
|
144
|
+
// Responses are wrapped in a standard structure:
|
|
145
|
+
// response.result.success - boolean indicating success/failure
|
|
146
|
+
// response.result.data - the raw data returned by the tool method
|
|
147
|
+
// response.result.error - error message if success is false
|
|
148
|
+
if (response.result.success) {
|
|
149
|
+
console.log(response.result.data);
|
|
150
|
+
// { message: "Hello, World! I'm a tool node that AI agents can use.", peerId: "..." }
|
|
151
|
+
}
|
|
146
152
|
|
|
147
153
|
await toolNode.stop();
|
|
148
154
|
```
|
|
@@ -581,6 +587,118 @@ const response = await agent1.use(agent2.address, {
|
|
|
581
587
|
|
|
582
588
|
## API Reference
|
|
583
589
|
|
|
590
|
+
### Class Hierarchy
|
|
591
|
+
|
|
592
|
+
The o-node package provides several classes that build on each other through both inheritance and composition (mixins):
|
|
593
|
+
|
|
594
|
+
```
|
|
595
|
+
oCore (from @olane/o-core)
|
|
596
|
+
└─ oToolBase (from @olane/o-tool) [inheritance]
|
|
597
|
+
└─ oNode [inheritance]
|
|
598
|
+
└─ oServerNode [inheritance]
|
|
599
|
+
└─ oNodeTool [composition via oTool mixin]
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
`oNodeTool` is the **recommended base class** for building tool nodes. It applies the `oTool` mixin to `oServerNode`, which adds protocol handling, tool method discovery (methods prefixed with `_tool_`), and the standard request/response pipeline. Use `oServerNode` directly only when you need low-level networking without the tool layer.
|
|
603
|
+
|
|
604
|
+
### oNodeTool Class
|
|
605
|
+
|
|
606
|
+
The primary base class for building tool nodes. Created by applying the `oTool` mixin to `oServerNode`, which adds protocol handling, `_tool_` method discovery, and the standard response wrapping pipeline.
|
|
607
|
+
|
|
608
|
+
**Import:**
|
|
609
|
+
```typescript
|
|
610
|
+
import { oNodeTool, oNodeAddress } from '@olane/o-node';
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
**Usage:**
|
|
614
|
+
```typescript
|
|
615
|
+
import { oNodeTool, oNodeAddress } from '@olane/o-node';
|
|
616
|
+
import { oRequest } from '@olane/o-core';
|
|
617
|
+
|
|
618
|
+
class MyTool extends oNodeTool {
|
|
619
|
+
constructor(config: any) {
|
|
620
|
+
super({
|
|
621
|
+
...config,
|
|
622
|
+
address: new oNodeAddress('o://my-tool'),
|
|
623
|
+
description: 'A tool node for AI agents',
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// Initialize external services in this hook (not in start())
|
|
628
|
+
async hookInitializeFinished(): Promise<void> {
|
|
629
|
+
// Set up API clients, load resources, etc.
|
|
630
|
+
await super.hookInitializeFinished();
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// Start background tasks in this hook
|
|
634
|
+
async hookStartFinished(): Promise<void> {
|
|
635
|
+
// Start monitoring, spawn children, etc.
|
|
636
|
+
await super.hookStartFinished();
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// Methods prefixed with _tool_ are automatically discovered
|
|
640
|
+
async _tool_greet(request: oRequest): Promise<any> {
|
|
641
|
+
const { name } = request.params;
|
|
642
|
+
if (!name) {
|
|
643
|
+
throw new Error('name is required');
|
|
644
|
+
}
|
|
645
|
+
// Return raw data - base class wraps it automatically
|
|
646
|
+
return { message: `Hello, ${name}!` };
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// Cleanup resources
|
|
650
|
+
async stop(): Promise<void> {
|
|
651
|
+
// Disconnect clients, clear timers, etc.
|
|
652
|
+
await super.stop();
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
**Configuration** (`oNodeToolConfig`):
|
|
658
|
+
|
|
659
|
+
Extends `oNodeConfig` (with `address` optional, since it can be set in the constructor):
|
|
660
|
+
|
|
661
|
+
```typescript
|
|
662
|
+
interface oNodeToolConfig extends Omit<oNodeConfig, 'address'> {}
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
See `oNodeConfig` below for the full set of configuration options.
|
|
666
|
+
|
|
667
|
+
**Lifecycle Hooks:**
|
|
668
|
+
|
|
669
|
+
| Hook | When | Use For |
|
|
670
|
+
|------|------|---------|
|
|
671
|
+
| `hookInitializeFinished()` | After `initialize()`, before `register()` | Initialize 3rd party services |
|
|
672
|
+
| `hookStartFinished()` | After `register()`, fully started | Start background tasks, create children |
|
|
673
|
+
| `stop()` | When stopping | Cleanup resources, disconnect services |
|
|
674
|
+
|
|
675
|
+
> **Important**: Never override `start()`. It orchestrates the entire lifecycle. Use `hookInitializeFinished()` and `hookStartFinished()` instead.
|
|
676
|
+
|
|
677
|
+
**Response Structure:**
|
|
678
|
+
|
|
679
|
+
When calling tool methods via `node.use()`, responses follow the standard Olane response structure:
|
|
680
|
+
|
|
681
|
+
```typescript
|
|
682
|
+
const response = await node.use(
|
|
683
|
+
new oNodeAddress('o://some-tool'),
|
|
684
|
+
{ method: 'some_method', params: { ... } }
|
|
685
|
+
);
|
|
686
|
+
|
|
687
|
+
// response.result.success - boolean indicating success or failure
|
|
688
|
+
// response.result.data - the return value on success
|
|
689
|
+
// response.result.error - error message on failure
|
|
690
|
+
|
|
691
|
+
if (response.result.success) {
|
|
692
|
+
const data = response.result.data;
|
|
693
|
+
} else {
|
|
694
|
+
console.error('Error:', response.result.error);
|
|
695
|
+
}
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
> **Important**: Never access `response.success` or `response.data` directly. Always use `response.result.success` and `response.result.data`.
|
|
699
|
+
|
|
700
|
+
---
|
|
701
|
+
|
|
584
702
|
### oNode Class
|
|
585
703
|
|
|
586
704
|
Extends `oToolBase` from `@olane/o-tool`, which extends `oCore` from `@olane/o-core`.
|
|
@@ -852,39 +970,40 @@ describe('Agent Communication', () => {
|
|
|
852
970
|
```typescript
|
|
853
971
|
class MonitoredNode extends oServerNode {
|
|
854
972
|
private healthCheckInterval?: NodeJS.Timeout;
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
// Start health monitoring
|
|
973
|
+
|
|
974
|
+
// Use hookStartFinished() instead of overriding start()
|
|
975
|
+
async hookStartFinished(): Promise<void> {
|
|
976
|
+
// Start health monitoring after the node is fully started
|
|
860
977
|
this.healthCheckInterval = setInterval(() => {
|
|
861
978
|
const connections = this.p2pNode.getConnections();
|
|
862
979
|
const peers = this.p2pNode.getPeers();
|
|
863
|
-
|
|
980
|
+
|
|
864
981
|
console.log('Health Check:', {
|
|
865
982
|
connections: connections.length,
|
|
866
983
|
peers: peers.length,
|
|
867
984
|
protocols: this.p2pNode.getProtocols()
|
|
868
985
|
});
|
|
869
|
-
|
|
986
|
+
|
|
870
987
|
// Alert if disconnected
|
|
871
988
|
if (connections.length === 0 && this.leader) {
|
|
872
989
|
console.warn('No active connections! Attempting reconnect...');
|
|
873
990
|
this.reconnectToLeader();
|
|
874
991
|
}
|
|
875
992
|
}, 30000); // Every 30 seconds
|
|
993
|
+
|
|
994
|
+
await super.hookStartFinished();
|
|
876
995
|
}
|
|
877
|
-
|
|
996
|
+
|
|
878
997
|
async stop(): Promise<void> {
|
|
879
998
|
if (this.healthCheckInterval) {
|
|
880
999
|
clearInterval(this.healthCheckInterval);
|
|
881
1000
|
}
|
|
882
1001
|
await super.stop();
|
|
883
1002
|
}
|
|
884
|
-
|
|
1003
|
+
|
|
885
1004
|
private async reconnectToLeader(): Promise<void> {
|
|
886
1005
|
if (!this.leader) return;
|
|
887
|
-
|
|
1006
|
+
|
|
888
1007
|
try {
|
|
889
1008
|
await this.register();
|
|
890
1009
|
console.log('Reconnected to leader');
|
|
@@ -961,32 +1080,32 @@ const agent = new oServerNode({
|
|
|
961
1080
|
|
|
962
1081
|
```bash
|
|
963
1082
|
# Run tests
|
|
964
|
-
|
|
1083
|
+
pnpm test
|
|
965
1084
|
|
|
966
1085
|
# Run tests in Node.js
|
|
967
|
-
|
|
1086
|
+
pnpm run test:node
|
|
968
1087
|
|
|
969
1088
|
# Run tests in browser
|
|
970
|
-
|
|
1089
|
+
pnpm run test:browser
|
|
971
1090
|
```
|
|
972
1091
|
|
|
973
1092
|
## Development
|
|
974
1093
|
|
|
975
1094
|
```bash
|
|
976
1095
|
# Install dependencies
|
|
977
|
-
|
|
1096
|
+
pnpm install
|
|
978
1097
|
|
|
979
1098
|
# Build the package
|
|
980
|
-
|
|
1099
|
+
pnpm run build
|
|
981
1100
|
|
|
982
1101
|
# Run in development mode with debug output
|
|
983
|
-
|
|
1102
|
+
pnpm run dev
|
|
984
1103
|
|
|
985
1104
|
# Update o-core dependency
|
|
986
|
-
|
|
1105
|
+
pnpm run update:lib
|
|
987
1106
|
|
|
988
1107
|
# Lint the code
|
|
989
|
-
|
|
1108
|
+
pnpm run lint
|
|
990
1109
|
```
|
|
991
1110
|
|
|
992
1111
|
## Related Packages
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olane/o-node",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@eslint/eslintrc": "^3.3.1",
|
|
42
42
|
"@eslint/js": "^9.29.0",
|
|
43
|
-
"@olane/o-test": "0.8.
|
|
43
|
+
"@olane/o-test": "0.8.4",
|
|
44
44
|
"@tsconfig/node20": "^20.1.6",
|
|
45
45
|
"@types/jest": "^30.0.0",
|
|
46
46
|
"@types/json5": "^2.2.0",
|
|
@@ -60,13 +60,13 @@
|
|
|
60
60
|
"typescript": "5.4.5"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@olane/o-config": "0.8.
|
|
64
|
-
"@olane/o-core": "0.8.
|
|
65
|
-
"@olane/o-protocol": "0.8.
|
|
66
|
-
"@olane/o-tool": "0.8.
|
|
63
|
+
"@olane/o-config": "0.8.4",
|
|
64
|
+
"@olane/o-core": "0.8.4",
|
|
65
|
+
"@olane/o-protocol": "0.8.4",
|
|
66
|
+
"@olane/o-tool": "0.8.4",
|
|
67
67
|
"debug": "^4.4.1",
|
|
68
68
|
"dotenv": "^16.5.0",
|
|
69
69
|
"json5": "^2.2.3"
|
|
70
70
|
},
|
|
71
|
-
"gitHead": "
|
|
71
|
+
"gitHead": "b53623b1ad4365133911722f80d5597a72b65bf2"
|
|
72
72
|
}
|