@soulcraft/brainy 3.20.1 โ†’ 3.20.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 (91) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/bin/brainy-interactive.js +2 -2
  3. package/dist/brainy.d.ts +1 -1
  4. package/dist/mcp/brainyMCPAdapter.d.ts +1 -1
  5. package/dist/mcp/brainyMCPService.d.ts +1 -1
  6. package/dist/neural/embeddedPatterns.d.ts +1 -1
  7. package/dist/neural/embeddedPatterns.js +1 -1
  8. package/dist/shared/default-augmentations.d.ts +1 -1
  9. package/dist/types/{brainyDataInterface.js โ†’ brainyInterface.js} +1 -1
  10. package/dist/vfs/VirtualFileSystem.d.ts +1 -0
  11. package/dist/vfs/VirtualFileSystem.js +108 -69
  12. package/package.json +1 -1
  13. package/dist/augmentationFactory.d.ts +0 -86
  14. package/dist/augmentationFactory.js +0 -342
  15. package/dist/augmentationRegistry.d.ts +0 -38
  16. package/dist/augmentationRegistry.js +0 -54
  17. package/dist/augmentationRegistryLoader.d.ts +0 -146
  18. package/dist/augmentationRegistryLoader.js +0 -213
  19. package/dist/augmentations/KnowledgeAugmentation.d.ts +0 -40
  20. package/dist/augmentations/KnowledgeAugmentation.js +0 -251
  21. package/dist/augmentations/intelligentVerbScoring.d.ts +0 -158
  22. package/dist/augmentations/intelligentVerbScoring.js +0 -377
  23. package/dist/augmentations/marketplace/AugmentationMarketplace.d.ts +0 -168
  24. package/dist/augmentations/marketplace/AugmentationMarketplace.js +0 -329
  25. package/dist/augmentations/marketplace/cli.d.ts +0 -47
  26. package/dist/augmentations/marketplace/cli.js +0 -265
  27. package/dist/augmentations/memoryAugmentations.d.ts +0 -72
  28. package/dist/augmentations/memoryAugmentations.js +0 -280
  29. package/dist/augmentations/serverSearchAugmentations.d.ts +0 -190
  30. package/dist/augmentations/serverSearchAugmentations.js +0 -586
  31. package/dist/brainy-unified.d.ts +0 -106
  32. package/dist/brainy-unified.js +0 -327
  33. package/dist/brainyData.d.ts +0 -1832
  34. package/dist/brainyData.js +0 -6443
  35. package/dist/brainyDataV3.d.ts +0 -186
  36. package/dist/brainyDataV3.js +0 -337
  37. package/dist/config/distributedPresets-new.d.ts +0 -118
  38. package/dist/config/distributedPresets-new.js +0 -318
  39. package/dist/config/modelPrecisionManager.d.ts +0 -42
  40. package/dist/config/modelPrecisionManager.js +0 -98
  41. package/dist/connectors/interfaces/IConnector.d.ts +0 -143
  42. package/dist/connectors/interfaces/IConnector.js +0 -8
  43. package/dist/demo.d.ts +0 -106
  44. package/dist/demo.js +0 -201
  45. package/dist/embeddings/SingletonModelManager.d.ts +0 -95
  46. package/dist/embeddings/SingletonModelManager.js +0 -220
  47. package/dist/embeddings/lightweight-embedder.d.ts +0 -22
  48. package/dist/embeddings/lightweight-embedder.js +0 -128
  49. package/dist/embeddings/model-manager.d.ts +0 -39
  50. package/dist/embeddings/model-manager.js +0 -245
  51. package/dist/embeddings/universal-memory-manager.d.ts +0 -38
  52. package/dist/embeddings/universal-memory-manager.js +0 -166
  53. package/dist/embeddings/worker-embedding.d.ts +0 -7
  54. package/dist/embeddings/worker-embedding.js +0 -73
  55. package/dist/embeddings/worker-manager.d.ts +0 -28
  56. package/dist/embeddings/worker-manager.js +0 -162
  57. package/dist/examples/basicUsage.d.ts +0 -4
  58. package/dist/examples/basicUsage.js +0 -121
  59. package/dist/indices/fieldIndex.d.ts +0 -76
  60. package/dist/indices/fieldIndex.js +0 -357
  61. package/dist/mcp/brainyMCPBroadcast.d.ts +0 -82
  62. package/dist/mcp/brainyMCPBroadcast.js +0 -303
  63. package/dist/mcp/brainyMCPClient.d.ts +0 -92
  64. package/dist/mcp/brainyMCPClient.js +0 -258
  65. package/dist/scripts/precomputePatternEmbeddings.d.ts +0 -19
  66. package/dist/scripts/precomputePatternEmbeddings.js +0 -100
  67. package/dist/utils/cacheAutoConfig.d.ts +0 -63
  68. package/dist/utils/cacheAutoConfig.js +0 -261
  69. package/dist/utils/hybridModelManager.d.ts +0 -64
  70. package/dist/utils/hybridModelManager.js +0 -95
  71. package/dist/utils/statistics.d.ts +0 -28
  72. package/dist/utils/statistics.js +0 -25
  73. package/dist/vfs/ConceptSystem.d.ts +0 -203
  74. package/dist/vfs/ConceptSystem.js +0 -545
  75. package/dist/vfs/EntityManager.d.ts +0 -75
  76. package/dist/vfs/EntityManager.js +0 -216
  77. package/dist/vfs/EventRecorder.d.ts +0 -84
  78. package/dist/vfs/EventRecorder.js +0 -269
  79. package/dist/vfs/GitBridge.d.ts +0 -167
  80. package/dist/vfs/GitBridge.js +0 -537
  81. package/dist/vfs/KnowledgeAugmentation.d.ts +0 -104
  82. package/dist/vfs/KnowledgeAugmentation.js +0 -146
  83. package/dist/vfs/KnowledgeLayer.d.ts +0 -35
  84. package/dist/vfs/KnowledgeLayer.js +0 -443
  85. package/dist/vfs/PersistentEntitySystem.d.ts +0 -165
  86. package/dist/vfs/PersistentEntitySystem.js +0 -503
  87. package/dist/vfs/SemanticVersioning.d.ts +0 -105
  88. package/dist/vfs/SemanticVersioning.js +0 -309
  89. package/dist/vfs/VFSHealthCheck.d.ts +0 -78
  90. package/dist/vfs/VFSHealthCheck.js +0 -299
  91. /package/dist/types/{brainyDataInterface.d.ts โ†’ brainyInterface.d.ts} +0 -0
@@ -1,128 +0,0 @@
1
- /**
2
- * Lightweight Embedding Alternative
3
- *
4
- * Uses pre-computed embeddings for common terms
5
- * Falls back to ONNX for unknown terms
6
- *
7
- * This reduces memory usage by 90% for typical queries
8
- */
9
- import { singletonModelManager } from './SingletonModelManager.js';
10
- // Pre-computed embeddings for top 10,000 common terms
11
- // In production, this would be loaded from a file
12
- const PRECOMPUTED_EMBEDDINGS = {
13
- // Programming languages
14
- 'javascript': new Array(384).fill(0).map((_, i) => Math.sin(i * 0.1)),
15
- 'python': new Array(384).fill(0).map((_, i) => Math.cos(i * 0.1)),
16
- 'typescript': new Array(384).fill(0).map((_, i) => Math.sin(i * 0.15)),
17
- 'java': new Array(384).fill(0).map((_, i) => Math.cos(i * 0.15)),
18
- 'rust': new Array(384).fill(0).map((_, i) => Math.sin(i * 0.2)),
19
- 'go': new Array(384).fill(0).map((_, i) => Math.cos(i * 0.2)),
20
- // Frameworks
21
- 'react': new Array(384).fill(0).map((_, i) => Math.sin(i * 0.25)),
22
- 'vue': new Array(384).fill(0).map((_, i) => Math.cos(i * 0.25)),
23
- 'angular': new Array(384).fill(0).map((_, i) => Math.sin(i * 0.3)),
24
- 'svelte': new Array(384).fill(0).map((_, i) => Math.cos(i * 0.3)),
25
- // Databases
26
- 'postgresql': new Array(384).fill(0).map((_, i) => Math.sin(i * 0.35)),
27
- 'mysql': new Array(384).fill(0).map((_, i) => Math.cos(i * 0.35)),
28
- 'mongodb': new Array(384).fill(0).map((_, i) => Math.sin(i * 0.4)),
29
- 'redis': new Array(384).fill(0).map((_, i) => Math.cos(i * 0.4)),
30
- // Common terms
31
- 'database': new Array(384).fill(0).map((_, i) => Math.sin(i * 0.45)),
32
- 'api': new Array(384).fill(0).map((_, i) => Math.cos(i * 0.45)),
33
- 'server': new Array(384).fill(0).map((_, i) => Math.sin(i * 0.5)),
34
- 'client': new Array(384).fill(0).map((_, i) => Math.cos(i * 0.5)),
35
- 'frontend': new Array(384).fill(0).map((_, i) => Math.sin(i * 0.55)),
36
- 'backend': new Array(384).fill(0).map((_, i) => Math.cos(i * 0.55)),
37
- // Add more pre-computed embeddings here...
38
- };
39
- // Simple word similarity using character n-grams
40
- function computeSimpleEmbedding(text) {
41
- const normalized = text.toLowerCase().trim();
42
- const vector = new Array(384).fill(0);
43
- // Character trigrams for simple semantic similarity
44
- for (let i = 0; i < normalized.length - 2; i++) {
45
- const trigram = normalized.slice(i, i + 3);
46
- const hash = trigram.charCodeAt(0) * 31 +
47
- trigram.charCodeAt(1) * 7 +
48
- trigram.charCodeAt(2);
49
- const index = Math.abs(hash) % 384;
50
- vector[index] += 1 / (normalized.length - 2);
51
- }
52
- // Normalize vector
53
- const magnitude = Math.sqrt(vector.reduce((sum, val) => sum + val * val, 0));
54
- if (magnitude > 0) {
55
- for (let i = 0; i < vector.length; i++) {
56
- vector[i] /= magnitude;
57
- }
58
- }
59
- return vector;
60
- }
61
- export class LightweightEmbedder {
62
- constructor() {
63
- this.stats = {
64
- precomputedHits: 0,
65
- simpleComputes: 0,
66
- onnxComputes: 0
67
- };
68
- }
69
- async embed(text) {
70
- if (Array.isArray(text)) {
71
- return Promise.all(text.map(t => this.embedSingle(t)));
72
- }
73
- return this.embedSingle(text);
74
- }
75
- async embedSingle(text) {
76
- const normalized = text.toLowerCase().trim();
77
- // 1. Check pre-computed embeddings (instant, zero memory)
78
- if (PRECOMPUTED_EMBEDDINGS[normalized]) {
79
- this.stats.precomputedHits++;
80
- return PRECOMPUTED_EMBEDDINGS[normalized];
81
- }
82
- // 2. Check for close matches in pre-computed
83
- for (const [term, embedding] of Object.entries(PRECOMPUTED_EMBEDDINGS)) {
84
- if (normalized.includes(term) || term.includes(normalized)) {
85
- this.stats.precomputedHits++;
86
- // Return slightly modified version to maintain uniqueness
87
- return embedding.map(v => v * 0.95);
88
- }
89
- }
90
- // 3. For short text, use simple embedding (fast, low memory)
91
- if (normalized.length < 50) {
92
- this.stats.simpleComputes++;
93
- return computeSimpleEmbedding(normalized);
94
- }
95
- // 4. Last resort: Use SingletonModelManager for complex text
96
- console.log('โš ๏ธ Using singleton model for complex text...');
97
- this.stats.onnxComputes++;
98
- return await singletonModelManager.embed(text);
99
- }
100
- getStats() {
101
- return {
102
- ...this.stats,
103
- totalEmbeddings: this.stats.precomputedHits +
104
- this.stats.simpleComputes +
105
- this.stats.onnxComputes,
106
- cacheHitRate: this.stats.precomputedHits /
107
- (this.stats.precomputedHits +
108
- this.stats.simpleComputes +
109
- this.stats.onnxComputes)
110
- };
111
- }
112
- // Pre-load common embeddings from file
113
- async loadPrecomputed(filePath) {
114
- if (!filePath)
115
- return;
116
- try {
117
- const fs = await import('fs/promises');
118
- const data = await fs.readFile(filePath, 'utf-8');
119
- const embeddings = JSON.parse(data);
120
- Object.assign(PRECOMPUTED_EMBEDDINGS, embeddings);
121
- console.log(`โœ… Loaded ${Object.keys(embeddings).length} pre-computed embeddings`);
122
- }
123
- catch (error) {
124
- console.warn('Could not load pre-computed embeddings:', error);
125
- }
126
- }
127
- }
128
- //# sourceMappingURL=lightweight-embedder.js.map
@@ -1,39 +0,0 @@
1
- /**
2
- * Model Manager - Ensures transformer models are available at runtime
3
- *
4
- * Strategy (in order):
5
- * 1. Check local cache first (instant)
6
- * 2. Try Soulcraft CDN (fastest when available)
7
- * 3. Try GitHub release tar.gz with extraction (reliable backup)
8
- * 4. Fall back to Hugging Face (always works)
9
- *
10
- * NO USER CONFIGURATION REQUIRED - Everything is automatic!
11
- */
12
- export declare class ModelManager {
13
- private static instance;
14
- private modelsPath;
15
- private isInitialized;
16
- private constructor();
17
- static getInstance(): ModelManager;
18
- private getModelsPath;
19
- ensureModels(modelName?: string): Promise<boolean>;
20
- private verifyModelFiles;
21
- /**
22
- * Check which model variants are available locally
23
- */
24
- getAvailableModels(modelName?: string): {
25
- fp32: boolean;
26
- q8: boolean;
27
- };
28
- /**
29
- * Get the best available model variant based on preference and availability
30
- */
31
- getBestAvailableModel(preferredType?: 'fp32' | 'q8', modelName?: string): 'fp32' | 'q8' | null;
32
- private tryModelSource;
33
- private downloadAndExtractFromGitHub;
34
- /**
35
- * Pre-download models for deployment
36
- * This is what npm run download-models calls
37
- */
38
- static predownload(): Promise<void>;
39
- }
@@ -1,245 +0,0 @@
1
- /**
2
- * Model Manager - Ensures transformer models are available at runtime
3
- *
4
- * Strategy (in order):
5
- * 1. Check local cache first (instant)
6
- * 2. Try Soulcraft CDN (fastest when available)
7
- * 3. Try GitHub release tar.gz with extraction (reliable backup)
8
- * 4. Fall back to Hugging Face (always works)
9
- *
10
- * NO USER CONFIGURATION REQUIRED - Everything is automatic!
11
- */
12
- import { existsSync } from 'fs';
13
- import { mkdir, writeFile } from 'fs/promises';
14
- import { join } from 'path';
15
- import { env } from '@huggingface/transformers';
16
- // Model sources in order of preference
17
- const MODEL_SOURCES = {
18
- // CDN - Fastest when available (currently active)
19
- cdn: {
20
- host: 'https://models.soulcraft.com/models',
21
- pathTemplate: '{model}/', // e.g., Xenova/all-MiniLM-L6-v2/
22
- testFile: 'config.json' // File to test availability
23
- },
24
- // GitHub Release - tar.gz fallback (already exists and works)
25
- githubRelease: {
26
- tarUrl: 'https://github.com/soulcraftlabs/brainy/releases/download/models-v1/all-MiniLM-L6-v2.tar.gz'
27
- },
28
- // Original Hugging Face - final fallback (always works)
29
- huggingface: {
30
- host: 'https://huggingface.co',
31
- pathTemplate: '{model}/resolve/{revision}/' // Default transformers.js pattern
32
- }
33
- };
34
- // Model verification files - BOTH fp32 and q8 variants
35
- const REQUIRED_FILES = [
36
- 'config.json',
37
- 'tokenizer.json',
38
- 'tokenizer_config.json'
39
- ];
40
- const MODEL_VARIANTS = {
41
- fp32: 'onnx/model.onnx',
42
- q8: 'onnx/model_quantized.onnx'
43
- };
44
- export class ModelManager {
45
- constructor() {
46
- this.isInitialized = false;
47
- // Determine models path
48
- this.modelsPath = this.getModelsPath();
49
- }
50
- static getInstance() {
51
- if (!ModelManager.instance) {
52
- ModelManager.instance = new ModelManager();
53
- }
54
- return ModelManager.instance;
55
- }
56
- getModelsPath() {
57
- // Check various possible locations
58
- const paths = [
59
- process.env.BRAINY_MODELS_PATH,
60
- './models',
61
- join(process.cwd(), 'models'),
62
- join(process.env.HOME || '', '.brainy', 'models'),
63
- env.cacheDir
64
- ];
65
- // Find first existing path or use default
66
- for (const path of paths) {
67
- if (path && existsSync(path)) {
68
- return path;
69
- }
70
- }
71
- // Default to local models directory
72
- return join(process.cwd(), 'models');
73
- }
74
- async ensureModels(modelName = 'Xenova/all-MiniLM-L6-v2') {
75
- if (this.isInitialized) {
76
- return true;
77
- }
78
- // Configure transformers.js environment
79
- env.cacheDir = this.modelsPath;
80
- env.allowLocalModels = true;
81
- env.useFSCache = true;
82
- // Check if model already exists locally
83
- const modelPath = join(this.modelsPath, ...modelName.split('/'));
84
- if (await this.verifyModelFiles(modelPath)) {
85
- console.log('โœ… Models found in cache:', modelPath);
86
- env.allowRemoteModels = false; // Use local only
87
- this.isInitialized = true;
88
- return true;
89
- }
90
- // Try to download from our sources
91
- console.log('๐Ÿ“ฅ Downloading transformer models...');
92
- // Try CDN first (fastest when available)
93
- if (await this.tryModelSource('Soulcraft CDN', MODEL_SOURCES.cdn, modelName)) {
94
- this.isInitialized = true;
95
- return true;
96
- }
97
- // Try GitHub release with tar.gz extraction (reliable backup)
98
- if (await this.downloadAndExtractFromGitHub(modelName)) {
99
- this.isInitialized = true;
100
- return true;
101
- }
102
- // Fall back to Hugging Face (always works)
103
- console.log('โš ๏ธ Using Hugging Face fallback for models');
104
- env.remoteHost = MODEL_SOURCES.huggingface.host;
105
- env.remotePathTemplate = MODEL_SOURCES.huggingface.pathTemplate;
106
- env.allowRemoteModels = true;
107
- this.isInitialized = true;
108
- return true;
109
- }
110
- async verifyModelFiles(modelPath) {
111
- // Check if essential files exist
112
- for (const file of REQUIRED_FILES) {
113
- const fullPath = join(modelPath, file);
114
- if (!existsSync(fullPath)) {
115
- return false;
116
- }
117
- }
118
- // At least one model variant must exist (fp32 or q8)
119
- const fp32Exists = existsSync(join(modelPath, MODEL_VARIANTS.fp32));
120
- const q8Exists = existsSync(join(modelPath, MODEL_VARIANTS.q8));
121
- return fp32Exists || q8Exists;
122
- }
123
- /**
124
- * Check which model variants are available locally
125
- */
126
- getAvailableModels(modelName = 'Xenova/all-MiniLM-L6-v2') {
127
- const modelPath = join(this.modelsPath, modelName);
128
- return {
129
- fp32: existsSync(join(modelPath, MODEL_VARIANTS.fp32)),
130
- q8: existsSync(join(modelPath, MODEL_VARIANTS.q8))
131
- };
132
- }
133
- /**
134
- * Get the best available model variant based on preference and availability
135
- */
136
- getBestAvailableModel(preferredType = 'fp32', modelName = 'Xenova/all-MiniLM-L6-v2') {
137
- const available = this.getAvailableModels(modelName);
138
- // If preferred type is available, use it
139
- if (available[preferredType]) {
140
- return preferredType;
141
- }
142
- // Otherwise fall back to what's available
143
- if (preferredType === 'q8' && available.fp32) {
144
- console.warn('โš ๏ธ Q8 model requested but not available, falling back to FP32');
145
- return 'fp32';
146
- }
147
- if (preferredType === 'fp32' && available.q8) {
148
- console.warn('โš ๏ธ FP32 model requested but not available, falling back to Q8');
149
- return 'q8';
150
- }
151
- return null;
152
- }
153
- async tryModelSource(name, source, modelName) {
154
- try {
155
- console.log(`๐Ÿ“ฅ Trying ${name}...`);
156
- // Test if the source is accessible by trying to fetch a test file
157
- const testFile = source.testFile || 'config.json';
158
- const modelPath = source.pathTemplate.replace('{model}', modelName).replace('{revision}', 'main');
159
- const testUrl = `${source.host}/${modelPath}${testFile}`;
160
- const response = await fetch(testUrl).catch(() => null);
161
- if (response && response.ok) {
162
- console.log(`โœ… ${name} is available`);
163
- // Configure transformers.js to use this source
164
- env.remoteHost = source.host;
165
- env.remotePathTemplate = source.pathTemplate;
166
- env.allowRemoteModels = true;
167
- // The model will be downloaded automatically by transformers.js when needed
168
- return true;
169
- }
170
- else {
171
- console.log(`โš ๏ธ ${name} not available (${response?.status || 'unreachable'})`);
172
- return false;
173
- }
174
- }
175
- catch (error) {
176
- console.log(`โš ๏ธ ${name} check failed:`, error.message);
177
- return false;
178
- }
179
- }
180
- async downloadAndExtractFromGitHub(modelName) {
181
- try {
182
- console.log('๐Ÿ“ฅ Trying GitHub Release (tar.gz)...');
183
- // Download tar.gz file
184
- const response = await fetch(MODEL_SOURCES.githubRelease.tarUrl);
185
- if (!response.ok) {
186
- console.log(`โš ๏ธ GitHub Release not available (${response.status})`);
187
- return false;
188
- }
189
- // Since we can't use tar-stream, we'll use Node's built-in child_process
190
- // to extract using system tar command (available on all Unix systems)
191
- const buffer = await response.arrayBuffer();
192
- const modelPath = join(this.modelsPath, ...modelName.split('/'));
193
- // Create model directory
194
- await mkdir(modelPath, { recursive: true });
195
- // Write tar.gz to temp file and extract
196
- const tempFile = join(this.modelsPath, 'temp-model.tar.gz');
197
- await writeFile(tempFile, Buffer.from(buffer));
198
- // Extract using system tar command
199
- const { exec } = await import('child_process');
200
- const { promisify } = await import('util');
201
- const execAsync = promisify(exec);
202
- try {
203
- // Extract and strip the first directory component
204
- await execAsync(`tar -xzf ${tempFile} -C ${modelPath} --strip-components=1`, {
205
- cwd: this.modelsPath
206
- });
207
- // Clean up temp file
208
- const { unlink } = await import('fs/promises');
209
- await unlink(tempFile);
210
- console.log('โœ… GitHub Release models extracted and cached locally');
211
- // Configure to use local models now
212
- env.allowRemoteModels = false;
213
- return true;
214
- }
215
- catch (extractError) {
216
- console.log('โš ๏ธ Tar extraction failed, trying alternative method');
217
- return false;
218
- }
219
- }
220
- catch (error) {
221
- console.log('โš ๏ธ GitHub Release download failed:', error.message);
222
- return false;
223
- }
224
- }
225
- /**
226
- * Pre-download models for deployment
227
- * This is what npm run download-models calls
228
- */
229
- static async predownload() {
230
- const manager = ModelManager.getInstance();
231
- const success = await manager.ensureModels();
232
- if (!success) {
233
- throw new Error('Failed to download models');
234
- }
235
- console.log('โœ… Models downloaded successfully');
236
- }
237
- }
238
- // Auto-initialize on import in production
239
- if (process.env.NODE_ENV === 'production' && process.env.SKIP_MODEL_CHECK !== 'true') {
240
- ModelManager.getInstance().ensureModels().catch(error => {
241
- console.error('โš ๏ธ Model initialization failed:', error);
242
- // Don't throw - allow app to start and try downloading on first use
243
- });
244
- }
245
- //# sourceMappingURL=model-manager.js.map
@@ -1,38 +0,0 @@
1
- /**
2
- * Universal Memory Manager for Embeddings
3
- *
4
- * Works in ALL environments: Node.js, browsers, serverless, workers
5
- * Solves transformers.js memory leak with environment-specific strategies
6
- */
7
- import { Vector, EmbeddingFunction } from '../coreTypes.js';
8
- interface MemoryStats {
9
- embeddings: number;
10
- memoryUsage: string;
11
- restarts: number;
12
- strategy: string;
13
- }
14
- export declare class UniversalMemoryManager {
15
- private embeddingFunction;
16
- private embedCount;
17
- private restartCount;
18
- private lastRestart;
19
- private strategy;
20
- private maxEmbeddings;
21
- constructor();
22
- getEmbeddingFunction(): Promise<EmbeddingFunction>;
23
- embed(data: string | string[]): Promise<Vector>;
24
- private checkMemoryLimits;
25
- private ensureEmbeddingFunction;
26
- private initNodeDirect;
27
- private initServerless;
28
- private initBrowser;
29
- private initFallback;
30
- private initDirect;
31
- private cleanup;
32
- getMemoryStats(): MemoryStats;
33
- dispose(): Promise<void>;
34
- }
35
- export declare const universalMemoryManager: UniversalMemoryManager;
36
- export declare function getUniversalEmbeddingFunction(): Promise<EmbeddingFunction>;
37
- export declare function getEmbeddingMemoryStats(): MemoryStats;
38
- export {};
@@ -1,166 +0,0 @@
1
- /**
2
- * Universal Memory Manager for Embeddings
3
- *
4
- * Works in ALL environments: Node.js, browsers, serverless, workers
5
- * Solves transformers.js memory leak with environment-specific strategies
6
- */
7
- import { getModelPrecision } from '../config/modelPrecisionManager.js';
8
- // Environment detection
9
- const isNode = typeof process !== 'undefined' && process.versions?.node;
10
- const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
11
- const isServerless = typeof process !== 'undefined' && (process.env.VERCEL ||
12
- process.env.NETLIFY ||
13
- process.env.AWS_LAMBDA_FUNCTION_NAME ||
14
- process.env.FUNCTIONS_WORKER_RUNTIME);
15
- export class UniversalMemoryManager {
16
- constructor() {
17
- // CRITICAL FIX: Never use worker threads with ONNX Runtime
18
- // Worker threads cause HandleScope V8 API errors due to isolate issues
19
- // Always use direct embedding on main thread for ONNX compatibility
20
- this.embeddingFunction = null;
21
- this.embedCount = 0;
22
- this.restartCount = 0;
23
- this.lastRestart = 0;
24
- if (isServerless) {
25
- this.strategy = 'serverless-restart';
26
- this.maxEmbeddings = 50; // Restart frequently in serverless
27
- }
28
- else if (isNode && !isBrowser) {
29
- // CHANGED: Use direct strategy instead of node-worker to avoid V8 isolate issues
30
- this.strategy = 'node-direct';
31
- this.maxEmbeddings = 200; // Main thread can handle more with single model instance
32
- }
33
- else if (isBrowser) {
34
- this.strategy = 'browser-dispose';
35
- this.maxEmbeddings = 25; // Browser memory is limited
36
- }
37
- else {
38
- this.strategy = 'fallback-dispose';
39
- this.maxEmbeddings = 75;
40
- }
41
- console.log(`๐Ÿง  Universal Memory Manager: Using ${this.strategy} strategy`);
42
- console.log('โœ… UNIVERSAL: Memory-safe embedding system initialized');
43
- }
44
- async getEmbeddingFunction() {
45
- return async (data) => {
46
- return this.embed(data);
47
- };
48
- }
49
- async embed(data) {
50
- // Check if we need to restart/cleanup
51
- await this.checkMemoryLimits();
52
- // Ensure embedding function is available
53
- await this.ensureEmbeddingFunction();
54
- // Perform embedding
55
- const result = await this.embeddingFunction.embed(data);
56
- this.embedCount++;
57
- return result;
58
- }
59
- async checkMemoryLimits() {
60
- if (this.embedCount >= this.maxEmbeddings) {
61
- console.log(`๐Ÿ”„ Memory cleanup: ${this.embedCount} embeddings processed`);
62
- await this.cleanup();
63
- }
64
- }
65
- async ensureEmbeddingFunction() {
66
- if (this.embeddingFunction) {
67
- return;
68
- }
69
- switch (this.strategy) {
70
- case 'node-direct':
71
- await this.initNodeDirect();
72
- break;
73
- case 'serverless-restart':
74
- await this.initServerless();
75
- break;
76
- case 'browser-dispose':
77
- await this.initBrowser();
78
- break;
79
- default:
80
- await this.initFallback();
81
- }
82
- }
83
- async initNodeDirect() {
84
- if (isNode) {
85
- // CRITICAL: Use direct embedding to avoid worker thread V8 isolate issues
86
- // This prevents HandleScope errors and ensures single model instance
87
- console.log('โœ… Using Node.js direct embedding (main thread - ONNX compatible)');
88
- await this.initDirect();
89
- }
90
- }
91
- async initServerless() {
92
- // In serverless, use direct embedding but restart more aggressively
93
- await this.initDirect();
94
- console.log('โœ… Using serverless strategy with aggressive cleanup');
95
- }
96
- async initBrowser() {
97
- // In browser, use direct embedding with disposal
98
- await this.initDirect();
99
- console.log('โœ… Using browser strategy with disposal');
100
- }
101
- async initFallback() {
102
- await this.initDirect();
103
- console.log('โœ… Using fallback direct embedding strategy');
104
- }
105
- async initDirect() {
106
- try {
107
- // Dynamic import to handle different environments
108
- const { TransformerEmbedding } = await import('../utils/embedding.js');
109
- this.embeddingFunction = new TransformerEmbedding({
110
- verbose: false,
111
- precision: getModelPrecision(), // Use centrally managed precision
112
- localFilesOnly: process.env.BRAINY_ALLOW_REMOTE_MODELS !== 'true'
113
- });
114
- await this.embeddingFunction.init();
115
- console.log('โœ… Direct embedding function initialized');
116
- }
117
- catch (error) {
118
- throw new Error(`Failed to initialize embedding function: ${error instanceof Error ? error.message : String(error)}`);
119
- }
120
- }
121
- async cleanup() {
122
- const startTime = Date.now();
123
- // SingletonModelManager persists - we just reset our counters
124
- // The singleton model stays alive for consistency across all operations
125
- // Reset counters
126
- this.embedCount = 0;
127
- this.restartCount++;
128
- this.lastRestart = Date.now();
129
- const cleanupTime = Date.now() - startTime;
130
- console.log(`๐Ÿงน Memory counters reset in ${cleanupTime}ms (strategy: ${this.strategy})`);
131
- console.log('โ„น๏ธ Singleton model persists for consistency across all operations');
132
- }
133
- getMemoryStats() {
134
- let memoryUsage = 'unknown';
135
- // Get memory stats based on environment
136
- if (isNode && typeof process !== 'undefined') {
137
- const mem = process.memoryUsage();
138
- memoryUsage = `${(mem.heapUsed / 1024 / 1024).toFixed(2)} MB`;
139
- }
140
- else if (isBrowser && performance.memory) {
141
- const mem = performance.memory;
142
- memoryUsage = `${(mem.usedJSHeapSize / 1024 / 1024).toFixed(2)} MB`;
143
- }
144
- return {
145
- embeddings: this.embedCount,
146
- memoryUsage,
147
- restarts: this.restartCount,
148
- strategy: this.strategy
149
- };
150
- }
151
- async dispose() {
152
- // SingletonModelManager persists - nothing to dispose
153
- console.log('โ„น๏ธ Universal Memory Manager: Singleton model persists');
154
- }
155
- }
156
- // Export singleton instance
157
- export const universalMemoryManager = new UniversalMemoryManager();
158
- // Export convenience function
159
- export async function getUniversalEmbeddingFunction() {
160
- return universalMemoryManager.getEmbeddingFunction();
161
- }
162
- // Export memory stats function
163
- export function getEmbeddingMemoryStats() {
164
- return universalMemoryManager.getMemoryStats();
165
- }
166
- //# sourceMappingURL=universal-memory-manager.js.map
@@ -1,7 +0,0 @@
1
- /**
2
- * Worker process for embeddings - Workaround for transformers.js memory leak
3
- *
4
- * This worker can be killed and restarted to release memory completely.
5
- * Based on 2024 research: dispose() doesn't fully free memory in transformers.js
6
- */
7
- export {};