@soulcraft/brainy 3.9.0 → 3.10.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 +89 -33
- package/dist/augmentations/KnowledgeAugmentation.d.ts +40 -0
- package/dist/augmentations/KnowledgeAugmentation.js +251 -0
- package/dist/augmentations/defaultAugmentations.d.ts +1 -0
- package/dist/augmentations/defaultAugmentations.js +5 -0
- package/dist/brainy.d.ts +11 -0
- package/dist/brainy.js +87 -1
- package/dist/embeddings/EmbeddingManager.js +14 -2
- package/dist/utils/mutex.d.ts +2 -0
- package/dist/utils/mutex.js +14 -3
- package/dist/vfs/ConceptSystem.d.ts +202 -0
- package/dist/vfs/ConceptSystem.js +598 -0
- package/dist/vfs/EntityManager.d.ts +75 -0
- package/dist/vfs/EntityManager.js +216 -0
- package/dist/vfs/EventRecorder.d.ts +83 -0
- package/dist/vfs/EventRecorder.js +292 -0
- package/dist/vfs/FSCompat.d.ts +85 -0
- package/dist/vfs/FSCompat.js +257 -0
- package/dist/vfs/GitBridge.d.ts +167 -0
- package/dist/vfs/GitBridge.js +537 -0
- package/dist/vfs/KnowledgeAugmentation.d.ts +104 -0
- package/dist/vfs/KnowledgeAugmentation.js +146 -0
- package/dist/vfs/KnowledgeLayer.d.ts +35 -0
- package/dist/vfs/KnowledgeLayer.js +443 -0
- package/dist/vfs/PathResolver.d.ts +96 -0
- package/dist/vfs/PathResolver.js +362 -0
- package/dist/vfs/PersistentEntitySystem.d.ts +163 -0
- package/dist/vfs/PersistentEntitySystem.js +525 -0
- package/dist/vfs/SemanticVersioning.d.ts +105 -0
- package/dist/vfs/SemanticVersioning.js +318 -0
- package/dist/vfs/VirtualFileSystem.d.ts +246 -0
- package/dist/vfs/VirtualFileSystem.js +1927 -0
- package/dist/vfs/importers/DirectoryImporter.d.ts +86 -0
- package/dist/vfs/importers/DirectoryImporter.js +298 -0
- package/dist/vfs/index.d.ts +19 -0
- package/dist/vfs/index.js +26 -0
- package/dist/vfs/streams/VFSReadStream.d.ts +19 -0
- package/dist/vfs/streams/VFSReadStream.js +54 -0
- package/dist/vfs/streams/VFSWriteStream.d.ts +21 -0
- package/dist/vfs/streams/VFSWriteStream.js +70 -0
- package/dist/vfs/types.d.ts +330 -0
- package/dist/vfs/types.js +46 -0
- package/package.json +1 -1
package/dist/brainy.js
CHANGED
|
@@ -14,6 +14,7 @@ import { createDefaultAugmentations } from './augmentations/defaultAugmentations
|
|
|
14
14
|
import { ImprovedNeuralAPI } from './neural/improvedNeuralAPI.js';
|
|
15
15
|
import { NaturalLanguageProcessor } from './neural/naturalLanguageProcessor.js';
|
|
16
16
|
import { TripleIntelligenceSystem } from './triple/TripleIntelligenceSystem.js';
|
|
17
|
+
import { VirtualFileSystem } from './vfs/VirtualFileSystem.js';
|
|
17
18
|
import { MetadataIndexManager } from './utils/metadataIndex.js';
|
|
18
19
|
import { GraphAdjacencyIndex } from './graph/graphAdjacencyIndex.js';
|
|
19
20
|
import { createPipeline } from './streaming/pipeline.js';
|
|
@@ -138,6 +139,12 @@ export class Brainy {
|
|
|
138
139
|
throw new Error('Brainy not initialized. Call init() first.');
|
|
139
140
|
}
|
|
140
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Check if Brainy is initialized
|
|
144
|
+
*/
|
|
145
|
+
get isInitialized() {
|
|
146
|
+
return this.initialized;
|
|
147
|
+
}
|
|
141
148
|
// ============= CORE CRUD OPERATIONS =============
|
|
142
149
|
/**
|
|
143
150
|
* Add an entity to the database
|
|
@@ -895,6 +902,15 @@ export class Brainy {
|
|
|
895
902
|
}
|
|
896
903
|
return this._nlp;
|
|
897
904
|
}
|
|
905
|
+
/**
|
|
906
|
+
* Virtual File System API - Knowledge Operating System
|
|
907
|
+
*/
|
|
908
|
+
vfs() {
|
|
909
|
+
if (!this._vfs) {
|
|
910
|
+
this._vfs = new VirtualFileSystem(this);
|
|
911
|
+
}
|
|
912
|
+
return this._vfs;
|
|
913
|
+
}
|
|
898
914
|
/**
|
|
899
915
|
* Data Management API - backup, restore, import, export
|
|
900
916
|
*/
|
|
@@ -1448,9 +1464,79 @@ export class Brainy {
|
|
|
1448
1464
|
}
|
|
1449
1465
|
/**
|
|
1450
1466
|
* Embed data into vector
|
|
1467
|
+
* Handles any data type by converting to string representation
|
|
1451
1468
|
*/
|
|
1452
1469
|
async embed(data) {
|
|
1453
|
-
|
|
1470
|
+
// Handle different data types intelligently
|
|
1471
|
+
let textToEmbed;
|
|
1472
|
+
if (typeof data === 'string') {
|
|
1473
|
+
textToEmbed = data;
|
|
1474
|
+
}
|
|
1475
|
+
else if (Array.isArray(data)) {
|
|
1476
|
+
// Array of items - convert each to string
|
|
1477
|
+
textToEmbed = data.map(item => {
|
|
1478
|
+
if (typeof item === 'string')
|
|
1479
|
+
return item;
|
|
1480
|
+
if (typeof item === 'number' || typeof item === 'boolean')
|
|
1481
|
+
return String(item);
|
|
1482
|
+
if (item && typeof item === 'object') {
|
|
1483
|
+
// For objects, try to extract meaningful text
|
|
1484
|
+
if (item.data)
|
|
1485
|
+
return String(item.data);
|
|
1486
|
+
if (item.content)
|
|
1487
|
+
return String(item.content);
|
|
1488
|
+
if (item.text)
|
|
1489
|
+
return String(item.text);
|
|
1490
|
+
if (item.name)
|
|
1491
|
+
return String(item.name);
|
|
1492
|
+
if (item.title)
|
|
1493
|
+
return String(item.title);
|
|
1494
|
+
if (item.description)
|
|
1495
|
+
return String(item.description);
|
|
1496
|
+
// Fallback to JSON for complex objects
|
|
1497
|
+
try {
|
|
1498
|
+
return JSON.stringify(item);
|
|
1499
|
+
}
|
|
1500
|
+
catch {
|
|
1501
|
+
return String(item);
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
return String(item);
|
|
1505
|
+
});
|
|
1506
|
+
}
|
|
1507
|
+
else if (data && typeof data === 'object') {
|
|
1508
|
+
// Single object - extract meaningful text
|
|
1509
|
+
if (data.data)
|
|
1510
|
+
textToEmbed = String(data.data);
|
|
1511
|
+
else if (data.content)
|
|
1512
|
+
textToEmbed = String(data.content);
|
|
1513
|
+
else if (data.text)
|
|
1514
|
+
textToEmbed = String(data.text);
|
|
1515
|
+
else if (data.name)
|
|
1516
|
+
textToEmbed = String(data.name);
|
|
1517
|
+
else if (data.title)
|
|
1518
|
+
textToEmbed = String(data.title);
|
|
1519
|
+
else if (data.description)
|
|
1520
|
+
textToEmbed = String(data.description);
|
|
1521
|
+
else {
|
|
1522
|
+
// For complex objects, create a descriptive string
|
|
1523
|
+
try {
|
|
1524
|
+
textToEmbed = JSON.stringify(data);
|
|
1525
|
+
}
|
|
1526
|
+
catch {
|
|
1527
|
+
textToEmbed = String(data);
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
else if (data === null || data === undefined) {
|
|
1532
|
+
// Handle null/undefined gracefully
|
|
1533
|
+
textToEmbed = '';
|
|
1534
|
+
}
|
|
1535
|
+
else {
|
|
1536
|
+
// Numbers, booleans, etc - convert to string
|
|
1537
|
+
textToEmbed = String(data);
|
|
1538
|
+
}
|
|
1539
|
+
return this.embedder(textToEmbed);
|
|
1454
1540
|
}
|
|
1455
1541
|
/**
|
|
1456
1542
|
* Warm up the system
|
|
@@ -165,8 +165,20 @@ export class EmbeddingManager {
|
|
|
165
165
|
if (!this.model) {
|
|
166
166
|
throw new Error('Model not initialized');
|
|
167
167
|
}
|
|
168
|
-
//
|
|
169
|
-
|
|
168
|
+
// CRITICAL FIX: Ensure input is always a string
|
|
169
|
+
let input;
|
|
170
|
+
if (Array.isArray(text)) {
|
|
171
|
+
// Join array elements, converting each to string first
|
|
172
|
+
input = text.map(t => typeof t === 'string' ? t : String(t)).join(' ');
|
|
173
|
+
}
|
|
174
|
+
else if (typeof text === 'string') {
|
|
175
|
+
input = text;
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
// This shouldn't happen but let's be defensive
|
|
179
|
+
console.warn('EmbeddingManager.embed received non-string input:', typeof text);
|
|
180
|
+
input = String(text);
|
|
181
|
+
}
|
|
170
182
|
// Generate embedding
|
|
171
183
|
const output = await this.model(input, {
|
|
172
184
|
pooling: 'mean',
|
package/dist/utils/mutex.d.ts
CHANGED
|
@@ -29,7 +29,9 @@ export declare class FileMutex implements MutexInterface {
|
|
|
29
29
|
private lockDir;
|
|
30
30
|
private processLocks;
|
|
31
31
|
private lockTimers;
|
|
32
|
+
private modulesLoaded;
|
|
32
33
|
constructor(lockDir: string);
|
|
34
|
+
private loadNodeModules;
|
|
33
35
|
acquire(key: string, timeout?: number): Promise<() => void>;
|
|
34
36
|
private release;
|
|
35
37
|
runExclusive<T>(key: string, fn: () => Promise<T>, timeout?: number): Promise<T>;
|
package/dist/utils/mutex.js
CHANGED
|
@@ -74,14 +74,25 @@ export class FileMutex {
|
|
|
74
74
|
constructor(lockDir) {
|
|
75
75
|
this.processLocks = new Map();
|
|
76
76
|
this.lockTimers = new Map();
|
|
77
|
+
this.modulesLoaded = false;
|
|
77
78
|
this.lockDir = lockDir;
|
|
78
|
-
|
|
79
|
+
}
|
|
80
|
+
async loadNodeModules() {
|
|
81
|
+
if (this.modulesLoaded)
|
|
82
|
+
return;
|
|
79
83
|
if (typeof window === 'undefined') {
|
|
80
|
-
|
|
81
|
-
|
|
84
|
+
// Modern ESM-compatible dynamic imports
|
|
85
|
+
const [fs, path] = await Promise.all([
|
|
86
|
+
import('fs'),
|
|
87
|
+
import('path')
|
|
88
|
+
]);
|
|
89
|
+
this.fs = fs;
|
|
90
|
+
this.path = path;
|
|
91
|
+
this.modulesLoaded = true;
|
|
82
92
|
}
|
|
83
93
|
}
|
|
84
94
|
async acquire(key, timeout = 30000) {
|
|
95
|
+
await this.loadNodeModules();
|
|
85
96
|
if (!this.fs || !this.path) {
|
|
86
97
|
throw new Error('FileMutex is only available in Node.js environments');
|
|
87
98
|
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal Concept System for VFS
|
|
3
|
+
*
|
|
4
|
+
* Manages concepts that transcend files and exist independently
|
|
5
|
+
* Ideas that can be linked to multiple manifestations across domains
|
|
6
|
+
* PRODUCTION-READY: Real implementation using Brainy
|
|
7
|
+
*/
|
|
8
|
+
import { Brainy } from '../brainy.js';
|
|
9
|
+
/**
|
|
10
|
+
* Universal concept that exists independently of files
|
|
11
|
+
*/
|
|
12
|
+
export interface UniversalConcept {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
domain: string;
|
|
17
|
+
category: string;
|
|
18
|
+
keywords: string[];
|
|
19
|
+
links: ConceptLink[];
|
|
20
|
+
manifestations: ConceptManifestation[];
|
|
21
|
+
strength: number;
|
|
22
|
+
created: number;
|
|
23
|
+
lastUpdated: number;
|
|
24
|
+
version: number;
|
|
25
|
+
metadata: Record<string, any>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A link between concepts
|
|
29
|
+
*/
|
|
30
|
+
export interface ConceptLink {
|
|
31
|
+
id: string;
|
|
32
|
+
targetConceptId: string;
|
|
33
|
+
relationship: 'extends' | 'implements' | 'uses' | 'opposite' | 'related' | 'contains' | 'part-of';
|
|
34
|
+
strength: number;
|
|
35
|
+
context?: string;
|
|
36
|
+
bidirectional: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A manifestation of a concept in a specific location
|
|
40
|
+
*/
|
|
41
|
+
export interface ConceptManifestation {
|
|
42
|
+
id: string;
|
|
43
|
+
conceptId: string;
|
|
44
|
+
filePath: string;
|
|
45
|
+
context: string;
|
|
46
|
+
form: 'definition' | 'usage' | 'example' | 'discussion' | 'implementation';
|
|
47
|
+
position?: {
|
|
48
|
+
line?: number;
|
|
49
|
+
column?: number;
|
|
50
|
+
offset?: number;
|
|
51
|
+
};
|
|
52
|
+
confidence: number;
|
|
53
|
+
timestamp: number;
|
|
54
|
+
extractedBy: 'manual' | 'auto' | 'ai';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Configuration for concept system
|
|
58
|
+
*/
|
|
59
|
+
export interface ConceptSystemConfig {
|
|
60
|
+
autoLink?: boolean;
|
|
61
|
+
similarityThreshold?: number;
|
|
62
|
+
maxManifestations?: number;
|
|
63
|
+
strengthDecay?: number;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Concept graph structure for visualization
|
|
67
|
+
*/
|
|
68
|
+
export interface ConceptGraph {
|
|
69
|
+
concepts: Array<{
|
|
70
|
+
id: string;
|
|
71
|
+
name: string;
|
|
72
|
+
domain: string;
|
|
73
|
+
strength: number;
|
|
74
|
+
manifestationCount: number;
|
|
75
|
+
}>;
|
|
76
|
+
links: Array<{
|
|
77
|
+
source: string;
|
|
78
|
+
target: string;
|
|
79
|
+
relationship: string;
|
|
80
|
+
strength: number;
|
|
81
|
+
}>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Universal Concept System
|
|
85
|
+
*
|
|
86
|
+
* Manages concepts that exist independently of any specific file or context
|
|
87
|
+
* Examples:
|
|
88
|
+
* - "Authentication" concept appearing in docs, code, tests
|
|
89
|
+
* - "Customer Journey" concept in marketing, UX, analytics
|
|
90
|
+
* - "Dependency Injection" pattern across multiple codebases
|
|
91
|
+
* - "Sustainability" theme in various research papers
|
|
92
|
+
*/
|
|
93
|
+
export declare class ConceptSystem {
|
|
94
|
+
private brain;
|
|
95
|
+
private config;
|
|
96
|
+
private conceptCache;
|
|
97
|
+
constructor(brain: Brainy, config?: ConceptSystemConfig);
|
|
98
|
+
/**
|
|
99
|
+
* Create a new universal concept
|
|
100
|
+
*/
|
|
101
|
+
createConcept(concept: Omit<UniversalConcept, 'id' | 'created' | 'lastUpdated' | 'version' | 'links' | 'manifestations'>): Promise<string>;
|
|
102
|
+
/**
|
|
103
|
+
* Find concepts by various criteria
|
|
104
|
+
*/
|
|
105
|
+
findConcepts(query: {
|
|
106
|
+
name?: string;
|
|
107
|
+
domain?: string;
|
|
108
|
+
category?: string;
|
|
109
|
+
keywords?: string[];
|
|
110
|
+
similar?: string;
|
|
111
|
+
manifestedIn?: string;
|
|
112
|
+
}): Promise<UniversalConcept[]>;
|
|
113
|
+
/**
|
|
114
|
+
* Link two concepts together
|
|
115
|
+
*/
|
|
116
|
+
linkConcept(fromConceptId: string, toConceptId: string, relationship: ConceptLink['relationship'], options?: {
|
|
117
|
+
strength?: number;
|
|
118
|
+
context?: string;
|
|
119
|
+
bidirectional?: boolean;
|
|
120
|
+
}): Promise<string>;
|
|
121
|
+
/**
|
|
122
|
+
* Record a manifestation of a concept in a file
|
|
123
|
+
*/
|
|
124
|
+
recordManifestation(conceptId: string, filePath: string, context: string, form: ConceptManifestation['form'], options?: {
|
|
125
|
+
position?: ConceptManifestation['position'];
|
|
126
|
+
confidence?: number;
|
|
127
|
+
extractedBy?: ConceptManifestation['extractedBy'];
|
|
128
|
+
}): Promise<string>;
|
|
129
|
+
/**
|
|
130
|
+
* Extract and link concepts from content
|
|
131
|
+
*/
|
|
132
|
+
extractAndLinkConcepts(filePath: string, content: Buffer): Promise<string[]>;
|
|
133
|
+
/**
|
|
134
|
+
* Get concept graph for visualization
|
|
135
|
+
*/
|
|
136
|
+
getConceptGraph(options?: {
|
|
137
|
+
domain?: string;
|
|
138
|
+
minStrength?: number;
|
|
139
|
+
maxConcepts?: number;
|
|
140
|
+
}): Promise<ConceptGraph>;
|
|
141
|
+
/**
|
|
142
|
+
* Find appearances of a concept
|
|
143
|
+
*/
|
|
144
|
+
findAppearances(conceptId: string, options?: {
|
|
145
|
+
filePath?: string;
|
|
146
|
+
form?: ConceptManifestation['form'];
|
|
147
|
+
minConfidence?: number;
|
|
148
|
+
limit?: number;
|
|
149
|
+
}): Promise<ConceptManifestation[]>;
|
|
150
|
+
/**
|
|
151
|
+
* Auto-link concept to similar concepts
|
|
152
|
+
*/
|
|
153
|
+
private autoLinkConcept;
|
|
154
|
+
/**
|
|
155
|
+
* Get concept by ID
|
|
156
|
+
*/
|
|
157
|
+
private getConcept;
|
|
158
|
+
/**
|
|
159
|
+
* Update stored concept
|
|
160
|
+
*/
|
|
161
|
+
private updateConcept;
|
|
162
|
+
/**
|
|
163
|
+
* Calculate similarity between two concepts
|
|
164
|
+
*/
|
|
165
|
+
private calculateConceptSimilarity;
|
|
166
|
+
/**
|
|
167
|
+
* Generate embedding for concept
|
|
168
|
+
*/
|
|
169
|
+
private generateConceptEmbedding;
|
|
170
|
+
/**
|
|
171
|
+
* Generate embedding for text
|
|
172
|
+
*/
|
|
173
|
+
private generateTextEmbedding;
|
|
174
|
+
/**
|
|
175
|
+
* Get reverse relationship type
|
|
176
|
+
*/
|
|
177
|
+
private getReverseRelationship;
|
|
178
|
+
/**
|
|
179
|
+
* Map concept relationship to VerbType
|
|
180
|
+
*/
|
|
181
|
+
private getVerbType;
|
|
182
|
+
/**
|
|
183
|
+
* Detect concept domain from context
|
|
184
|
+
*/
|
|
185
|
+
private detectDomain;
|
|
186
|
+
/**
|
|
187
|
+
* Detect concept category
|
|
188
|
+
*/
|
|
189
|
+
private detectCategory;
|
|
190
|
+
/**
|
|
191
|
+
* Detect manifestation form from context
|
|
192
|
+
*/
|
|
193
|
+
private detectManifestationForm;
|
|
194
|
+
/**
|
|
195
|
+
* Extract context around a position
|
|
196
|
+
*/
|
|
197
|
+
private extractContext;
|
|
198
|
+
/**
|
|
199
|
+
* Clear concept cache
|
|
200
|
+
*/
|
|
201
|
+
clearCache(conceptId?: string): void;
|
|
202
|
+
}
|