@soulcraft/brainy 2.11.0 → 2.14.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/CHANGELOG.md +15 -0
- package/dist/brainyData.d.ts +5 -8
- package/dist/brainyData.js +56 -39
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/modelAutoConfig.d.ts +1 -0
- package/dist/config/modelAutoConfig.js +27 -22
- package/dist/config/modelPrecisionManager.d.ts +42 -0
- package/dist/config/modelPrecisionManager.js +98 -0
- package/dist/config/zeroConfig.js +1 -1
- package/dist/embeddings/CachedEmbeddings.d.ts +40 -0
- package/dist/embeddings/CachedEmbeddings.js +146 -0
- package/dist/embeddings/EmbeddingManager.d.ts +106 -0
- package/dist/embeddings/EmbeddingManager.js +296 -0
- package/dist/embeddings/SingletonModelManager.d.ts +95 -0
- package/dist/embeddings/SingletonModelManager.js +220 -0
- package/dist/embeddings/index.d.ts +12 -0
- package/dist/embeddings/index.js +16 -0
- package/dist/embeddings/lightweight-embedder.d.ts +0 -1
- package/dist/embeddings/lightweight-embedder.js +4 -12
- package/dist/embeddings/universal-memory-manager.js +13 -50
- package/dist/embeddings/worker-embedding.js +4 -8
- package/dist/neural/improvedNeuralAPI.d.ts +346 -0
- package/dist/neural/improvedNeuralAPI.js +2439 -0
- package/dist/neural/types.d.ts +267 -0
- package/dist/neural/types.js +24 -0
- package/dist/utils/embedding.d.ts +7 -2
- package/dist/utils/embedding.js +51 -33
- package/dist/utils/hybridModelManager.d.ts +19 -28
- package/dist/utils/hybridModelManager.js +36 -200
- package/package.json +1 -1
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Hybrid Model Manager - BEST OF BOTH WORLDS
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* NOW A WRAPPER AROUND SingletonModelManager
|
|
5
|
+
* Maintained for backward compatibility
|
|
6
|
+
*
|
|
7
|
+
* Previously combined:
|
|
5
8
|
* 1. Multi-source downloading strategy (GitHub → CDN → Hugging Face)
|
|
6
9
|
* 2. Singleton pattern preventing multiple ONNX model loads
|
|
7
10
|
* 3. Environment-specific optimizations
|
|
8
11
|
* 4. Graceful fallbacks and error handling
|
|
12
|
+
*
|
|
13
|
+
* Now delegates all operations to SingletonModelManager for true unification
|
|
9
14
|
*/
|
|
10
|
-
import {
|
|
11
|
-
import { existsSync } from 'fs';
|
|
12
|
-
import { join } from 'path';
|
|
15
|
+
import { singletonModelManager, getUnifiedEmbeddingFunction } from '../embeddings/SingletonModelManager.js';
|
|
13
16
|
/**
|
|
14
|
-
*
|
|
17
|
+
* HybridModelManager - Now a wrapper around SingletonModelManager
|
|
18
|
+
* Maintained for backward compatibility
|
|
15
19
|
*/
|
|
16
20
|
class HybridModelManager {
|
|
17
21
|
constructor() {
|
|
18
|
-
|
|
19
|
-
this.modelPromise = null;
|
|
20
|
-
this.isInitialized = false;
|
|
21
|
-
// Smart model path detection
|
|
22
|
-
this.modelsPath = this.getModelsPath();
|
|
22
|
+
console.log('🔄 HybridModelManager now delegates to SingletonModelManager');
|
|
23
23
|
}
|
|
24
24
|
static getInstance() {
|
|
25
25
|
if (!HybridModelManager.instance) {
|
|
@@ -28,207 +28,42 @@ class HybridModelManager {
|
|
|
28
28
|
return HybridModelManager.instance;
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
|
-
* Get the primary embedding model -
|
|
31
|
+
* Get the primary embedding model - delegates to SingletonModelManager
|
|
32
32
|
*/
|
|
33
33
|
async getPrimaryModel() {
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
return this.primaryModel;
|
|
37
|
-
}
|
|
38
|
-
// If initialization is in progress, wait for it
|
|
39
|
-
if (this.modelPromise) {
|
|
40
|
-
return await this.modelPromise;
|
|
41
|
-
}
|
|
42
|
-
// Start initialization with multi-source strategy
|
|
43
|
-
this.modelPromise = this.initializePrimaryModel();
|
|
44
|
-
return await this.modelPromise;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Smart model path detection
|
|
48
|
-
*/
|
|
49
|
-
getModelsPath() {
|
|
50
|
-
const paths = [
|
|
51
|
-
process.env.BRAINY_MODELS_PATH,
|
|
52
|
-
'./models',
|
|
53
|
-
'./node_modules/@soulcraft/brainy/models',
|
|
54
|
-
join(process.cwd(), 'models')
|
|
55
|
-
];
|
|
56
|
-
// Find first existing path or use default
|
|
57
|
-
for (const path of paths) {
|
|
58
|
-
if (path && existsSync(path)) {
|
|
59
|
-
return path;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
return join(process.cwd(), 'models');
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Initialize with BEST OF BOTH: Multi-source + Singleton
|
|
66
|
-
*/
|
|
67
|
-
async initializePrimaryModel() {
|
|
68
|
-
try {
|
|
69
|
-
// Environment detection for optimal configuration
|
|
70
|
-
const isTest = globalThis.__BRAINY_TEST_ENV__ || process.env.NODE_ENV === 'test';
|
|
71
|
-
const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
72
|
-
const isServerless = typeof process !== 'undefined' && (process.env.VERCEL ||
|
|
73
|
-
process.env.NETLIFY ||
|
|
74
|
-
process.env.AWS_LAMBDA_FUNCTION_NAME ||
|
|
75
|
-
process.env.FUNCTIONS_WORKER_RUNTIME);
|
|
76
|
-
const isDocker = typeof process !== 'undefined' && (process.env.DOCKER_CONTAINER ||
|
|
77
|
-
process.env.KUBERNETES_SERVICE_HOST);
|
|
78
|
-
// Respect BRAINY_ALLOW_REMOTE_MODELS environment variable first
|
|
79
|
-
let forceLocalOnly = false;
|
|
80
|
-
if (process.env.BRAINY_ALLOW_REMOTE_MODELS !== undefined) {
|
|
81
|
-
forceLocalOnly = process.env.BRAINY_ALLOW_REMOTE_MODELS !== 'true';
|
|
82
|
-
}
|
|
83
|
-
// Smart configuration based on environment
|
|
84
|
-
let options = {
|
|
85
|
-
verbose: !isTest && !isServerless,
|
|
86
|
-
precision: 'fp32', // Use clearer precision parameter
|
|
87
|
-
device: 'cpu'
|
|
88
|
-
};
|
|
89
|
-
// Environment-specific optimizations
|
|
90
|
-
if (isBrowser) {
|
|
91
|
-
options = {
|
|
92
|
-
...options,
|
|
93
|
-
localFilesOnly: forceLocalOnly || false, // Respect environment variable
|
|
94
|
-
precision: 'fp32',
|
|
95
|
-
device: 'cpu',
|
|
96
|
-
verbose: false
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
else if (isServerless) {
|
|
100
|
-
options = {
|
|
101
|
-
...options,
|
|
102
|
-
localFilesOnly: forceLocalOnly || true, // Default true for serverless, but respect env
|
|
103
|
-
precision: 'fp32',
|
|
104
|
-
device: 'cpu',
|
|
105
|
-
verbose: false
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
else if (isDocker) {
|
|
109
|
-
options = {
|
|
110
|
-
...options,
|
|
111
|
-
localFilesOnly: forceLocalOnly || true, // Default true for docker, but respect env
|
|
112
|
-
precision: 'fp32',
|
|
113
|
-
device: 'auto',
|
|
114
|
-
verbose: false
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
else if (isTest) {
|
|
118
|
-
// CRITICAL FOR TESTS: Allow remote downloads but be smart about it
|
|
119
|
-
options = {
|
|
120
|
-
...options,
|
|
121
|
-
localFilesOnly: forceLocalOnly || false, // Respect environment variable for tests
|
|
122
|
-
precision: 'fp32',
|
|
123
|
-
device: 'cpu',
|
|
124
|
-
verbose: false
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
options = {
|
|
129
|
-
...options,
|
|
130
|
-
localFilesOnly: forceLocalOnly || false, // Respect environment variable for default node
|
|
131
|
-
precision: 'fp32',
|
|
132
|
-
device: 'auto',
|
|
133
|
-
verbose: true
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
const environmentName = isBrowser ? 'browser' :
|
|
137
|
-
isServerless ? 'serverless' :
|
|
138
|
-
isDocker ? 'container' :
|
|
139
|
-
isTest ? 'test' : 'node';
|
|
140
|
-
if (options.verbose) {
|
|
141
|
-
console.log(`🧠 Initializing hybrid model manager (${environmentName} mode)...`);
|
|
142
|
-
}
|
|
143
|
-
// MULTI-SOURCE STRATEGY: Try local first, then remote fallbacks
|
|
144
|
-
this.primaryModel = await this.createModelWithFallbacks(options, environmentName);
|
|
145
|
-
this.isInitialized = true;
|
|
146
|
-
this.modelPromise = null; // Clear the promise
|
|
147
|
-
if (options.verbose) {
|
|
148
|
-
console.log(`✅ Hybrid model manager initialized successfully`);
|
|
149
|
-
}
|
|
150
|
-
return this.primaryModel;
|
|
151
|
-
}
|
|
152
|
-
catch (error) {
|
|
153
|
-
this.modelPromise = null; // Clear failed promise
|
|
154
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
155
|
-
const environmentInfo = typeof window !== 'undefined' ? 'browser' :
|
|
156
|
-
typeof process !== 'undefined' ? `node (${process.version})` : 'unknown';
|
|
157
|
-
throw new Error(`Failed to initialize hybrid model manager in ${environmentInfo} environment: ${errorMessage}. ` +
|
|
158
|
-
`This is critical for all Brainy operations.`);
|
|
159
|
-
}
|
|
34
|
+
// Delegate to SingletonModelManager
|
|
35
|
+
return await singletonModelManager.getModel();
|
|
160
36
|
}
|
|
161
37
|
/**
|
|
162
|
-
*
|
|
163
|
-
*/
|
|
164
|
-
async createModelWithFallbacks(options, environmentName) {
|
|
165
|
-
const attempts = [
|
|
166
|
-
// 1. Try with current configuration (may use local cache)
|
|
167
|
-
{ ...options, localFilesOnly: false, source: 'primary' },
|
|
168
|
-
// 2. If that fails, explicitly allow remote with verbose logging
|
|
169
|
-
{ ...options, localFilesOnly: false, verbose: true, source: 'fallback-verbose' },
|
|
170
|
-
// 3. Last resort: basic configuration
|
|
171
|
-
{ verbose: false, precision: 'fp32', device: 'cpu', localFilesOnly: false, source: 'last-resort' }
|
|
172
|
-
];
|
|
173
|
-
let lastError = null;
|
|
174
|
-
for (const attemptOptions of attempts) {
|
|
175
|
-
try {
|
|
176
|
-
const { source, ...modelOptions } = attemptOptions;
|
|
177
|
-
if (attemptOptions.verbose) {
|
|
178
|
-
console.log(`🔄 Attempting model load (${source})...`);
|
|
179
|
-
}
|
|
180
|
-
const model = new TransformerEmbedding(modelOptions);
|
|
181
|
-
await model.init();
|
|
182
|
-
if (attemptOptions.verbose) {
|
|
183
|
-
console.log(`✅ Model loaded successfully with ${source} strategy`);
|
|
184
|
-
}
|
|
185
|
-
return model;
|
|
186
|
-
}
|
|
187
|
-
catch (error) {
|
|
188
|
-
lastError = error instanceof Error ? error : new Error(String(error));
|
|
189
|
-
if (attemptOptions.verbose) {
|
|
190
|
-
console.log(`❌ Failed ${attemptOptions.source} strategy:`, lastError.message);
|
|
191
|
-
}
|
|
192
|
-
// Continue to next attempt
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
// All attempts failed
|
|
196
|
-
throw new Error(`All model loading strategies failed in ${environmentName} environment. ` +
|
|
197
|
-
`Last error: ${lastError?.message}. ` +
|
|
198
|
-
`Check network connectivity or ensure models are available locally.`);
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Get embedding function that reuses the singleton model
|
|
38
|
+
* Get embedding function - delegates to SingletonModelManager
|
|
202
39
|
*/
|
|
203
40
|
async getEmbeddingFunction() {
|
|
204
|
-
|
|
205
|
-
return async (data) => {
|
|
206
|
-
return await model.embed(data);
|
|
207
|
-
};
|
|
41
|
+
return await getUnifiedEmbeddingFunction();
|
|
208
42
|
}
|
|
209
43
|
/**
|
|
210
|
-
* Check if model is ready
|
|
44
|
+
* Check if model is ready - delegates to SingletonModelManager
|
|
211
45
|
*/
|
|
212
46
|
isModelReady() {
|
|
213
|
-
return
|
|
47
|
+
return singletonModelManager.isInitialized();
|
|
214
48
|
}
|
|
215
49
|
/**
|
|
216
|
-
* Force model reload
|
|
50
|
+
* Force model reload - not supported with SingletonModelManager
|
|
217
51
|
*/
|
|
218
52
|
async reloadModel() {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
53
|
+
console.warn('⚠️ Model reload not supported with SingletonModelManager');
|
|
54
|
+
console.log('ℹ️ Singleton model persists for consistency');
|
|
55
|
+
// Just ensure model is initialized
|
|
222
56
|
await this.getPrimaryModel();
|
|
223
57
|
}
|
|
224
58
|
/**
|
|
225
|
-
* Get model status
|
|
59
|
+
* Get model status - delegates to SingletonModelManager
|
|
226
60
|
*/
|
|
227
61
|
getModelStatus() {
|
|
62
|
+
const isReady = singletonModelManager.isInitialized();
|
|
228
63
|
return {
|
|
229
|
-
loaded:
|
|
230
|
-
ready:
|
|
231
|
-
modelType: '
|
|
64
|
+
loaded: isReady,
|
|
65
|
+
ready: isReady,
|
|
66
|
+
modelType: 'SingletonModelManager (Unified model instance)'
|
|
232
67
|
};
|
|
233
68
|
}
|
|
234
69
|
}
|
|
@@ -236,24 +71,25 @@ HybridModelManager.instance = null;
|
|
|
236
71
|
// Export singleton instance
|
|
237
72
|
export const hybridModelManager = HybridModelManager.getInstance();
|
|
238
73
|
/**
|
|
239
|
-
* Get the hybrid singleton embedding function -
|
|
74
|
+
* Get the hybrid singleton embedding function - Now delegates to SingletonModelManager
|
|
75
|
+
* Maintained for backward compatibility
|
|
240
76
|
*/
|
|
241
77
|
export async function getHybridEmbeddingFunction() {
|
|
242
|
-
return await
|
|
78
|
+
return await getUnifiedEmbeddingFunction();
|
|
243
79
|
}
|
|
244
80
|
/**
|
|
245
|
-
*
|
|
81
|
+
* Hybrid embedding function - Now delegates to SingletonModelManager
|
|
82
|
+
* Maintained for backward compatibility
|
|
246
83
|
*/
|
|
247
84
|
export const hybridEmbeddingFunction = async (data) => {
|
|
248
|
-
|
|
249
|
-
return await embeddingFn(data);
|
|
85
|
+
return await singletonModelManager.embed(data);
|
|
250
86
|
};
|
|
251
87
|
/**
|
|
252
|
-
* Preload model for tests or production -
|
|
88
|
+
* Preload model for tests or production - Now delegates to SingletonModelManager
|
|
253
89
|
*/
|
|
254
90
|
export async function preloadHybridModel() {
|
|
255
|
-
console.log('🚀 Preloading
|
|
256
|
-
await
|
|
257
|
-
console.log('✅
|
|
91
|
+
console.log('🚀 Preloading model via SingletonModelManager...');
|
|
92
|
+
await singletonModelManager.getModel();
|
|
93
|
+
console.log('✅ Singleton model preloaded and ready!');
|
|
258
94
|
}
|
|
259
95
|
//# sourceMappingURL=hybridModelManager.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soulcraft/brainy",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0",
|
|
4
4
|
"description": "Universal Knowledge Protocol™ - World's first Triple Intelligence database unifying vector, graph, and document search in one API. 31 nouns × 40 verbs for infinite expressiveness.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|