@olane/o-tools-common 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.
Files changed (2) hide show
  1. package/README.md +173 -103
  2. package/package.json +10 -10
package/README.md CHANGED
@@ -4,13 +4,13 @@
4
4
 
5
5
  Common tool collection for Olane OS nodes - provides essential capabilities like encryption, search, and storage that most nodes need.
6
6
 
7
- **TL;DR**: Pre-built tools for encryption, search, and storage that you can add to any node with one function call.
7
+ **TL;DR**: Pre-built tools for storage, encryption, search, and approval that you can add to any node with one function call.
8
8
 
9
9
  ## Quick Start
10
10
 
11
11
  ```bash
12
12
  # Install the package
13
- npm install @olane/o-tools-common
13
+ pnpm install @olane/o-tools-common
14
14
  ```
15
15
 
16
16
  ```typescript
@@ -19,13 +19,12 @@ import { oLaneTool } from '@olane/o-lane';
19
19
  import { initCommonTools } from '@olane/o-tools-common';
20
20
 
21
21
  class MyNode extends oLaneTool {
22
- async start() {
23
- await super.start();
24
-
22
+ async hookStartFinished(): Promise<void> {
25
23
  // Initialize all common tools
26
24
  await initCommonTools(this);
27
-
25
+
28
26
  // Now you can use encryption, search, and storage tools
27
+ await super.hookStartFinished();
29
28
  }
30
29
  }
31
30
  ```
@@ -34,16 +33,18 @@ class MyNode extends oLaneTool {
34
33
 
35
34
  `o-tools-common` is a collection of reusable tools that solve common needs across Olane nodes:
36
35
 
36
+ - **Storage**: Persistent data storage (via `@olane/o-storage`)
37
+ - **OS Config Storage**: OS-level configuration storage
37
38
  - **Encryption**: Secure data encryption/decryption using AES-256-GCM
38
39
  - **Search**: Network-wide vector search capabilities
39
- - **Storage**: Persistent data storage (via `@olane/o-storage`)
40
+ - **Approval**: Human-in-the-loop approval system (via `@olane/o-approval`)
40
41
 
41
42
  Instead of implementing these capabilities in every node, import this package and get them instantly.
42
43
 
43
44
  ## Installation {#installation}
44
45
 
45
46
  ```bash
46
- npm install @olane/o-tools-common
47
+ pnpm install @olane/o-tools-common
47
48
  ```
48
49
 
49
50
  **Peer Dependencies:**
@@ -90,15 +91,17 @@ Encrypts plaintext to base64-encoded encrypted string.
90
91
 
91
92
  ```typescript
92
93
  // Encrypt sensitive data
93
- const result = await node.use(new oAddress('o://encryption'), {
94
+ const response = await node.use(new oNodeAddress('o://encryption'), {
94
95
  method: 'encrypt',
95
96
  params: {
96
97
  value: 'my-secret-password'
97
98
  }
98
99
  });
99
100
 
100
- console.log(result.value);
101
- // Output: "eyJlbmNyeXB0ZWRUZXh0Ij..."
101
+ if (response.result.success) {
102
+ console.log(response.result.data.value);
103
+ // Output: "eyJlbmNyeXB0ZWRUZXh0Ij..."
104
+ }
102
105
  ```
103
106
 
104
107
  ##### `_tool_decrypt(request)`
@@ -119,15 +122,17 @@ Decrypts base64-encoded encrypted string back to plaintext.
119
122
 
120
123
  ```typescript
121
124
  // Decrypt encrypted data
122
- const result = await node.use(new oAddress('o://encryption'), {
125
+ const response = await node.use(new oNodeAddress('o://encryption'), {
123
126
  method: 'decrypt',
124
127
  params: {
125
128
  value: 'eyJlbmNyeXB0ZWRUZXh0Ij...'
126
129
  }
127
130
  });
128
131
 
129
- console.log(result.value);
130
- // Output: "my-secret-password"
132
+ if (response.result.success) {
133
+ console.log(response.result.data.value);
134
+ // Output: "my-secret-password"
135
+ }
131
136
  ```
132
137
 
133
138
  #### Configuration
@@ -179,7 +184,7 @@ Array<{
179
184
 
180
185
  ```typescript
181
186
  // Search for documents about financial analysis
182
- const results = await node.use(new oAddress('o://search'), {
187
+ const response = await node.use(new oNodeAddress('o://search'), {
183
188
  method: 'vector',
184
189
  params: {
185
190
  query: 'financial analysis and revenue forecasting',
@@ -187,8 +192,10 @@ const results = await node.use(new oAddress('o://search'), {
187
192
  }
188
193
  });
189
194
 
190
- console.log(results);
191
- // Returns 5 most similar documents
195
+ if (response.result.success) {
196
+ console.log(response.result.data);
197
+ // Returns 5 most similar documents
198
+ }
192
199
  ```
193
200
 
194
201
  <Note>
@@ -205,6 +212,29 @@ Provides persistent data storage capabilities. This tool is imported from `@olan
205
212
 
206
213
  See [@olane/o-storage documentation](/packages/o-storage) for complete API reference.
207
214
 
215
+ ## Response Structure {#response-structure}
216
+
217
+ When calling common tools via `node.use()`, responses follow the standard Olane response structure:
218
+
219
+ ```typescript
220
+ const response = await this.use(
221
+ new oNodeAddress('o://encryption'),
222
+ { method: 'encrypt', params: { value: 'secret' } }
223
+ );
224
+
225
+ // response.result.success - boolean indicating success or failure
226
+ // response.result.data - the return value on success
227
+ // response.result.error - error message on failure
228
+
229
+ if (response.result.success) {
230
+ const encrypted = response.result.data.value;
231
+ } else {
232
+ console.error('Failed:', response.result.error);
233
+ }
234
+ ```
235
+
236
+ > **Important**: Never access `response.success` or `response.data` directly. Always use `response.result.success` and `response.result.data`.
237
+
208
238
  ## Usage Guide {#usage-guide}
209
239
 
210
240
  ### Basic Setup
@@ -213,44 +243,47 @@ Add common tools to any `oLaneTool` node:
213
243
 
214
244
  ```typescript
215
245
  import { oLaneTool } from '@olane/o-lane';
216
- import { oAddress } from '@olane/o-core';
246
+ import { oNodeAddress } from '@olane/o-node';
217
247
  import { initCommonTools } from '@olane/o-tools-common';
218
248
 
219
249
  class FinancialAnalystNode extends oLaneTool {
220
250
  constructor() {
221
251
  super({
222
- address: new oAddress('o://company/finance/analyst'),
252
+ address: new oNodeAddress('o://company/finance/analyst'),
223
253
  laneContext: {
224
254
  domain: 'Financial Analysis'
225
255
  }
226
256
  });
227
257
  }
228
258
 
229
- async start() {
230
- await super.start();
231
-
259
+ async hookStartFinished(): Promise<void> {
232
260
  // Add all common tools
233
261
  await initCommonTools(this);
234
-
262
+
235
263
  this.logger.info('Common tools initialized');
264
+ await super.hookStartFinished();
236
265
  }
237
266
 
238
267
  // Now you can use common tools in your methods
239
268
  async _tool_save_report(request: oRequest) {
240
269
  const { reportData } = request.params;
241
-
270
+
242
271
  // Use encryption tool
243
- const encrypted = await this.use(
244
- new oAddress('o://encryption'),
272
+ const encryptResponse = await this.use(
273
+ new oNodeAddress('o://encryption'),
245
274
  { method: 'encrypt', params: { value: reportData } }
246
275
  );
247
-
276
+
277
+ if (!encryptResponse.result.success) {
278
+ throw new Error(`Encryption failed: ${encryptResponse.result.error}`);
279
+ }
280
+
248
281
  // Use storage tool
249
282
  await this.use(
250
- new oAddress('o://storage'),
251
- { method: 'set', params: { key: 'report', value: encrypted.value } }
283
+ new oNodeAddress('o://storage'),
284
+ { method: 'put', params: { key: 'report', value: encryptResponse.result.data.value } }
252
285
  );
253
-
286
+
254
287
  return { saved: true };
255
288
  }
256
289
  }
@@ -265,18 +298,17 @@ import { EncryptionTool } from '@olane/o-tools-common';
265
298
  import { oLaneTool } from '@olane/o-lane';
266
299
 
267
300
  class MyNode extends oLaneTool {
268
- async start() {
269
- await super.start();
270
-
301
+ async hookStartFinished(): Promise<void> {
271
302
  // Only add encryption tool
272
303
  const encryptionTool = new EncryptionTool({
273
304
  name: 'encryption',
274
305
  parent: this.address,
275
306
  leader: this.leader
276
307
  });
277
-
308
+
278
309
  await encryptionTool.start();
279
310
  this.addChildNode(encryptionTool as any);
311
+ await super.hookStartFinished();
280
312
  }
281
313
  }
282
314
  ```
@@ -289,44 +321,56 @@ class MyNode extends oLaneTool {
289
321
  class AuthNode extends oLaneTool {
290
322
  async _tool_store_credentials(request: oRequest) {
291
323
  const { username, password } = request.params;
292
-
324
+
293
325
  // Encrypt password before storing
294
326
  const encrypted = await this.use(
295
- new oAddress('o://encryption'),
327
+ new oNodeAddress('o://encryption'),
296
328
  { method: 'encrypt', params: { value: password } }
297
329
  );
298
-
330
+
331
+ if (!encrypted.result.success) {
332
+ throw new Error(`Encryption failed: ${encrypted.result.error}`);
333
+ }
334
+
299
335
  // Store encrypted password
300
336
  await this.use(
301
- new oAddress('o://storage'),
302
- {
303
- method: 'set',
304
- params: {
305
- key: `user:${username}:password`,
306
- value: encrypted.value
307
- }
337
+ new oNodeAddress('o://storage'),
338
+ {
339
+ method: 'put',
340
+ params: {
341
+ key: `user:${username}:password`,
342
+ value: encrypted.result.data.value
343
+ }
308
344
  }
309
345
  );
310
-
311
- return { success: true };
346
+
347
+ return { stored: true };
312
348
  }
313
349
 
314
350
  async _tool_verify_credentials(request: oRequest) {
315
351
  const { username, password } = request.params;
316
-
352
+
317
353
  // Retrieve encrypted password
318
354
  const stored = await this.use(
319
- new oAddress('o://storage'),
355
+ new oNodeAddress('o://storage'),
320
356
  { method: 'get', params: { key: `user:${username}:password` } }
321
357
  );
322
-
358
+
359
+ if (!stored.result.success) {
360
+ throw new Error(`Storage retrieval failed: ${stored.result.error}`);
361
+ }
362
+
323
363
  // Decrypt and compare
324
364
  const decrypted = await this.use(
325
- new oAddress('o://encryption'),
326
- { method: 'decrypt', params: { value: stored.value } }
365
+ new oNodeAddress('o://encryption'),
366
+ { method: 'decrypt', params: { value: stored.result.data.value } }
327
367
  );
328
-
329
- return { valid: decrypted.value === password };
368
+
369
+ if (!decrypted.result.success) {
370
+ throw new Error(`Decryption failed: ${decrypted.result.error}`);
371
+ }
372
+
373
+ return { valid: decrypted.result.data.value === password };
330
374
  }
331
375
  }
332
376
  ```
@@ -337,34 +381,38 @@ class AuthNode extends oLaneTool {
337
381
  class DocumentAnalystNode extends oLaneTool {
338
382
  async _tool_analyze_with_context(request: oRequest) {
339
383
  const { query } = request.params;
340
-
384
+
341
385
  // Search for relevant documents
342
- const context = await this.use(
343
- new oAddress('o://search'),
344
- {
345
- method: 'vector',
346
- params: {
386
+ const searchResponse = await this.use(
387
+ new oNodeAddress('o://search'),
388
+ {
389
+ method: 'vector',
390
+ params: {
347
391
  query: query,
348
- limit: 5
349
- }
392
+ limit: 5
393
+ }
350
394
  }
351
395
  );
352
-
396
+
397
+ if (!searchResponse.result.success) {
398
+ throw new Error(`Search failed: ${searchResponse.result.error}`);
399
+ }
400
+
353
401
  // Use context to generate analysis
354
- const analysis = this.analyzeWithContext(query, context);
355
-
402
+ const analysis = this.analyzeWithContext(query, searchResponse.result.data);
403
+
356
404
  // Store analysis result
357
405
  await this.use(
358
- new oAddress('o://storage'),
359
- {
360
- method: 'set',
361
- params: {
362
- key: `analysis:${Date.now()}`,
363
- value: JSON.stringify(analysis)
364
- }
406
+ new oNodeAddress('o://storage'),
407
+ {
408
+ method: 'put',
409
+ params: {
410
+ key: `analysis:${Date.now()}`,
411
+ value: JSON.stringify(analysis)
412
+ }
365
413
  }
366
414
  );
367
-
415
+
368
416
  return analysis;
369
417
  }
370
418
  }
@@ -376,42 +424,54 @@ class DocumentAnalystNode extends oLaneTool {
376
424
  class IntegrationNode extends oLaneTool {
377
425
  async _tool_store_api_key(request: oRequest) {
378
426
  const { service, apiKey } = request.params;
379
-
427
+
380
428
  // Encrypt API key
381
429
  const encrypted = await this.use(
382
- new oAddress('o://encryption'),
430
+ new oNodeAddress('o://encryption'),
383
431
  { method: 'encrypt', params: { value: apiKey } }
384
432
  );
385
-
433
+
434
+ if (!encrypted.result.success) {
435
+ throw new Error(`Encryption failed: ${encrypted.result.error}`);
436
+ }
437
+
386
438
  // Store encrypted key
387
439
  await this.use(
388
- new oAddress('o://storage'),
389
- {
390
- method: 'set',
391
- params: {
392
- key: `api-keys:${service}`,
393
- value: encrypted.value
394
- }
440
+ new oNodeAddress('o://storage'),
441
+ {
442
+ method: 'put',
443
+ params: {
444
+ key: `api-keys:${service}`,
445
+ value: encrypted.result.data.value
446
+ }
395
447
  }
396
448
  );
397
-
449
+
398
450
  return { stored: true };
399
451
  }
400
452
 
401
453
  private async getApiKey(service: string): Promise<string> {
402
454
  // Retrieve encrypted key
403
455
  const stored = await this.use(
404
- new oAddress('o://storage'),
456
+ new oNodeAddress('o://storage'),
405
457
  { method: 'get', params: { key: `api-keys:${service}` } }
406
458
  );
407
-
459
+
460
+ if (!stored.result.success) {
461
+ throw new Error(`Storage retrieval failed: ${stored.result.error}`);
462
+ }
463
+
408
464
  // Decrypt and return
409
465
  const decrypted = await this.use(
410
- new oAddress('o://encryption'),
411
- { method: 'decrypt', params: { value: stored.value } }
466
+ new oNodeAddress('o://encryption'),
467
+ { method: 'decrypt', params: { value: stored.result.data.value } }
412
468
  );
413
-
414
- return decrypted.value;
469
+
470
+ if (!decrypted.result.success) {
471
+ throw new Error(`Decryption failed: ${decrypted.result.error}`);
472
+ }
473
+
474
+ return decrypted.result.data.value;
415
475
  }
416
476
  }
417
477
  ```
@@ -428,6 +488,13 @@ Initializes all common tools as child nodes of the provided parent node.
428
488
  **Returns:**
429
489
  - `Promise<Tool[]>`: Array of initialized tool instances
430
490
 
491
+ **Initialized tools (5 total):**
492
+ 1. `StorageTool` - Persistent data storage (`o://storage`)
493
+ 2. `OSConfigStorageTool` - OS-level configuration storage (`o://os-config-storage`)
494
+ 3. `EncryptionTool` - AES-256-GCM encryption/decryption (`o://encryption`)
495
+ 4. `SearchTool` - Network-wide vector search (`o://search`)
496
+ 5. `oApprovalTool` - Human-in-the-loop approval system (`o://approval`)
497
+
431
498
  **Example:**
432
499
 
433
500
  ```typescript
@@ -435,15 +502,16 @@ import { initCommonTools } from '@olane/o-tools-common';
435
502
  import { oLaneTool } from '@olane/o-lane';
436
503
 
437
504
  class MyNode extends oLaneTool {
438
- async start() {
439
- await super.start();
440
-
505
+ async hookStartFinished(): Promise<void> {
441
506
  const tools = await initCommonTools(this);
442
507
  // tools[0] = StorageTool
443
- // tools[1] = EncryptionTool
444
- // tools[2] = SearchTool
445
-
508
+ // tools[1] = OSConfigStorageTool
509
+ // tools[2] = EncryptionTool
510
+ // tools[3] = SearchTool
511
+ // tools[4] = oApprovalTool
512
+
446
513
  console.log(`Initialized ${tools.length} common tools`);
514
+ await super.hookStartFinished();
447
515
  }
448
516
  }
449
517
  ```
@@ -461,9 +529,9 @@ new EncryptionTool(config: oNodeToolConfig)
461
529
  **Config:**
462
530
  ```typescript
463
531
  {
464
- name: string, // Tool name
465
- parent: oAddress, // Parent node address
466
- leader: LeaderClient // Leader client instance
532
+ name: string, // Tool name
533
+ parent: oNodeAddress, // Parent node address
534
+ leader: LeaderClient // Leader client instance
467
535
  }
468
536
  ```
469
537
 
@@ -480,9 +548,9 @@ new SearchTool(config: oNodeToolConfig)
480
548
  **Config:**
481
549
  ```typescript
482
550
  {
483
- name: string, // Tool name
484
- parent: oAddress, // Parent node address
485
- leader: LeaderClient // Leader client instance
551
+ name: string, // Tool name
552
+ parent: oNodeAddress, // Parent node address
553
+ leader: LeaderClient // Leader client instance
486
554
  }
487
555
  ```
488
556
 
@@ -555,7 +623,7 @@ const storageTools = [
555
623
  **Solution:**
556
624
  ```bash
557
625
  # Install all peer dependencies
558
- npm install @olane/o-core@latest @olane/o-config@latest \
626
+ pnpm add @olane/o-core@latest @olane/o-config@latest \
559
627
  @olane/o-protocol@latest @olane/o-tool@latest \
560
628
  @olane/o-lane@latest @olane/o-leader@latest \
561
629
  @olane/o-storage@latest
@@ -590,9 +658,11 @@ Common tools are implemented as **child nodes** of your main node:
590
658
  │ ┌───────────────────────────────────┐ │
591
659
  │ │ Child Nodes (Common Tools) │ │
592
660
  │ │ │ │
661
+ │ │ o://storage │ │
662
+ │ │ o://os-config-storage │ │
593
663
  │ │ o://encryption │ │
594
664
  │ │ o://search │ │
595
- │ │ o://storage │ │
665
+ │ │ o://approval │ │
596
666
  │ └───────────────────────────────────┘ │
597
667
  └─────────────────────────────────────────┘
598
668
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olane/o-tools-common",
3
- "version": "0.8.2",
3
+ "version": "0.8.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -52,16 +52,16 @@
52
52
  "typescript": "5.4.5"
53
53
  },
54
54
  "dependencies": {
55
- "@olane/o-approval": "0.8.2",
56
- "@olane/o-config": "0.8.2",
57
- "@olane/o-core": "0.8.2",
58
- "@olane/o-lane": "0.8.2",
59
- "@olane/o-leader": "0.8.2",
60
- "@olane/o-protocol": "0.8.2",
61
- "@olane/o-storage": "0.8.2",
62
- "@olane/o-tool": "0.8.2",
55
+ "@olane/o-approval": "0.8.4",
56
+ "@olane/o-config": "0.8.4",
57
+ "@olane/o-core": "0.8.4",
58
+ "@olane/o-lane": "0.8.4",
59
+ "@olane/o-leader": "0.8.4",
60
+ "@olane/o-protocol": "0.8.4",
61
+ "@olane/o-storage": "0.8.4",
62
+ "@olane/o-tool": "0.8.4",
63
63
  "debug": "^4.4.1",
64
64
  "dotenv": "^16.5.0"
65
65
  },
66
- "gitHead": "9e35c874d849d051bcffe483fd2a8c2b3ecf68cc"
66
+ "gitHead": "b53623b1ad4365133911722f80d5597a72b65bf2"
67
67
  }