@olane/o-tools-common 0.7.2 → 0.7.3

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 +664 -0
  2. package/package.json +9 -9
package/README.md CHANGED
@@ -1 +1,665 @@
1
1
  # o-tools-common
2
+
3
+ **⚠️ EXPERIMENTAL PACKAGE** - This package is in active development and APIs may change.
4
+
5
+ Common tool collection for Olane OS nodes - provides essential capabilities like encryption, search, and storage that most nodes need.
6
+
7
+ **TL;DR**: Pre-built tools for encryption, search, and storage that you can add to any node with one function call.
8
+
9
+ ## Quick Start
10
+
11
+ ```bash
12
+ # Install the package
13
+ npm install @olane/o-tools-common
14
+ ```
15
+
16
+ ```typescript
17
+ // Add common tools to your node with one line
18
+ import { oLaneTool } from '@olane/o-lane';
19
+ import { initCommonTools } from '@olane/o-tools-common';
20
+
21
+ class MyNode extends oLaneTool {
22
+ async start() {
23
+ await super.start();
24
+
25
+ // Initialize all common tools
26
+ await initCommonTools(this);
27
+
28
+ // Now you can use encryption, search, and storage tools
29
+ }
30
+ }
31
+ ```
32
+
33
+ ## Overview {#overview}
34
+
35
+ `o-tools-common` is a collection of reusable tools that solve common needs across Olane nodes:
36
+
37
+ - **Encryption**: Secure data encryption/decryption using AES-256-GCM
38
+ - **Search**: Network-wide vector search capabilities
39
+ - **Storage**: Persistent data storage (via `@olane/o-storage`)
40
+
41
+ Instead of implementing these capabilities in every node, import this package and get them instantly.
42
+
43
+ ## Installation {#installation}
44
+
45
+ ```bash
46
+ npm install @olane/o-tools-common
47
+ ```
48
+
49
+ **Peer Dependencies:**
50
+
51
+ The package requires these Olane packages (usually already in your project):
52
+
53
+ ```json
54
+ {
55
+ "@olane/o-config": "^0.7.2",
56
+ "@olane/o-core": "^0.7.2",
57
+ "@olane/o-leader": "^0.7.2",
58
+ "@olane/o-protocol": "^0.7.2",
59
+ "@olane/o-storage": "^0.7.2",
60
+ "@olane/o-tool": "^0.7.2",
61
+ "@olane/o-lane": "^0.7.2"
62
+ }
63
+ ```
64
+
65
+ ## Available Tools {#available-tools}
66
+
67
+ ### 1. Encryption Tool {#encryption-tool}
68
+
69
+ Encrypts and decrypts sensitive data using AES-256-GCM algorithm.
70
+
71
+ **Address**: `o://encryption`
72
+
73
+ #### Methods
74
+
75
+ ##### `_tool_encrypt(request)`
76
+
77
+ Encrypts plaintext to base64-encoded encrypted string.
78
+
79
+ **Parameters:**
80
+ - `value` (string, required): The plaintext to encrypt
81
+
82
+ **Returns:**
83
+ ```typescript
84
+ {
85
+ value: string // Base64-encoded encrypted data
86
+ }
87
+ ```
88
+
89
+ **Example:**
90
+
91
+ ```typescript
92
+ // Encrypt sensitive data
93
+ const result = await node.use(new oAddress('o://encryption'), {
94
+ method: 'encrypt',
95
+ params: {
96
+ value: 'my-secret-password'
97
+ }
98
+ });
99
+
100
+ console.log(result.value);
101
+ // Output: "eyJlbmNyeXB0ZWRUZXh0Ij..."
102
+ ```
103
+
104
+ ##### `_tool_decrypt(request)`
105
+
106
+ Decrypts base64-encoded encrypted string back to plaintext.
107
+
108
+ **Parameters:**
109
+ - `value` (string, required): Base64-encoded encrypted data
110
+
111
+ **Returns:**
112
+ ```typescript
113
+ {
114
+ value: string // Decrypted plaintext
115
+ }
116
+ ```
117
+
118
+ **Example:**
119
+
120
+ ```typescript
121
+ // Decrypt encrypted data
122
+ const result = await node.use(new oAddress('o://encryption'), {
123
+ method: 'decrypt',
124
+ params: {
125
+ value: 'eyJlbmNyeXB0ZWRUZXh0Ij...'
126
+ }
127
+ });
128
+
129
+ console.log(result.value);
130
+ // Output: "my-secret-password"
131
+ ```
132
+
133
+ #### Configuration
134
+
135
+ Set encryption key via environment variable:
136
+
137
+ ```bash
138
+ # .env file
139
+ VAULT_KEY=your-secret-key-here
140
+ ```
141
+
142
+ **Generate a secure key:**
143
+
144
+ ```typescript
145
+ import { EncryptionService } from '@olane/o-tools-common';
146
+
147
+ const secretKey = EncryptionService.generateSecretKey();
148
+ console.log(secretKey);
149
+ // Use this in your VAULT_KEY env var
150
+ ```
151
+
152
+ ---
153
+
154
+ ### 2. Search Tool {#search-tool}
155
+
156
+ Performs vector-based semantic search across the Olane network.
157
+
158
+ **Address**: `o://search`
159
+
160
+ #### Methods
161
+
162
+ ##### `_tool_vector(request)`
163
+
164
+ Searches the network using vector similarity.
165
+
166
+ **Parameters:**
167
+ - `query` (string, required): Search query
168
+ - `limit` (number, optional): Maximum results to return (default: 10)
169
+
170
+ **Returns:**
171
+ ```typescript
172
+ Array<{
173
+ // Search results from vector store
174
+ // Structure depends on vector store implementation
175
+ }>
176
+ ```
177
+
178
+ **Example:**
179
+
180
+ ```typescript
181
+ // Search for documents about financial analysis
182
+ const results = await node.use(new oAddress('o://search'), {
183
+ method: 'vector',
184
+ params: {
185
+ query: 'financial analysis and revenue forecasting',
186
+ limit: 5
187
+ }
188
+ });
189
+
190
+ console.log(results);
191
+ // Returns 5 most similar documents
192
+ ```
193
+
194
+ <Note>
195
+ **Prerequisite**: Search tool requires a vector store node at `o://vector-store` with a `search_similar` method.
196
+ </Note>
197
+
198
+ ---
199
+
200
+ ### 3. Storage Tool {#storage-tool}
201
+
202
+ Provides persistent data storage capabilities. This tool is imported from `@olane/o-storage`.
203
+
204
+ **Address**: `o://storage`
205
+
206
+ See [@olane/o-storage documentation](/packages/o-storage) for complete API reference.
207
+
208
+ ## Usage Guide {#usage-guide}
209
+
210
+ ### Basic Setup
211
+
212
+ Add common tools to any `oLaneTool` node:
213
+
214
+ ```typescript
215
+ import { oLaneTool } from '@olane/o-lane';
216
+ import { oAddress } from '@olane/o-core';
217
+ import { initCommonTools } from '@olane/o-tools-common';
218
+
219
+ class FinancialAnalystNode extends oLaneTool {
220
+ constructor() {
221
+ super({
222
+ address: new oAddress('o://company/finance/analyst'),
223
+ laneContext: {
224
+ domain: 'Financial Analysis'
225
+ }
226
+ });
227
+ }
228
+
229
+ async start() {
230
+ await super.start();
231
+
232
+ // Add all common tools
233
+ await initCommonTools(this);
234
+
235
+ this.logger.info('Common tools initialized');
236
+ }
237
+
238
+ // Now you can use common tools in your methods
239
+ async _tool_save_report(request: oRequest) {
240
+ const { reportData } = request.params;
241
+
242
+ // Use encryption tool
243
+ const encrypted = await this.use(
244
+ new oAddress('o://encryption'),
245
+ { method: 'encrypt', params: { value: reportData } }
246
+ );
247
+
248
+ // Use storage tool
249
+ await this.use(
250
+ new oAddress('o://storage'),
251
+ { method: 'set', params: { key: 'report', value: encrypted.value } }
252
+ );
253
+
254
+ return { saved: true };
255
+ }
256
+ }
257
+ ```
258
+
259
+ ### Selective Tool Initialization
260
+
261
+ Initialize tools individually if you don't need all of them:
262
+
263
+ ```typescript
264
+ import { EncryptionTool } from '@olane/o-tools-common';
265
+ import { oLaneTool } from '@olane/o-lane';
266
+
267
+ class MyNode extends oLaneTool {
268
+ async start() {
269
+ await super.start();
270
+
271
+ // Only add encryption tool
272
+ const encryptionTool = new EncryptionTool({
273
+ name: 'encryption',
274
+ parent: this.address,
275
+ leader: this.leader
276
+ });
277
+
278
+ await encryptionTool.start();
279
+ this.addChildNode(encryptionTool as any);
280
+ }
281
+ }
282
+ ```
283
+
284
+ ## Common Use Cases {#use-cases}
285
+
286
+ ### Use Case 1: Encrypt User Credentials
287
+
288
+ ```typescript
289
+ class AuthNode extends oLaneTool {
290
+ async _tool_store_credentials(request: oRequest) {
291
+ const { username, password } = request.params;
292
+
293
+ // Encrypt password before storing
294
+ const encrypted = await this.use(
295
+ new oAddress('o://encryption'),
296
+ { method: 'encrypt', params: { value: password } }
297
+ );
298
+
299
+ // Store encrypted password
300
+ await this.use(
301
+ new oAddress('o://storage'),
302
+ {
303
+ method: 'set',
304
+ params: {
305
+ key: `user:${username}:password`,
306
+ value: encrypted.value
307
+ }
308
+ }
309
+ );
310
+
311
+ return { success: true };
312
+ }
313
+
314
+ async _tool_verify_credentials(request: oRequest) {
315
+ const { username, password } = request.params;
316
+
317
+ // Retrieve encrypted password
318
+ const stored = await this.use(
319
+ new oAddress('o://storage'),
320
+ { method: 'get', params: { key: `user:${username}:password` } }
321
+ );
322
+
323
+ // Decrypt and compare
324
+ const decrypted = await this.use(
325
+ new oAddress('o://encryption'),
326
+ { method: 'decrypt', params: { value: stored.value } }
327
+ );
328
+
329
+ return { valid: decrypted.value === password };
330
+ }
331
+ }
332
+ ```
333
+
334
+ ### Use Case 2: Search and Retrieve Context
335
+
336
+ ```typescript
337
+ class DocumentAnalystNode extends oLaneTool {
338
+ async _tool_analyze_with_context(request: oRequest) {
339
+ const { query } = request.params;
340
+
341
+ // Search for relevant documents
342
+ const context = await this.use(
343
+ new oAddress('o://search'),
344
+ {
345
+ method: 'vector',
346
+ params: {
347
+ query: query,
348
+ limit: 5
349
+ }
350
+ }
351
+ );
352
+
353
+ // Use context to generate analysis
354
+ const analysis = this.analyzeWithContext(query, context);
355
+
356
+ // Store analysis result
357
+ 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
+ }
365
+ }
366
+ );
367
+
368
+ return analysis;
369
+ }
370
+ }
371
+ ```
372
+
373
+ ### Use Case 3: Secure API Key Management
374
+
375
+ ```typescript
376
+ class IntegrationNode extends oLaneTool {
377
+ async _tool_store_api_key(request: oRequest) {
378
+ const { service, apiKey } = request.params;
379
+
380
+ // Encrypt API key
381
+ const encrypted = await this.use(
382
+ new oAddress('o://encryption'),
383
+ { method: 'encrypt', params: { value: apiKey } }
384
+ );
385
+
386
+ // Store encrypted key
387
+ await this.use(
388
+ new oAddress('o://storage'),
389
+ {
390
+ method: 'set',
391
+ params: {
392
+ key: `api-keys:${service}`,
393
+ value: encrypted.value
394
+ }
395
+ }
396
+ );
397
+
398
+ return { stored: true };
399
+ }
400
+
401
+ private async getApiKey(service: string): Promise<string> {
402
+ // Retrieve encrypted key
403
+ const stored = await this.use(
404
+ new oAddress('o://storage'),
405
+ { method: 'get', params: { key: `api-keys:${service}` } }
406
+ );
407
+
408
+ // Decrypt and return
409
+ const decrypted = await this.use(
410
+ new oAddress('o://encryption'),
411
+ { method: 'decrypt', params: { value: stored.value } }
412
+ );
413
+
414
+ return decrypted.value;
415
+ }
416
+ }
417
+ ```
418
+
419
+ ## API Reference {#api-reference}
420
+
421
+ ### `initCommonTools(oNode: oLaneTool): Promise<Tool[]>`
422
+
423
+ Initializes all common tools as child nodes of the provided parent node.
424
+
425
+ **Parameters:**
426
+ - `oNode` (oLaneTool, required): Parent node to attach common tools to
427
+
428
+ **Returns:**
429
+ - `Promise<Tool[]>`: Array of initialized tool instances
430
+
431
+ **Example:**
432
+
433
+ ```typescript
434
+ import { initCommonTools } from '@olane/o-tools-common';
435
+ import { oLaneTool } from '@olane/o-lane';
436
+
437
+ class MyNode extends oLaneTool {
438
+ async start() {
439
+ await super.start();
440
+
441
+ const tools = await initCommonTools(this);
442
+ // tools[0] = StorageTool
443
+ // tools[1] = EncryptionTool
444
+ // tools[2] = SearchTool
445
+
446
+ console.log(`Initialized ${tools.length} common tools`);
447
+ }
448
+ }
449
+ ```
450
+
451
+ ### `EncryptionTool`
452
+
453
+ Tool class for encryption/decryption operations.
454
+
455
+ **Constructor:**
456
+
457
+ ```typescript
458
+ new EncryptionTool(config: oNodeToolConfig)
459
+ ```
460
+
461
+ **Config:**
462
+ ```typescript
463
+ {
464
+ name: string, // Tool name
465
+ parent: oAddress, // Parent node address
466
+ leader: LeaderClient // Leader client instance
467
+ }
468
+ ```
469
+
470
+ ### `SearchTool`
471
+
472
+ Tool class for network search operations.
473
+
474
+ **Constructor:**
475
+
476
+ ```typescript
477
+ new SearchTool(config: oNodeToolConfig)
478
+ ```
479
+
480
+ **Config:**
481
+ ```typescript
482
+ {
483
+ name: string, // Tool name
484
+ parent: oAddress, // Parent node address
485
+ leader: LeaderClient // Leader client instance
486
+ }
487
+ ```
488
+
489
+ ## Configuration {#configuration}
490
+
491
+ ### Environment Variables
492
+
493
+ ```bash
494
+ # Encryption key (required for EncryptionTool)
495
+ VAULT_KEY=your-secret-encryption-key
496
+
497
+ # Generate with:
498
+ # node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
499
+ ```
500
+
501
+ ### Security Best Practices
502
+
503
+ <Warning>
504
+ **Never commit encryption keys to version control!** Always use environment variables or secure secret management.
505
+ </Warning>
506
+
507
+ 1. **Generate strong keys**: Use `EncryptionService.generateSecretKey()` or crypto library
508
+ 2. **Rotate keys periodically**: Update `VAULT_KEY` on a schedule
509
+ 3. **Use different keys per environment**: Development, staging, and production should have unique keys
510
+ 4. **Store keys securely**: Use secret managers like AWS Secrets Manager, Azure Key Vault, or HashiCorp Vault
511
+
512
+ ## Troubleshooting {#troubleshooting}
513
+
514
+ ### Error: "Encryption failed"
515
+
516
+ **Cause**: `VAULT_KEY` environment variable not set or invalid.
517
+
518
+ **Solution:**
519
+ ```bash
520
+ # Generate a new key
521
+ node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
522
+
523
+ # Add to .env file
524
+ echo "VAULT_KEY=<generated-key>" >> .env
525
+ ```
526
+
527
+ ### Error: "Decryption failed"
528
+
529
+ **Cause**: Encrypted data was created with a different key than current `VAULT_KEY`.
530
+
531
+ **Solution:**
532
+ - Ensure you're using the same `VAULT_KEY` that was used for encryption
533
+ - If key was rotated, decrypt old data with old key and re-encrypt with new key
534
+
535
+ ### Error: "Cannot find module 'o://vector-store'"
536
+
537
+ **Cause**: Search tool requires a vector store node but none is running.
538
+
539
+ **Solution:**
540
+ ```typescript
541
+ // Option 1: Don't initialize search tool
542
+ const storageTools = [
543
+ new StorageTool({ name: 'storage', parent: this.address, leader: this.leader }),
544
+ new EncryptionTool({ name: 'encryption', parent: this.address, leader: this.leader })
545
+ ];
546
+
547
+ // Option 2: Implement vector store node
548
+ // See @olane/o-storage documentation for vector store setup
549
+ ```
550
+
551
+ ### Warning: "Peer dependency not met"
552
+
553
+ **Cause**: Missing required Olane packages.
554
+
555
+ **Solution:**
556
+ ```bash
557
+ # Install all peer dependencies
558
+ npm install @olane/o-core@latest @olane/o-config@latest \
559
+ @olane/o-protocol@latest @olane/o-tool@latest \
560
+ @olane/o-lane@latest @olane/o-leader@latest \
561
+ @olane/o-storage@latest
562
+ ```
563
+
564
+ ## Performance Considerations {#performance}
565
+
566
+ ### Encryption Overhead
567
+
568
+ - **Encryption time**: ~1-2ms per operation for typical strings
569
+ - **Recommendation**: Batch encrypt when possible, cache decrypted values if reused
570
+
571
+ ### Search Performance
572
+
573
+ - Search performance depends on vector store implementation and dataset size
574
+ - **Recommendation**: Set appropriate `limit` parameters (default 10)
575
+
576
+ ### Storage
577
+
578
+ - Storage performance varies by backend (memory, disk, database)
579
+ - See `@olane/o-storage` documentation for optimization tips
580
+
581
+ ## Architecture {#architecture}
582
+
583
+ Common tools are implemented as **child nodes** of your main node:
584
+
585
+ ```
586
+ ┌─────────────────────────────────────────┐
587
+ │ Your Node (oLaneTool) │
588
+ │ o://your-node │
589
+ │ │
590
+ │ ┌───────────────────────────────────┐ │
591
+ │ │ Child Nodes (Common Tools) │ │
592
+ │ │ │ │
593
+ │ │ o://encryption │ │
594
+ │ │ o://search │ │
595
+ │ │ o://storage │ │
596
+ │ └───────────────────────────────────┘ │
597
+ └─────────────────────────────────────────┘
598
+ ```
599
+
600
+ **How it works:**
601
+
602
+ 1. `initCommonTools()` creates tool instances
603
+ 2. Each tool is started independently
604
+ 3. Tools are added as child nodes via `addChildNode()`
605
+ 4. Your node can call tools using `this.use(address, params)`
606
+ 5. Other nodes in the network can also discover and use these tools
607
+
608
+ ## Package Details {#package-details}
609
+
610
+ **Current Version**: 0.7.2
611
+
612
+ **Repository**: [github.com/olane-labs/olane](https://github.com/olane-labs/olane)
613
+
614
+ **License**: ISC
615
+
616
+ **Status**: ⚠️ Experimental - APIs subject to change
617
+
618
+ ## Limitations {#limitations}
619
+
620
+ <Warning>
621
+ This is an **experimental package**. Expect breaking changes in future versions.
622
+ </Warning>
623
+
624
+ - **Encryption**: Uses single key for all data (no key rotation support yet)
625
+ - **Search**: Requires separate vector store implementation
626
+ - **Storage**: Limited to capabilities of `@olane/o-storage`
627
+ - **No selective exports**: All tools initialized together or manually
628
+
629
+ ## Roadmap {#roadmap}
630
+
631
+ Planned improvements:
632
+
633
+ - [ ] Key rotation support for encryption
634
+ - [ ] Built-in vector store implementation
635
+ - [ ] Caching layer for frequently decrypted values
636
+ - [ ] Compression for encrypted data
637
+ - [ ] Batch operations for encryption
638
+ - [ ] More granular tool configuration
639
+ - [ ] Additional common tools (logging, monitoring, etc.)
640
+
641
+ ## Related Resources {#related}
642
+
643
+ - **Package**: [o-tool Documentation](/packages/o-tool) - Base tool interface
644
+ - **Package**: [o-lane Documentation](/packages/o-lane) - Autonomous nodes
645
+ - **Package**: [o-storage Documentation](/packages/o-storage) - Storage capabilities
646
+ - **Package**: [o-leader Documentation](/packages/o-leader) - Service discovery
647
+ - **Concept**: [Tools vs Nodes](/docs/concepts/tools-nodes-applications) - Architecture patterns
648
+ - **Guide**: [Building Tool Nodes](/guides/building-nodes) - Node development
649
+
650
+ ## Examples {#examples}
651
+
652
+ See complete examples in the [examples directory](/examples):
653
+
654
+ - **Secure Node**: Node with encrypted credential storage
655
+ - **Search Node**: Document search and retrieval
656
+ - **Hybrid Node**: Combined search, storage, and encryption
657
+
658
+ ## Contributing
659
+
660
+ Found a bug or have a feature request? Open an issue on [GitHub](https://github.com/olane-labs/olane/issues).
661
+
662
+ ## License
663
+
664
+ ISC © oLane Inc.
665
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olane/o-tools-common",
3
- "version": "0.7.2",
3
+ "version": "0.7.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -31,7 +31,7 @@
31
31
  "url": "git+https://github.com/olane-labs/olane.git"
32
32
  },
33
33
  "author": "oLane Inc.",
34
- "license": "ISC",
34
+ "license": "(MIT OR Apache-2.0)",
35
35
  "description": "oLane common tools for most tool nodes",
36
36
  "devDependencies": {
37
37
  "@eslint/eslintrc": "^3.3.1",
@@ -54,13 +54,13 @@
54
54
  "typescript": "5.4.5"
55
55
  },
56
56
  "peerDependencies": {
57
- "@olane/o-config": "^0.7.1",
58
- "@olane/o-core": "^0.7.1",
59
- "@olane/o-lane": "^0.7.1",
60
- "@olane/o-leader": "^0.7.1",
61
- "@olane/o-protocol": "^0.7.1",
62
- "@olane/o-storage": "^0.7.1",
63
- "@olane/o-tool": "^0.7.1"
57
+ "@olane/o-config": "^0.7.2",
58
+ "@olane/o-core": "^0.7.2",
59
+ "@olane/o-lane": "^0.7.2",
60
+ "@olane/o-leader": "^0.7.2",
61
+ "@olane/o-protocol": "^0.7.2",
62
+ "@olane/o-storage": "^0.7.2",
63
+ "@olane/o-tool": "^0.7.2"
64
64
  },
65
65
  "dependencies": {
66
66
  "debug": "^4.4.1",