@soulcraft/brainy 1.2.0 → 1.4.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 +6 -8
- package/dist/brainyData.d.ts +5 -2
- package/dist/brainyData.js +86 -32
- package/dist/critical/model-guardian.d.ts +56 -0
- package/dist/critical/model-guardian.js +238 -0
- package/dist/embeddings/model-manager.d.ts +27 -0
- package/dist/embeddings/model-manager.js +189 -0
- package/dist/intelligence/neuralEngine.d.ts +207 -0
- package/dist/intelligence/neuralEngine.js +706 -0
- package/dist/utils/embedding.d.ts +2 -1
- package/dist/utils/embedding.js +9 -3
- package/dist/utils/hybridModelManager.d.ts +73 -0
- package/dist/utils/hybridModelManager.js +254 -0
- package/dist/utils/modelLoader.d.ts +32 -0
- package/dist/utils/modelLoader.js +219 -0
- package/dist/utils/modelManager.d.ts +77 -0
- package/dist/utils/modelManager.js +219 -0
- package/package.json +5 -2
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model Manager - Ensures transformer models are available at runtime
|
|
3
|
+
*
|
|
4
|
+
* Strategy:
|
|
5
|
+
* 1. Check local cache first
|
|
6
|
+
* 2. Try GitHub releases (our backup)
|
|
7
|
+
* 3. Fall back to Hugging Face
|
|
8
|
+
* 4. Future: CDN at models.soulcraft.com
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync } from 'fs';
|
|
11
|
+
import { join, dirname } from 'path';
|
|
12
|
+
import { env } from '@huggingface/transformers';
|
|
13
|
+
// Model sources in order of preference
|
|
14
|
+
const MODEL_SOURCES = {
|
|
15
|
+
// GitHub Release - our controlled backup
|
|
16
|
+
github: 'https://github.com/soulcraftlabs/brainy/releases/download/models-v1/all-MiniLM-L6-v2.tar.gz',
|
|
17
|
+
// Future CDN - fastest option when available
|
|
18
|
+
cdn: 'https://models.soulcraft.com/brainy/all-MiniLM-L6-v2.tar.gz',
|
|
19
|
+
// Original Hugging Face - fallback
|
|
20
|
+
huggingface: 'default' // Uses transformers.js default
|
|
21
|
+
};
|
|
22
|
+
// Expected model files and their hashes
|
|
23
|
+
const MODEL_MANIFEST = {
|
|
24
|
+
'Xenova/all-MiniLM-L6-v2': {
|
|
25
|
+
files: {
|
|
26
|
+
'onnx/model.onnx': {
|
|
27
|
+
size: 90555481,
|
|
28
|
+
sha256: null // Will be computed from actual model
|
|
29
|
+
},
|
|
30
|
+
'tokenizer.json': {
|
|
31
|
+
size: 711661,
|
|
32
|
+
sha256: null
|
|
33
|
+
},
|
|
34
|
+
'config.json': {
|
|
35
|
+
size: 650,
|
|
36
|
+
sha256: null
|
|
37
|
+
},
|
|
38
|
+
'tokenizer_config.json': {
|
|
39
|
+
size: 366,
|
|
40
|
+
sha256: null
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
export class ModelManager {
|
|
46
|
+
constructor() {
|
|
47
|
+
this.isInitialized = false;
|
|
48
|
+
// Determine models path
|
|
49
|
+
this.modelsPath = this.getModelsPath();
|
|
50
|
+
}
|
|
51
|
+
static getInstance() {
|
|
52
|
+
if (!ModelManager.instance) {
|
|
53
|
+
ModelManager.instance = new ModelManager();
|
|
54
|
+
}
|
|
55
|
+
return ModelManager.instance;
|
|
56
|
+
}
|
|
57
|
+
getModelsPath() {
|
|
58
|
+
// Check various possible locations
|
|
59
|
+
const paths = [
|
|
60
|
+
process.env.BRAINY_MODELS_PATH,
|
|
61
|
+
'./models',
|
|
62
|
+
join(process.cwd(), 'models'),
|
|
63
|
+
join(process.env.HOME || '', '.brainy', 'models'),
|
|
64
|
+
env.cacheDir
|
|
65
|
+
];
|
|
66
|
+
// Find first existing path or use default
|
|
67
|
+
for (const path of paths) {
|
|
68
|
+
if (path && existsSync(path)) {
|
|
69
|
+
return path;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Default to local models directory
|
|
73
|
+
return join(process.cwd(), 'models');
|
|
74
|
+
}
|
|
75
|
+
async ensureModels(modelName = 'Xenova/all-MiniLM-L6-v2') {
|
|
76
|
+
if (this.isInitialized) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
const modelPath = join(this.modelsPath, ...modelName.split('/'));
|
|
80
|
+
// Check if model already exists locally
|
|
81
|
+
if (await this.verifyModelFiles(modelPath, modelName)) {
|
|
82
|
+
console.log('✅ Models found in cache:', modelPath);
|
|
83
|
+
this.configureTransformers(modelPath);
|
|
84
|
+
this.isInitialized = true;
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
// Try to download from our sources
|
|
88
|
+
console.log('📥 Downloading transformer models...');
|
|
89
|
+
// Try GitHub first (our backup)
|
|
90
|
+
if (await this.downloadFromGitHub(modelName)) {
|
|
91
|
+
this.isInitialized = true;
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
// Try CDN (when available)
|
|
95
|
+
if (await this.downloadFromCDN(modelName)) {
|
|
96
|
+
this.isInitialized = true;
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
// Fall back to Hugging Face (default transformers.js behavior)
|
|
100
|
+
console.log('⚠️ Using Hugging Face fallback for models');
|
|
101
|
+
env.allowRemoteModels = true;
|
|
102
|
+
this.isInitialized = true;
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
async verifyModelFiles(modelPath, modelName) {
|
|
106
|
+
const manifest = MODEL_MANIFEST[modelName];
|
|
107
|
+
if (!manifest)
|
|
108
|
+
return false;
|
|
109
|
+
for (const [filePath, info] of Object.entries(manifest.files)) {
|
|
110
|
+
const fullPath = join(modelPath, filePath);
|
|
111
|
+
if (!existsSync(fullPath)) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
// Optionally verify size
|
|
115
|
+
if (process.env.VERIFY_MODEL_SIZE === 'true') {
|
|
116
|
+
const stats = await import('fs').then(fs => fs.promises.stat(fullPath));
|
|
117
|
+
if (stats.size !== info.size) {
|
|
118
|
+
console.warn(`⚠️ Model file size mismatch: ${filePath}`);
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
async downloadFromGitHub(modelName) {
|
|
126
|
+
try {
|
|
127
|
+
const url = MODEL_SOURCES.github;
|
|
128
|
+
console.log('📥 Downloading from GitHub releases...');
|
|
129
|
+
// Download tar.gz file
|
|
130
|
+
const response = await fetch(url);
|
|
131
|
+
if (!response.ok) {
|
|
132
|
+
throw new Error(`GitHub download failed: ${response.status}`);
|
|
133
|
+
}
|
|
134
|
+
const buffer = await response.arrayBuffer();
|
|
135
|
+
// Extract tar.gz (would need tar library in production)
|
|
136
|
+
// For now, return false to fall back to other methods
|
|
137
|
+
console.log('⚠️ GitHub model extraction not yet implemented');
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.log('⚠️ GitHub download failed:', error.message);
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
async downloadFromCDN(modelName) {
|
|
146
|
+
try {
|
|
147
|
+
const url = MODEL_SOURCES.cdn;
|
|
148
|
+
console.log('📥 Downloading from Soulcraft CDN...');
|
|
149
|
+
// Try to fetch from CDN
|
|
150
|
+
const response = await fetch(url);
|
|
151
|
+
if (!response.ok) {
|
|
152
|
+
throw new Error(`CDN download failed: ${response.status}`);
|
|
153
|
+
}
|
|
154
|
+
// Would extract files here
|
|
155
|
+
console.log('⚠️ CDN not yet available');
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
console.log('⚠️ CDN download failed:', error.message);
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
configureTransformers(modelPath) {
|
|
164
|
+
// Configure transformers.js to use our local models
|
|
165
|
+
env.localModelPath = dirname(modelPath);
|
|
166
|
+
env.allowRemoteModels = false;
|
|
167
|
+
console.log('🔧 Configured transformers.js to use local models');
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Pre-download models for deployment
|
|
171
|
+
* This is what npm run download-models calls
|
|
172
|
+
*/
|
|
173
|
+
static async predownload() {
|
|
174
|
+
const manager = ModelManager.getInstance();
|
|
175
|
+
const success = await manager.ensureModels();
|
|
176
|
+
if (!success) {
|
|
177
|
+
throw new Error('Failed to download models');
|
|
178
|
+
}
|
|
179
|
+
console.log('✅ Models downloaded successfully');
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Auto-initialize on import in production
|
|
183
|
+
if (process.env.NODE_ENV === 'production' && process.env.SKIP_MODEL_CHECK !== 'true') {
|
|
184
|
+
ModelManager.getInstance().ensureModels().catch(error => {
|
|
185
|
+
console.error('⚠️ Model initialization failed:', error);
|
|
186
|
+
// Don't throw - allow app to start and try downloading on first use
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=model-manager.js.map
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Neural Detection Engine - Shared AI Intelligence Infrastructure
|
|
3
|
+
*
|
|
4
|
+
* 🧠 Consolidates all neural analysis capabilities for consistent intelligence across Brainy
|
|
5
|
+
* ⚛️ Replaces basic heuristics with sophisticated semantic analysis
|
|
6
|
+
*
|
|
7
|
+
* This engine provides the core AI capabilities that power:
|
|
8
|
+
* - Smart entity type detection
|
|
9
|
+
* - Intelligent relationship inference
|
|
10
|
+
* - Data quality assessment
|
|
11
|
+
* - Impact analysis for operations
|
|
12
|
+
* - Pattern recognition and insights
|
|
13
|
+
*/
|
|
14
|
+
import { BrainyData } from '../brainyData.js';
|
|
15
|
+
import { NounType, VerbType } from '../types/graphTypes.js';
|
|
16
|
+
export interface EntityAnalysis {
|
|
17
|
+
detectedType: NounType;
|
|
18
|
+
confidence: number;
|
|
19
|
+
reasoning: string;
|
|
20
|
+
alternativeTypes: Array<{
|
|
21
|
+
type: NounType;
|
|
22
|
+
confidence: number;
|
|
23
|
+
}>;
|
|
24
|
+
suggestedId?: string;
|
|
25
|
+
qualityScore: number;
|
|
26
|
+
}
|
|
27
|
+
export interface RelationshipAnalysis {
|
|
28
|
+
verbType: VerbType;
|
|
29
|
+
confidence: number;
|
|
30
|
+
weight: number;
|
|
31
|
+
reasoning: string;
|
|
32
|
+
context: string;
|
|
33
|
+
metadata?: Record<string, any>;
|
|
34
|
+
}
|
|
35
|
+
export interface DeleteAnalysis {
|
|
36
|
+
strategy: 'soft-delete' | 'hard-delete' | 'cascade-delete' | 'soft-delete-preserve';
|
|
37
|
+
impactedEntities: string[];
|
|
38
|
+
orphanedRelationships: string[];
|
|
39
|
+
riskLevel: 'low' | 'medium' | 'high';
|
|
40
|
+
recommendation: string;
|
|
41
|
+
preserveData: boolean;
|
|
42
|
+
}
|
|
43
|
+
export interface DataInsights {
|
|
44
|
+
entityDistribution: Record<string, number>;
|
|
45
|
+
relationshipPatterns: Array<{
|
|
46
|
+
pattern: string;
|
|
47
|
+
frequency: number;
|
|
48
|
+
}>;
|
|
49
|
+
hierarchies: Array<{
|
|
50
|
+
type: string;
|
|
51
|
+
levels: number;
|
|
52
|
+
entities: string[];
|
|
53
|
+
}>;
|
|
54
|
+
clusters: Array<{
|
|
55
|
+
type: string;
|
|
56
|
+
size: number;
|
|
57
|
+
entities: string[];
|
|
58
|
+
}>;
|
|
59
|
+
anomalies: Array<{
|
|
60
|
+
type: string;
|
|
61
|
+
description: string;
|
|
62
|
+
entities: string[];
|
|
63
|
+
}>;
|
|
64
|
+
qualityMetrics: QualityAssessment;
|
|
65
|
+
}
|
|
66
|
+
export interface QualityAssessment {
|
|
67
|
+
completeness: number;
|
|
68
|
+
consistency: number;
|
|
69
|
+
accuracy: number;
|
|
70
|
+
richness: number;
|
|
71
|
+
recommendations: string[];
|
|
72
|
+
}
|
|
73
|
+
export interface DetectionOptions {
|
|
74
|
+
confidenceThreshold?: number;
|
|
75
|
+
includeAlternatives?: boolean;
|
|
76
|
+
generateReasoning?: boolean;
|
|
77
|
+
enableCaching?: boolean;
|
|
78
|
+
}
|
|
79
|
+
export interface ImpactOptions {
|
|
80
|
+
analyzeCascade?: boolean;
|
|
81
|
+
checkOrphans?: boolean;
|
|
82
|
+
riskAssessment?: boolean;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Neural Detection Engine - The Brainy AI Brain
|
|
86
|
+
*/
|
|
87
|
+
export declare class NeuralDetectionEngine {
|
|
88
|
+
private brainy;
|
|
89
|
+
private analysisCache;
|
|
90
|
+
private config;
|
|
91
|
+
constructor(brainy: BrainyData, config?: Partial<typeof NeuralDetectionEngine.prototype.config>);
|
|
92
|
+
/**
|
|
93
|
+
* Detect Entity Type - Replaces basic detectNounType() with neural analysis
|
|
94
|
+
*/
|
|
95
|
+
detectEntityType(data: any, options?: DetectionOptions): Promise<EntityAnalysis>;
|
|
96
|
+
/**
|
|
97
|
+
* Detect Relationship Types - Intelligent relationship inference
|
|
98
|
+
*/
|
|
99
|
+
detectRelationshipTypes(sourceData: any, targetData: any, options?: DetectionOptions): Promise<RelationshipAnalysis[]>;
|
|
100
|
+
/**
|
|
101
|
+
* Analyze Delete Impact - Intelligent cascade and orphan analysis
|
|
102
|
+
*/
|
|
103
|
+
analyzeDeleteImpact(nounId: string, options?: ImpactOptions): Promise<DeleteAnalysis>;
|
|
104
|
+
/**
|
|
105
|
+
* Generate Data Insights - Pattern recognition and analysis
|
|
106
|
+
*/
|
|
107
|
+
generateDataInsights(entities: any[], relationships: any[]): Promise<DataInsights>;
|
|
108
|
+
/**
|
|
109
|
+
* Assess Data Quality
|
|
110
|
+
*/
|
|
111
|
+
assessDataQuality(data: any[]): Promise<QualityAssessment>;
|
|
112
|
+
/**
|
|
113
|
+
* Calculate entity type confidence using multi-factor analysis
|
|
114
|
+
*/
|
|
115
|
+
private calculateEntityTypeConfidence;
|
|
116
|
+
/**
|
|
117
|
+
* Field-based confidence calculation
|
|
118
|
+
*/
|
|
119
|
+
private calculateFieldBasedConfidence;
|
|
120
|
+
/**
|
|
121
|
+
* Pattern-based confidence calculation
|
|
122
|
+
*/
|
|
123
|
+
private calculatePatternBasedConfidence;
|
|
124
|
+
/**
|
|
125
|
+
* Generate reasoning for entity type selection
|
|
126
|
+
*/
|
|
127
|
+
private generateEntityReasoning;
|
|
128
|
+
/**
|
|
129
|
+
* Calculate relationship confidence
|
|
130
|
+
*/
|
|
131
|
+
private calculateRelationshipConfidence;
|
|
132
|
+
/**
|
|
133
|
+
* Calculate relationship weight/strength
|
|
134
|
+
*/
|
|
135
|
+
private calculateRelationshipWeight;
|
|
136
|
+
/**
|
|
137
|
+
* Calculate type compatibility for relationships
|
|
138
|
+
*/
|
|
139
|
+
private calculateTypeCompatibility;
|
|
140
|
+
/**
|
|
141
|
+
* Generate relationship reasoning
|
|
142
|
+
*/
|
|
143
|
+
private generateRelationshipReasoning;
|
|
144
|
+
/**
|
|
145
|
+
* Extract main text from data object
|
|
146
|
+
*/
|
|
147
|
+
private extractMainText;
|
|
148
|
+
/**
|
|
149
|
+
* Extract relationship context
|
|
150
|
+
*/
|
|
151
|
+
private extractRelationshipContext;
|
|
152
|
+
/**
|
|
153
|
+
* Generate smart ID for entities
|
|
154
|
+
*/
|
|
155
|
+
private generateSmartId;
|
|
156
|
+
/**
|
|
157
|
+
* Assess entity quality
|
|
158
|
+
*/
|
|
159
|
+
private assessEntityQuality;
|
|
160
|
+
/**
|
|
161
|
+
* Basic type detection fallback
|
|
162
|
+
*/
|
|
163
|
+
private basicTypeDetection;
|
|
164
|
+
/**
|
|
165
|
+
* Check if relationship is critical for cascade analysis
|
|
166
|
+
*/
|
|
167
|
+
private isRelationshipCritical;
|
|
168
|
+
/**
|
|
169
|
+
* Get verb specificity score
|
|
170
|
+
*/
|
|
171
|
+
private getVerbSpecificity;
|
|
172
|
+
/**
|
|
173
|
+
* Get relevant fields for entity type
|
|
174
|
+
*/
|
|
175
|
+
private getRelevantFields;
|
|
176
|
+
/**
|
|
177
|
+
* Get matched patterns for entity type
|
|
178
|
+
*/
|
|
179
|
+
private getMatchedPatterns;
|
|
180
|
+
/**
|
|
181
|
+
* Detect hierarchies in relationships
|
|
182
|
+
*/
|
|
183
|
+
private detectHierarchies;
|
|
184
|
+
/**
|
|
185
|
+
* Detect clusters in entities
|
|
186
|
+
*/
|
|
187
|
+
private detectClusters;
|
|
188
|
+
/**
|
|
189
|
+
* Extract relationship metadata
|
|
190
|
+
*/
|
|
191
|
+
private extractRelationshipMetadata;
|
|
192
|
+
/**
|
|
193
|
+
* Generate cache key
|
|
194
|
+
*/
|
|
195
|
+
private generateCacheKey;
|
|
196
|
+
/**
|
|
197
|
+
* Clear analysis cache
|
|
198
|
+
*/
|
|
199
|
+
clearCache(): void;
|
|
200
|
+
/**
|
|
201
|
+
* Get cache statistics
|
|
202
|
+
*/
|
|
203
|
+
getCacheStats(): {
|
|
204
|
+
size: number;
|
|
205
|
+
keys: string[];
|
|
206
|
+
};
|
|
207
|
+
}
|