@soulcraft/brainy 0.15.0 → 0.17.0
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 +342 -309
- package/dist/brainyData.d.ts +18 -0
- package/dist/unified.js +61 -2
- package/dist/unified.min.js +1 -1
- package/package.json +3 -5
package/README.md
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
[](https://nodejs.org/)
|
|
7
7
|
[](https://www.typescriptlang.org/)
|
|
8
8
|
[](CONTRIBUTING.md)
|
|
9
|
-
[](https://www.npmjs.com/package/@soulcraft/brainy)
|
|
10
9
|
|
|
11
10
|
[//]: # ([](https://github.com/sodal-project/cartographer))
|
|
12
11
|
|
|
@@ -36,7 +35,7 @@ it gets - learning from your data to provide increasingly relevant results and c
|
|
|
36
35
|
- **Adaptive Intelligence** - Automatically optimizes for your environment and usage patterns
|
|
37
36
|
- **Persistent Storage** - Data persists across sessions and scales to any size
|
|
38
37
|
- **TypeScript Support** - Fully typed API with generics
|
|
39
|
-
- **CLI Tools** -
|
|
38
|
+
- **CLI Tools & Web Service** - Command-line interface and REST API web service for data management
|
|
40
39
|
- **Model Control Protocol (MCP)** - Allow external AI models to access Brainy data and use augmentation pipeline as
|
|
41
40
|
tools
|
|
42
41
|
|
|
@@ -62,14 +61,31 @@ GitHub Pages that showcases Brainy's main features.
|
|
|
62
61
|
npm install @soulcraft/brainy
|
|
63
62
|
```
|
|
64
63
|
|
|
65
|
-
TensorFlow.js packages are included as bundled dependencies and will be automatically installed without any additional
|
|
64
|
+
TensorFlow.js packages are included as bundled dependencies and will be automatically installed without any additional
|
|
65
|
+
configuration.
|
|
66
|
+
|
|
67
|
+
### Additional Packages
|
|
68
|
+
|
|
69
|
+
Brainy offers specialized packages for different use cases:
|
|
70
|
+
|
|
71
|
+
#### CLI Package
|
|
72
|
+
```bash
|
|
73
|
+
npm install -g @soulcraft/brainy-cli
|
|
74
|
+
```
|
|
75
|
+
Command-line interface for data management, bulk operations, and database administration.
|
|
76
|
+
|
|
77
|
+
#### Web Service Package
|
|
78
|
+
```bash
|
|
79
|
+
npm install @soulcraft/brainy-web-service
|
|
80
|
+
```
|
|
81
|
+
REST API web service wrapper that provides HTTP endpoints for search operations and database queries.
|
|
66
82
|
|
|
67
83
|
## 🏁 Quick Start
|
|
68
84
|
|
|
69
85
|
Brainy uses a unified build that automatically adapts to your environment (Node.js, browser, or serverless):
|
|
70
86
|
|
|
71
87
|
```typescript
|
|
72
|
-
import {
|
|
88
|
+
import {BrainyData, NounType, VerbType} from '@soulcraft/brainy'
|
|
73
89
|
|
|
74
90
|
// Create and initialize the database
|
|
75
91
|
const db = new BrainyData()
|
|
@@ -77,13 +93,13 @@ await db.init()
|
|
|
77
93
|
|
|
78
94
|
// Add data (automatically converted to vectors)
|
|
79
95
|
const catId = await db.add("Cats are independent pets", {
|
|
80
|
-
|
|
81
|
-
|
|
96
|
+
noun: NounType.Thing,
|
|
97
|
+
category: 'animal'
|
|
82
98
|
})
|
|
83
99
|
|
|
84
100
|
const dogId = await db.add("Dogs are loyal companions", {
|
|
85
|
-
|
|
86
|
-
|
|
101
|
+
noun: NounType.Thing,
|
|
102
|
+
category: 'animal'
|
|
87
103
|
})
|
|
88
104
|
|
|
89
105
|
// Search for similar items
|
|
@@ -92,8 +108,8 @@ console.log(results)
|
|
|
92
108
|
|
|
93
109
|
// Add a relationship between items
|
|
94
110
|
await db.addVerb(catId, dogId, {
|
|
95
|
-
|
|
96
|
-
|
|
111
|
+
verb: VerbType.RelatedTo,
|
|
112
|
+
description: 'Both are common household pets'
|
|
97
113
|
})
|
|
98
114
|
```
|
|
99
115
|
|
|
@@ -101,28 +117,30 @@ await db.addVerb(catId, dogId, {
|
|
|
101
117
|
|
|
102
118
|
```typescript
|
|
103
119
|
// Standard import - automatically adapts to any environment
|
|
104
|
-
import {
|
|
120
|
+
import {BrainyData} from '@soulcraft/brainy'
|
|
105
121
|
|
|
106
122
|
// Minified version for production
|
|
107
|
-
import {
|
|
123
|
+
import {BrainyData} from '@soulcraft/brainy/min'
|
|
108
124
|
```
|
|
109
125
|
|
|
110
|
-
> **Note**: The CLI functionality is available as a separate package `@soulcraft/brainy-cli` to reduce the bundle size
|
|
126
|
+
> **Note**: The CLI functionality is available as a separate package `@soulcraft/brainy-cli` to reduce the bundle size
|
|
127
|
+
> of the main package. Install it globally with `npm install -g @soulcraft/brainy-cli` to use the command-line
|
|
128
|
+
> interface.
|
|
111
129
|
|
|
112
130
|
### Browser Usage
|
|
113
131
|
|
|
114
132
|
```html
|
|
115
133
|
|
|
116
134
|
<script type="module">
|
|
117
|
-
|
|
118
|
-
|
|
135
|
+
// Use local files instead of CDN
|
|
136
|
+
import {BrainyData} from './dist/unified.js'
|
|
119
137
|
|
|
120
|
-
|
|
121
|
-
|
|
138
|
+
// Or minified version
|
|
139
|
+
// import { BrainyData } from './dist/unified.min.js'
|
|
122
140
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
141
|
+
const db = new BrainyData()
|
|
142
|
+
await db.init()
|
|
143
|
+
// ...
|
|
126
144
|
</script>
|
|
127
145
|
```
|
|
128
146
|
|
|
@@ -277,13 +295,13 @@ The pipeline runs automatically when you:
|
|
|
277
295
|
|
|
278
296
|
```typescript
|
|
279
297
|
// Add data (runs embedding → indexing → storage)
|
|
280
|
-
const id = await db.add("Your text data here", {
|
|
298
|
+
const id = await db.add("Your text data here", {metadata})
|
|
281
299
|
|
|
282
300
|
// Search (runs embedding → similarity search)
|
|
283
301
|
const results = await db.searchText("Your query here", 5)
|
|
284
302
|
|
|
285
303
|
// Connect entities (runs graph construction → storage)
|
|
286
|
-
await db.addVerb(sourceId, targetId, {
|
|
304
|
+
await db.addVerb(sourceId, targetId, {verb: VerbType.RelatedTo})
|
|
287
305
|
```
|
|
288
306
|
|
|
289
307
|
Using the CLI:
|
|
@@ -408,7 +426,8 @@ brainy visualize --root <id> --depth 3
|
|
|
408
426
|
|
|
409
427
|
### Using the CLI in Your Code
|
|
410
428
|
|
|
411
|
-
The CLI functionality is available as a separate package `@soulcraft/brainy-cli`. If you need CLI functionality in your
|
|
429
|
+
The CLI functionality is available as a separate package `@soulcraft/brainy-cli`. If you need CLI functionality in your
|
|
430
|
+
application, install the CLI package:
|
|
412
431
|
|
|
413
432
|
```bash
|
|
414
433
|
npm install @soulcraft/brainy-cli
|
|
@@ -466,7 +485,7 @@ const status = await db.status()
|
|
|
466
485
|
const backupData = await db.backup()
|
|
467
486
|
|
|
468
487
|
// Restore data into the database
|
|
469
|
-
const restoreResult = await db.restore(backupData, {
|
|
488
|
+
const restoreResult = await db.restore(backupData, {clearExisting: true})
|
|
470
489
|
```
|
|
471
490
|
|
|
472
491
|
### Working with Nouns (Entities)
|
|
@@ -474,25 +493,25 @@ const restoreResult = await db.restore(backupData, { clearExisting: true })
|
|
|
474
493
|
```typescript
|
|
475
494
|
// Add a noun (automatically vectorized)
|
|
476
495
|
const id = await db.add(textOrVector, {
|
|
477
|
-
|
|
478
|
-
|
|
496
|
+
noun: NounType.Thing,
|
|
497
|
+
// other metadata...
|
|
479
498
|
})
|
|
480
499
|
|
|
481
500
|
// Add multiple nouns in parallel (with multithreading and batch embedding)
|
|
482
501
|
const ids = await db.addBatch([
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
502
|
+
{
|
|
503
|
+
vectorOrData: "First item to add",
|
|
504
|
+
metadata: {noun: NounType.Thing, category: 'example'}
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
vectorOrData: "Second item to add",
|
|
508
|
+
metadata: {noun: NounType.Thing, category: 'example'}
|
|
509
|
+
},
|
|
510
|
+
// More items...
|
|
492
511
|
], {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
512
|
+
forceEmbed: false,
|
|
513
|
+
concurrency: 4, // Control the level of parallelism (default: 4)
|
|
514
|
+
batchSize: 50 // Control the number of items to process in a single batch (default: 50)
|
|
496
515
|
})
|
|
497
516
|
|
|
498
517
|
// Retrieve a noun
|
|
@@ -500,8 +519,8 @@ const noun = await db.get(id)
|
|
|
500
519
|
|
|
501
520
|
// Update noun metadata
|
|
502
521
|
await db.updateMetadata(id, {
|
|
503
|
-
|
|
504
|
-
|
|
522
|
+
noun: NounType.Thing,
|
|
523
|
+
// updated metadata...
|
|
505
524
|
})
|
|
506
525
|
|
|
507
526
|
// Delete a noun
|
|
@@ -520,8 +539,21 @@ const thingNouns = await db.searchByNounTypes([NounType.Thing], numResults)
|
|
|
520
539
|
```typescript
|
|
521
540
|
// Add a relationship between nouns
|
|
522
541
|
await db.addVerb(sourceId, targetId, {
|
|
523
|
-
|
|
524
|
-
|
|
542
|
+
verb: VerbType.RelatedTo,
|
|
543
|
+
// other metadata...
|
|
544
|
+
})
|
|
545
|
+
|
|
546
|
+
// Add a relationship with auto-creation of missing nouns
|
|
547
|
+
// This is useful when the target noun might not exist yet
|
|
548
|
+
await db.addVerb(sourceId, targetId, {
|
|
549
|
+
verb: VerbType.RelatedTo,
|
|
550
|
+
// Enable auto-creation of missing nouns
|
|
551
|
+
autoCreateMissingNouns: true,
|
|
552
|
+
// Optional metadata for auto-created nouns
|
|
553
|
+
missingNounMetadata: {
|
|
554
|
+
noun: NounType.Concept,
|
|
555
|
+
description: 'Auto-created noun'
|
|
556
|
+
}
|
|
525
557
|
})
|
|
526
558
|
|
|
527
559
|
// Get all relationships
|
|
@@ -549,20 +581,20 @@ await db.deleteVerb(verbId)
|
|
|
549
581
|
|
|
550
582
|
```typescript
|
|
551
583
|
import {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
584
|
+
BrainyData,
|
|
585
|
+
createTensorFlowEmbeddingFunction,
|
|
586
|
+
createThreadedEmbeddingFunction
|
|
555
587
|
} from '@soulcraft/brainy'
|
|
556
588
|
|
|
557
589
|
// Use the standard TensorFlow Universal Sentence Encoder embedding function
|
|
558
590
|
const db = new BrainyData({
|
|
559
|
-
|
|
591
|
+
embeddingFunction: createTensorFlowEmbeddingFunction()
|
|
560
592
|
})
|
|
561
593
|
await db.init()
|
|
562
594
|
|
|
563
595
|
// Or use the threaded embedding function for better performance
|
|
564
596
|
const threadedDb = new BrainyData({
|
|
565
|
-
|
|
597
|
+
embeddingFunction: createThreadedEmbeddingFunction()
|
|
566
598
|
})
|
|
567
599
|
await threadedDb.init()
|
|
568
600
|
|
|
@@ -603,42 +635,42 @@ Brainy includes comprehensive multithreading support to improve performance acro
|
|
|
603
635
|
7. **Automatic Environment Detection**: Adapts to browser (Web Workers) and Node.js (Worker Threads) environments
|
|
604
636
|
|
|
605
637
|
```typescript
|
|
606
|
-
import {
|
|
638
|
+
import {BrainyData, euclideanDistance} from '@soulcraft/brainy'
|
|
607
639
|
|
|
608
640
|
// Configure with custom options
|
|
609
641
|
const db = new BrainyData({
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
+
// Use Euclidean distance instead of default cosine distance
|
|
643
|
+
distanceFunction: euclideanDistance,
|
|
644
|
+
|
|
645
|
+
// HNSW index configuration for search performance
|
|
646
|
+
hnsw: {
|
|
647
|
+
M: 16, // Max connections per noun
|
|
648
|
+
efConstruction: 200, // Construction candidate list size
|
|
649
|
+
efSearch: 50, // Search candidate list size
|
|
650
|
+
},
|
|
651
|
+
|
|
652
|
+
// Performance optimization options
|
|
653
|
+
performance: {
|
|
654
|
+
useParallelization: true, // Enable multithreaded search operations
|
|
655
|
+
},
|
|
656
|
+
|
|
657
|
+
// Noun and Verb type validation
|
|
658
|
+
typeValidation: {
|
|
659
|
+
enforceNounTypes: true, // Validate noun types against NounType enum
|
|
660
|
+
enforceVerbTypes: true, // Validate verb types against VerbType enum
|
|
661
|
+
},
|
|
662
|
+
|
|
663
|
+
// Storage configuration
|
|
664
|
+
storage: {
|
|
665
|
+
requestPersistentStorage: true,
|
|
666
|
+
// Example configuration for cloud storage (replace with your own values):
|
|
667
|
+
// s3Storage: {
|
|
668
|
+
// bucketName: 'your-s3-bucket-name',
|
|
669
|
+
// region: 'your-aws-region'
|
|
670
|
+
// // Credentials should be provided via environment variables
|
|
671
|
+
// // AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
|
|
672
|
+
// }
|
|
673
|
+
}
|
|
642
674
|
})
|
|
643
675
|
```
|
|
644
676
|
|
|
@@ -652,34 +684,34 @@ hybrid approach:
|
|
|
652
684
|
3. **Memory-Efficient Indexing** - Optimizes memory usage for large-scale vector collections
|
|
653
685
|
|
|
654
686
|
```typescript
|
|
655
|
-
import {
|
|
687
|
+
import {BrainyData} from '@soulcraft/brainy'
|
|
656
688
|
|
|
657
689
|
// Configure with optimized HNSW index for large datasets
|
|
658
690
|
const db = new BrainyData({
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
691
|
+
hnswOptimized: {
|
|
692
|
+
// Standard HNSW parameters
|
|
693
|
+
M: 16, // Max connections per noun
|
|
694
|
+
efConstruction: 200, // Construction candidate list size
|
|
695
|
+
efSearch: 50, // Search candidate list size
|
|
696
|
+
|
|
697
|
+
// Memory threshold in bytes - when exceeded, will use disk-based approach
|
|
698
|
+
memoryThreshold: 1024 * 1024 * 1024, // 1GB default threshold
|
|
699
|
+
|
|
700
|
+
// Product quantization settings for dimensionality reduction
|
|
701
|
+
productQuantization: {
|
|
702
|
+
enabled: true, // Enable product quantization
|
|
703
|
+
numSubvectors: 16, // Number of subvectors to split the vector into
|
|
704
|
+
numCentroids: 256 // Number of centroids per subvector
|
|
705
|
+
},
|
|
706
|
+
|
|
707
|
+
// Whether to use disk-based storage for the index
|
|
708
|
+
useDiskBasedIndex: true // Enable disk-based storage
|
|
673
709
|
},
|
|
674
710
|
|
|
675
|
-
//
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
// Storage configuration (required for disk-based index)
|
|
680
|
-
storage: {
|
|
681
|
-
requestPersistentStorage: true
|
|
682
|
-
}
|
|
711
|
+
// Storage configuration (required for disk-based index)
|
|
712
|
+
storage: {
|
|
713
|
+
requestPersistentStorage: true
|
|
714
|
+
}
|
|
683
715
|
})
|
|
684
716
|
|
|
685
717
|
// The optimized index automatically adapts based on dataset size:
|
|
@@ -744,24 +776,24 @@ Brainy's restore functionality can handle:
|
|
|
744
776
|
```typescript
|
|
745
777
|
// Restore data with all options
|
|
746
778
|
const restoreResult = await db.restore(backupData, {
|
|
747
|
-
|
|
779
|
+
clearExisting: true // Whether to clear existing data before restore
|
|
748
780
|
})
|
|
749
781
|
|
|
750
782
|
// Import sparse data (without vectors)
|
|
751
783
|
// Vectors will be automatically created using the embedding function
|
|
752
784
|
const sparseData = {
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
785
|
+
nouns: [
|
|
786
|
+
{
|
|
787
|
+
id: '123',
|
|
788
|
+
// No vector field - will be created during import
|
|
789
|
+
metadata: {
|
|
790
|
+
noun: 'Thing',
|
|
791
|
+
text: 'This text will be used to generate a vector'
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
],
|
|
795
|
+
verbs: [],
|
|
796
|
+
version: '1.0.0'
|
|
765
797
|
}
|
|
766
798
|
|
|
767
799
|
const sparseImportResult = await db.importSparseData(sparseData)
|
|
@@ -808,82 +840,82 @@ boilerplate:
|
|
|
808
840
|
|
|
809
841
|
```typescript
|
|
810
842
|
import {
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
843
|
+
createMemoryAugmentation,
|
|
844
|
+
createConduitAugmentation,
|
|
845
|
+
createSenseAugmentation,
|
|
846
|
+
addWebSocketSupport,
|
|
847
|
+
executeStreamlined,
|
|
848
|
+
processStaticData,
|
|
849
|
+
processStreamingData,
|
|
850
|
+
createPipeline
|
|
819
851
|
} from '@soulcraft/brainy'
|
|
820
852
|
|
|
821
853
|
// Create a memory augmentation with minimal code
|
|
822
854
|
const memoryAug = createMemoryAugmentation({
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
855
|
+
name: 'simple-memory',
|
|
856
|
+
description: 'A simple in-memory storage augmentation',
|
|
857
|
+
autoRegister: true,
|
|
858
|
+
autoInitialize: true,
|
|
859
|
+
|
|
860
|
+
// Implement only the methods you need
|
|
861
|
+
storeData: async (key, data) => {
|
|
862
|
+
// Your implementation here
|
|
863
|
+
return {
|
|
864
|
+
success: true,
|
|
865
|
+
data: true
|
|
866
|
+
}
|
|
867
|
+
},
|
|
836
868
|
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
869
|
+
retrieveData: async (key) => {
|
|
870
|
+
// Your implementation here
|
|
871
|
+
return {
|
|
872
|
+
success: true,
|
|
873
|
+
data: {example: 'data', key}
|
|
874
|
+
}
|
|
842
875
|
}
|
|
843
|
-
}
|
|
844
876
|
})
|
|
845
877
|
|
|
846
878
|
// Add WebSocket support to any augmentation
|
|
847
879
|
const wsAugmentation = addWebSocketSupport(memoryAug, {
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
880
|
+
connectWebSocket: async (url) => {
|
|
881
|
+
// Your implementation here
|
|
882
|
+
return {
|
|
883
|
+
connectionId: 'ws-1',
|
|
884
|
+
url,
|
|
885
|
+
status: 'connected'
|
|
886
|
+
}
|
|
854
887
|
}
|
|
855
|
-
}
|
|
856
888
|
})
|
|
857
889
|
|
|
858
890
|
// Process static data through a pipeline
|
|
859
891
|
const result = await processStaticData(
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
892
|
+
'Input data',
|
|
893
|
+
[
|
|
894
|
+
{
|
|
895
|
+
augmentation: senseAug,
|
|
896
|
+
method: 'processRawData',
|
|
897
|
+
transformArgs: (data) => [data, 'text']
|
|
898
|
+
},
|
|
899
|
+
{
|
|
900
|
+
augmentation: memoryAug,
|
|
901
|
+
method: 'storeData',
|
|
902
|
+
transformArgs: (data) => ['processed-data', data]
|
|
903
|
+
}
|
|
904
|
+
]
|
|
873
905
|
)
|
|
874
906
|
|
|
875
907
|
// Create a reusable pipeline
|
|
876
908
|
const pipeline = createPipeline([
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
909
|
+
{
|
|
910
|
+
augmentation: senseAug,
|
|
911
|
+
method: 'processRawData',
|
|
912
|
+
transformArgs: (data) => [data, 'text']
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
augmentation: memoryAug,
|
|
916
|
+
method: 'storeData',
|
|
917
|
+
transformArgs: (data) => ['processed-data', data]
|
|
918
|
+
}
|
|
887
919
|
])
|
|
888
920
|
|
|
889
921
|
// Use the pipeline
|
|
@@ -891,11 +923,11 @@ const result = await pipeline('New input data')
|
|
|
891
923
|
|
|
892
924
|
// Dynamically load augmentations at runtime
|
|
893
925
|
const loadedAugmentations = await loadAugmentationModule(
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
926
|
+
import('./my-augmentations.js'),
|
|
927
|
+
{
|
|
928
|
+
autoRegister: true,
|
|
929
|
+
autoInitialize: true
|
|
930
|
+
}
|
|
899
931
|
)
|
|
900
932
|
```
|
|
901
933
|
|
|
@@ -909,60 +941,61 @@ The simplified augmentation system provides:
|
|
|
909
941
|
|
|
910
942
|
#### WebSocket Augmentation Types
|
|
911
943
|
|
|
912
|
-
Brainy exports several WebSocket augmentation types that can be used by augmentation creators to add WebSocket
|
|
944
|
+
Brainy exports several WebSocket augmentation types that can be used by augmentation creators to add WebSocket
|
|
945
|
+
capabilities to their augmentations:
|
|
913
946
|
|
|
914
947
|
```typescript
|
|
915
948
|
import {
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
949
|
+
// Base WebSocket support interface
|
|
950
|
+
IWebSocketSupport,
|
|
951
|
+
|
|
952
|
+
// Combined WebSocket augmentation types
|
|
953
|
+
IWebSocketSenseAugmentation,
|
|
954
|
+
IWebSocketConduitAugmentation,
|
|
955
|
+
IWebSocketCognitionAugmentation,
|
|
956
|
+
IWebSocketMemoryAugmentation,
|
|
957
|
+
IWebSocketPerceptionAugmentation,
|
|
958
|
+
IWebSocketDialogAugmentation,
|
|
959
|
+
IWebSocketActivationAugmentation,
|
|
960
|
+
|
|
961
|
+
// Function to add WebSocket support to any augmentation
|
|
962
|
+
addWebSocketSupport
|
|
930
963
|
} from '@soulcraft/brainy'
|
|
931
964
|
|
|
932
965
|
// Example: Creating a typed WebSocket-enabled sense augmentation
|
|
933
966
|
const mySenseAug = createSenseAugmentation({
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
967
|
+
name: 'my-sense',
|
|
968
|
+
processRawData: async (data, dataType) => {
|
|
969
|
+
// Implementation
|
|
970
|
+
return {
|
|
971
|
+
success: true,
|
|
972
|
+
data: {nouns: [], verbs: []}
|
|
973
|
+
}
|
|
940
974
|
}
|
|
941
|
-
}
|
|
942
975
|
}) as IWebSocketSenseAugmentation
|
|
943
976
|
|
|
944
977
|
// Add WebSocket support
|
|
945
978
|
addWebSocketSupport(mySenseAug, {
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
979
|
+
connectWebSocket: async (url) => {
|
|
980
|
+
// WebSocket implementation
|
|
981
|
+
return {
|
|
982
|
+
connectionId: 'ws-1',
|
|
983
|
+
url,
|
|
984
|
+
status: 'connected'
|
|
985
|
+
}
|
|
986
|
+
},
|
|
987
|
+
sendWebSocketMessage: async (connectionId, data) => {
|
|
988
|
+
// Send message implementation
|
|
989
|
+
},
|
|
990
|
+
onWebSocketMessage: async (connectionId, callback) => {
|
|
991
|
+
// Register callback implementation
|
|
992
|
+
},
|
|
993
|
+
offWebSocketMessage: async (connectionId, callback) => {
|
|
994
|
+
// Remove callback implementation
|
|
995
|
+
},
|
|
996
|
+
closeWebSocket: async (connectionId, code, reason) => {
|
|
997
|
+
// Close connection implementation
|
|
952
998
|
}
|
|
953
|
-
},
|
|
954
|
-
sendWebSocketMessage: async (connectionId, data) => {
|
|
955
|
-
// Send message implementation
|
|
956
|
-
},
|
|
957
|
-
onWebSocketMessage: async (connectionId, callback) => {
|
|
958
|
-
// Register callback implementation
|
|
959
|
-
},
|
|
960
|
-
offWebSocketMessage: async (connectionId, callback) => {
|
|
961
|
-
// Remove callback implementation
|
|
962
|
-
},
|
|
963
|
-
closeWebSocket: async (connectionId, code, reason) => {
|
|
964
|
-
// Close connection implementation
|
|
965
|
-
}
|
|
966
999
|
})
|
|
967
1000
|
|
|
968
1001
|
// Now mySenseAug has both sense augmentation methods and WebSocket methods
|
|
@@ -970,7 +1003,8 @@ await mySenseAug.processRawData('data', 'text')
|
|
|
970
1003
|
await mySenseAug.connectWebSocket('wss://example.com')
|
|
971
1004
|
```
|
|
972
1005
|
|
|
973
|
-
These WebSocket augmentation types combine the base augmentation interfaces with the `IWebSocketSupport` interface,
|
|
1006
|
+
These WebSocket augmentation types combine the base augmentation interfaces with the `IWebSocketSupport` interface,
|
|
1007
|
+
providing type safety and autocompletion for augmentations with WebSocket capabilities.
|
|
974
1008
|
|
|
975
1009
|
### Model Control Protocol (MCP)
|
|
976
1010
|
|
|
@@ -999,13 +1033,13 @@ everywhere.
|
|
|
999
1033
|
Brainy automatically detects the environment it's running in:
|
|
1000
1034
|
|
|
1001
1035
|
```typescript
|
|
1002
|
-
import {
|
|
1036
|
+
import {environment} from '@soulcraft/brainy'
|
|
1003
1037
|
|
|
1004
1038
|
// Check which environment we're running in
|
|
1005
1039
|
console.log(`Running in ${
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1040
|
+
environment.isBrowser ? 'browser' :
|
|
1041
|
+
environment.isNode ? 'Node.js' :
|
|
1042
|
+
'serverless/unknown'
|
|
1009
1043
|
} environment`)
|
|
1010
1044
|
```
|
|
1011
1045
|
|
|
@@ -1034,7 +1068,6 @@ Works in all modern browsers:
|
|
|
1034
1068
|
|
|
1035
1069
|
For browsers without OPFS support, falls back to in-memory storage.
|
|
1036
1070
|
|
|
1037
|
-
|
|
1038
1071
|
## Related Projects
|
|
1039
1072
|
|
|
1040
1073
|
- **[Cartographer](https://github.com/sodal-project/cartographer)** - A companion project that provides standardized
|
|
@@ -1079,9 +1112,9 @@ You can use the conduit augmentations to sync Brainy instances:
|
|
|
1079
1112
|
|
|
1080
1113
|
```typescript
|
|
1081
1114
|
import {
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1115
|
+
BrainyData,
|
|
1116
|
+
pipeline,
|
|
1117
|
+
createConduitAugmentation
|
|
1085
1118
|
} from '@soulcraft/brainy'
|
|
1086
1119
|
|
|
1087
1120
|
// Create and initialize the database
|
|
@@ -1097,36 +1130,36 @@ pipeline.register(wsConduit)
|
|
|
1097
1130
|
// Connect to another Brainy instance (server or browser)
|
|
1098
1131
|
// Replace the example URL below with your actual WebSocket server URL
|
|
1099
1132
|
const connectionResult = await pipeline.executeConduitPipeline(
|
|
1100
|
-
|
|
1101
|
-
|
|
1133
|
+
'establishConnection',
|
|
1134
|
+
['wss://example-websocket-server.com/brainy-sync', {protocols: 'brainy-sync'}]
|
|
1102
1135
|
)
|
|
1103
1136
|
|
|
1104
1137
|
if (connectionResult[0] && (await connectionResult[0]).success) {
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
}
|
|
1120
|
-
|
|
1121
|
-
// Set up real-time sync by monitoring the stream
|
|
1122
|
-
await wsConduit.monitorStream(connection.connectionId, async (data) => {
|
|
1123
|
-
// Handle incoming data (e.g., new nouns, verbs, updates)
|
|
1124
|
-
if (data.type === 'newNoun') {
|
|
1125
|
-
await db.add(data.vector, data.metadata)
|
|
1126
|
-
} else if (data.type === 'newVerb') {
|
|
1127
|
-
await db.addVerb(data.sourceId, data.targetId, data.vector, data.options)
|
|
1138
|
+
const connection = (await connectionResult[0]).data
|
|
1139
|
+
|
|
1140
|
+
// Read data from the remote instance
|
|
1141
|
+
const readResult = await pipeline.executeConduitPipeline(
|
|
1142
|
+
'readData',
|
|
1143
|
+
[{connectionId: connection.connectionId, query: {type: 'getAllNouns'}}]
|
|
1144
|
+
)
|
|
1145
|
+
|
|
1146
|
+
// Process and add the received data to the local instance
|
|
1147
|
+
if (readResult[0] && (await readResult[0]).success) {
|
|
1148
|
+
const remoteNouns = (await readResult[0]).data
|
|
1149
|
+
for (const noun of remoteNouns) {
|
|
1150
|
+
await db.add(noun.vector, noun.metadata)
|
|
1151
|
+
}
|
|
1128
1152
|
}
|
|
1129
|
-
|
|
1153
|
+
|
|
1154
|
+
// Set up real-time sync by monitoring the stream
|
|
1155
|
+
await wsConduit.monitorStream(connection.connectionId, async (data) => {
|
|
1156
|
+
// Handle incoming data (e.g., new nouns, verbs, updates)
|
|
1157
|
+
if (data.type === 'newNoun') {
|
|
1158
|
+
await db.add(data.vector, data.metadata)
|
|
1159
|
+
} else if (data.type === 'newVerb') {
|
|
1160
|
+
await db.addVerb(data.sourceId, data.targetId, data.vector, data.options)
|
|
1161
|
+
}
|
|
1162
|
+
})
|
|
1130
1163
|
}
|
|
1131
1164
|
```
|
|
1132
1165
|
|
|
@@ -1134,9 +1167,9 @@ if (connectionResult[0] && (await connectionResult[0]).success) {
|
|
|
1134
1167
|
|
|
1135
1168
|
```typescript
|
|
1136
1169
|
import {
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1170
|
+
BrainyData,
|
|
1171
|
+
pipeline,
|
|
1172
|
+
createConduitAugmentation
|
|
1140
1173
|
} from '@soulcraft/brainy'
|
|
1141
1174
|
|
|
1142
1175
|
// Create and initialize the database
|
|
@@ -1152,48 +1185,48 @@ pipeline.register(webrtcConduit)
|
|
|
1152
1185
|
// Connect to a peer using a signaling server
|
|
1153
1186
|
// Replace the example values below with your actual configuration
|
|
1154
1187
|
const connectionResult = await pipeline.executeConduitPipeline(
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1188
|
+
'establishConnection',
|
|
1189
|
+
[
|
|
1190
|
+
'peer-id-to-connect-to', // Replace with actual peer ID
|
|
1191
|
+
{
|
|
1192
|
+
signalServerUrl: 'wss://example-signal-server.com', // Replace with your signal server
|
|
1193
|
+
localPeerId: 'my-local-peer-id', // Replace with your local peer ID
|
|
1194
|
+
iceServers: [{urls: 'stun:stun.l.google.com:19302'}] // Public STUN server
|
|
1195
|
+
}
|
|
1196
|
+
]
|
|
1164
1197
|
)
|
|
1165
1198
|
|
|
1166
1199
|
if (connectionResult[0] && (await connectionResult[0]).success) {
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
}
|
|
1177
|
-
})
|
|
1178
|
-
|
|
1179
|
-
// When adding new data locally, also send to the peer
|
|
1180
|
-
const nounId = await db.add("New data to sync", { noun: "Thing" })
|
|
1181
|
-
|
|
1182
|
-
// Send the new noun to the peer
|
|
1183
|
-
await pipeline.executeConduitPipeline(
|
|
1184
|
-
'writeData',
|
|
1185
|
-
[
|
|
1186
|
-
{
|
|
1187
|
-
connectionId: connection.connectionId,
|
|
1188
|
-
data: {
|
|
1189
|
-
type: 'newNoun',
|
|
1190
|
-
id: nounId,
|
|
1191
|
-
vector: (await db.get(nounId)).vector,
|
|
1192
|
-
metadata: (await db.get(nounId)).metadata
|
|
1200
|
+
const connection = (await connectionResult[0]).data
|
|
1201
|
+
|
|
1202
|
+
// Set up real-time sync by monitoring the stream
|
|
1203
|
+
await webrtcConduit.monitorStream(connection.connectionId, async (data) => {
|
|
1204
|
+
// Handle incoming data (e.g., new nouns, verbs, updates)
|
|
1205
|
+
if (data.type === 'newNoun') {
|
|
1206
|
+
await db.add(data.vector, data.metadata)
|
|
1207
|
+
} else if (data.type === 'newVerb') {
|
|
1208
|
+
await db.addVerb(data.sourceId, data.targetId, data.vector, data.options)
|
|
1193
1209
|
}
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1210
|
+
})
|
|
1211
|
+
|
|
1212
|
+
// When adding new data locally, also send to the peer
|
|
1213
|
+
const nounId = await db.add("New data to sync", {noun: "Thing"})
|
|
1214
|
+
|
|
1215
|
+
// Send the new noun to the peer
|
|
1216
|
+
await pipeline.executeConduitPipeline(
|
|
1217
|
+
'writeData',
|
|
1218
|
+
[
|
|
1219
|
+
{
|
|
1220
|
+
connectionId: connection.connectionId,
|
|
1221
|
+
data: {
|
|
1222
|
+
type: 'newNoun',
|
|
1223
|
+
id: nounId,
|
|
1224
|
+
vector: (await db.get(nounId)).vector,
|
|
1225
|
+
metadata: (await db.get(nounId)).metadata
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
]
|
|
1229
|
+
)
|
|
1197
1230
|
}
|
|
1198
1231
|
```
|
|
1199
1232
|
|
|
@@ -1203,39 +1236,39 @@ Brainy supports searching a server-hosted instance from a browser, storing resul
|
|
|
1203
1236
|
searches against the local instance:
|
|
1204
1237
|
|
|
1205
1238
|
```typescript
|
|
1206
|
-
import {
|
|
1239
|
+
import {BrainyData} from '@soulcraft/brainy'
|
|
1207
1240
|
|
|
1208
1241
|
// Create and initialize the database with remote server configuration
|
|
1209
1242
|
// Replace the example URL below with your actual Brainy server URL
|
|
1210
1243
|
const db = new BrainyData({
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1244
|
+
remoteServer: {
|
|
1245
|
+
url: 'wss://example-brainy-server.com/ws', // Replace with your server URL
|
|
1246
|
+
protocols: 'brainy-sync',
|
|
1247
|
+
autoConnect: true // Connect automatically during initialization
|
|
1248
|
+
}
|
|
1216
1249
|
})
|
|
1217
1250
|
await db.init()
|
|
1218
1251
|
|
|
1219
1252
|
// Or connect manually after initialization
|
|
1220
1253
|
if (!db.isConnectedToRemoteServer()) {
|
|
1221
|
-
|
|
1222
|
-
|
|
1254
|
+
// Replace the example URL below with your actual Brainy server URL
|
|
1255
|
+
await db.connectToRemoteServer('wss://example-brainy-server.com/ws', 'brainy-sync')
|
|
1223
1256
|
}
|
|
1224
1257
|
|
|
1225
1258
|
// Search the remote server (results are stored locally)
|
|
1226
|
-
const remoteResults = await db.searchText('machine learning', 5, {
|
|
1259
|
+
const remoteResults = await db.searchText('machine learning', 5, {searchMode: 'remote'})
|
|
1227
1260
|
|
|
1228
1261
|
// Search the local database (includes previously stored results)
|
|
1229
|
-
const localResults = await db.searchText('machine learning', 5, {
|
|
1262
|
+
const localResults = await db.searchText('machine learning', 5, {searchMode: 'local'})
|
|
1230
1263
|
|
|
1231
1264
|
// Perform a combined search (local first, then remote if needed)
|
|
1232
|
-
const combinedResults = await db.searchText('neural networks', 5, {
|
|
1265
|
+
const combinedResults = await db.searchText('neural networks', 5, {searchMode: 'combined'})
|
|
1233
1266
|
|
|
1234
1267
|
// Add data to both local and remote instances
|
|
1235
1268
|
const id = await db.addToBoth('Deep learning is a subset of machine learning', {
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1269
|
+
noun: 'Concept',
|
|
1270
|
+
category: 'AI',
|
|
1271
|
+
tags: ['deep learning', 'neural networks']
|
|
1239
1272
|
})
|
|
1240
1273
|
|
|
1241
1274
|
// Clean up when done (this also cleans up worker pools)
|