@soulcraft/brainy 3.5.1 → 3.7.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/dist/augmentations/auditLogAugmentation.js +1 -1
- package/dist/augmentations/configResolver.js +52 -31
- package/dist/augmentations/discovery/localDiscovery.d.ts +2 -0
- package/dist/augmentations/discovery/localDiscovery.js +20 -2
- package/dist/critical/model-guardian.js +40 -22
- package/dist/embeddings/EmbeddingManager.d.ts +4 -0
- package/dist/embeddings/EmbeddingManager.js +61 -19
- package/dist/utils/embedding.js +2 -2
- package/dist/utils/paramValidation.js +29 -5
- package/dist/utils/structuredLogger.js +15 -4
- package/dist/utils/version.d.ts +8 -0
- package/dist/utils/version.js +65 -18
- package/package.json +6 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Provides comprehensive audit trail for all Brainy operations
|
|
4
4
|
*/
|
|
5
5
|
import { BaseAugmentation } from './brainyAugmentation.js';
|
|
6
|
-
import { createHash } from '
|
|
6
|
+
import { createHash } from '../universal/crypto.js';
|
|
7
7
|
/**
|
|
8
8
|
* Audit Log Augmentation
|
|
9
9
|
*/
|
|
@@ -7,9 +7,7 @@
|
|
|
7
7
|
* - Runtime updates
|
|
8
8
|
* - Default values from schema
|
|
9
9
|
*/
|
|
10
|
-
import {
|
|
11
|
-
import { join } from 'node:path';
|
|
12
|
-
import { homedir } from 'node:os';
|
|
10
|
+
import { isNode } from '../utils/environment.js';
|
|
13
11
|
/**
|
|
14
12
|
* Configuration source priority (highest to lowest)
|
|
15
13
|
*/
|
|
@@ -29,14 +27,28 @@ export class AugmentationConfigResolver {
|
|
|
29
27
|
this.options = options;
|
|
30
28
|
this.sources = [];
|
|
31
29
|
this.resolved = {};
|
|
30
|
+
// Default config paths - include home directory paths only in Node.js
|
|
31
|
+
const defaultConfigPaths = [
|
|
32
|
+
'.brainyrc',
|
|
33
|
+
'.brainyrc.json',
|
|
34
|
+
'brainy.config.json'
|
|
35
|
+
];
|
|
36
|
+
// Add home directory paths in Node.js environments
|
|
37
|
+
if (isNode()) {
|
|
38
|
+
try {
|
|
39
|
+
const nodeRequire = typeof require !== 'undefined' ? require : null;
|
|
40
|
+
if (nodeRequire) {
|
|
41
|
+
const path = nodeRequire('node:path');
|
|
42
|
+
const os = nodeRequire('node:os');
|
|
43
|
+
defaultConfigPaths.push(path.join(os.homedir(), '.brainy', 'config.json'), path.join(os.homedir(), '.brainyrc'));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Silently continue without home directory paths
|
|
48
|
+
}
|
|
49
|
+
}
|
|
32
50
|
this.options = {
|
|
33
|
-
configPaths:
|
|
34
|
-
'.brainyrc',
|
|
35
|
-
'.brainyrc.json',
|
|
36
|
-
'brainy.config.json',
|
|
37
|
-
join(homedir(), '.brainy', 'config.json'),
|
|
38
|
-
join(homedir(), '.brainyrc')
|
|
39
|
-
],
|
|
51
|
+
configPaths: defaultConfigPaths,
|
|
40
52
|
envPrefix: `BRAINY_AUG_${options.augmentationId.toUpperCase()}_`,
|
|
41
53
|
allowUndefined: true,
|
|
42
54
|
...options
|
|
@@ -98,30 +110,39 @@ export class AugmentationConfigResolver {
|
|
|
98
110
|
*/
|
|
99
111
|
loadFromFiles() {
|
|
100
112
|
// Skip in browser environment
|
|
101
|
-
if (
|
|
113
|
+
if (!isNode()) {
|
|
102
114
|
return;
|
|
103
115
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
try {
|
|
117
|
+
const nodeRequire = typeof require !== 'undefined' ? require : null;
|
|
118
|
+
if (!nodeRequire)
|
|
119
|
+
return;
|
|
120
|
+
const fs = nodeRequire('node:fs');
|
|
121
|
+
for (const configPath of this.options.configPaths || []) {
|
|
122
|
+
try {
|
|
123
|
+
if (fs.existsSync(configPath)) {
|
|
124
|
+
const content = fs.readFileSync(configPath, 'utf8');
|
|
125
|
+
const config = this.parseConfigFile(content, configPath);
|
|
126
|
+
// Extract augmentation-specific configuration
|
|
127
|
+
const augConfig = this.extractAugmentationConfig(config);
|
|
128
|
+
if (augConfig && Object.keys(augConfig).length > 0) {
|
|
129
|
+
this.sources.push({
|
|
130
|
+
priority: ConfigPriority.FILE,
|
|
131
|
+
source: `file:${configPath}`,
|
|
132
|
+
config: augConfig
|
|
133
|
+
});
|
|
134
|
+
break; // Use first found config file
|
|
135
|
+
}
|
|
118
136
|
}
|
|
119
137
|
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
// Silently ignore file errors
|
|
140
|
+
console.debug(`Failed to load config from ${configPath}:`, error);
|
|
141
|
+
}
|
|
120
142
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
// Silently continue if require fails
|
|
125
146
|
}
|
|
126
147
|
}
|
|
127
148
|
/**
|
|
@@ -162,7 +183,7 @@ export class AugmentationConfigResolver {
|
|
|
162
183
|
*/
|
|
163
184
|
loadFromEnvironment() {
|
|
164
185
|
// Skip in browser environment
|
|
165
|
-
if (
|
|
186
|
+
if (!isNode() || !process.env) {
|
|
166
187
|
return;
|
|
167
188
|
}
|
|
168
189
|
const prefix = this.options.envPrefix;
|
|
@@ -376,7 +397,7 @@ export class AugmentationConfigResolver {
|
|
|
376
397
|
*/
|
|
377
398
|
async saveToFile(filepath, format = 'json') {
|
|
378
399
|
// Skip in browser environment
|
|
379
|
-
if (
|
|
400
|
+
if (!isNode()) {
|
|
380
401
|
throw new Error('Cannot save configuration files in browser environment');
|
|
381
402
|
}
|
|
382
403
|
const fs = await import('node:fs');
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Discovers augmentations installed locally in node_modules
|
|
5
5
|
* and built-in augmentations that ship with Brainy
|
|
6
|
+
*
|
|
7
|
+
* NOTE: This is a Node.js-only feature that requires filesystem access
|
|
6
8
|
*/
|
|
7
9
|
import { AugmentationManifest } from '../manifest.js';
|
|
8
10
|
export interface LocalAugmentation {
|
|
@@ -3,9 +3,27 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Discovers augmentations installed locally in node_modules
|
|
5
5
|
* and built-in augmentations that ship with Brainy
|
|
6
|
+
*
|
|
7
|
+
* NOTE: This is a Node.js-only feature that requires filesystem access
|
|
6
8
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
// Node.js modules - dynamically imported to avoid bundler issues
|
|
10
|
+
let fs = null;
|
|
11
|
+
let path = null;
|
|
12
|
+
// Load Node.js modules if available
|
|
13
|
+
if (typeof window === 'undefined') {
|
|
14
|
+
try {
|
|
15
|
+
fs = await import('node:fs');
|
|
16
|
+
path = await import('node:path');
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
// Will throw error in methods if not available
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Create compatibility layer for sync methods
|
|
23
|
+
const existsSync = fs?.existsSync || (() => { throw new Error('Filesystem not available'); });
|
|
24
|
+
const readdirSync = fs?.readdirSync || (() => { throw new Error('Filesystem not available'); });
|
|
25
|
+
const readFileSync = fs?.readFileSync || (() => { throw new Error('Filesystem not available'); });
|
|
26
|
+
const join = path?.join || ((...args) => args.join('/'));
|
|
9
27
|
/**
|
|
10
28
|
* Discovers augmentations installed locally
|
|
11
29
|
*/
|
|
@@ -10,9 +10,6 @@
|
|
|
10
10
|
* 3. Model MUST produce consistent 384-dim embeddings
|
|
11
11
|
* 4. System MUST fail fast if model unavailable in production
|
|
12
12
|
*/
|
|
13
|
-
import { existsSync } from 'node:fs';
|
|
14
|
-
import { stat } from 'node:fs/promises';
|
|
15
|
-
import { join } from 'node:path';
|
|
16
13
|
import { env } from '@huggingface/transformers';
|
|
17
14
|
// CRITICAL: These values MUST NEVER CHANGE
|
|
18
15
|
const CRITICAL_MODEL_CONFIG = {
|
|
@@ -87,8 +84,8 @@ export class ModelGuardian {
|
|
|
87
84
|
this.configureTransformers();
|
|
88
85
|
return;
|
|
89
86
|
}
|
|
90
|
-
// Step 2: In production, FAIL FAST
|
|
91
|
-
if (process.env.NODE_ENV === 'production' && !process.env.BRAINY_ALLOW_RUNTIME_DOWNLOAD) {
|
|
87
|
+
// Step 2: In production, FAIL FAST (Node.js only)
|
|
88
|
+
if (typeof window === 'undefined' && process.env.NODE_ENV === 'production' && !process.env.BRAINY_ALLOW_RUNTIME_DOWNLOAD) {
|
|
92
89
|
throw new Error('🚨 CRITICAL FAILURE: Transformer model not found in production!\n' +
|
|
93
90
|
'The model is REQUIRED for Brainy to function.\n' +
|
|
94
91
|
'Users CANNOT access their data without it.\n' +
|
|
@@ -124,7 +121,16 @@ export class ModelGuardian {
|
|
|
124
121
|
* Verify the local model files exist and are correct
|
|
125
122
|
*/
|
|
126
123
|
async verifyLocalModel() {
|
|
127
|
-
|
|
124
|
+
// Browser doesn't have local file access
|
|
125
|
+
if (typeof window !== 'undefined') {
|
|
126
|
+
console.log('⚠️ Model verification skipped in browser environment');
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
// Dynamically import Node.js modules
|
|
130
|
+
const fs = await import('node:fs');
|
|
131
|
+
const fsPromises = await import('node:fs/promises');
|
|
132
|
+
const path = await import('node:path');
|
|
133
|
+
const modelBasePath = path.join(this.modelPath, ...CRITICAL_MODEL_CONFIG.modelName.split('/'));
|
|
128
134
|
console.log(`🔍 Debug: Checking model at path: ${modelBasePath}`);
|
|
129
135
|
console.log(`🔍 Debug: Model path components: ${this.modelPath} + ${CRITICAL_MODEL_CONFIG.modelName.split('/')}`);
|
|
130
136
|
// Check critical files
|
|
@@ -134,15 +140,15 @@ export class ModelGuardian {
|
|
|
134
140
|
'config.json'
|
|
135
141
|
];
|
|
136
142
|
for (const file of criticalFiles) {
|
|
137
|
-
const filePath = join(modelBasePath, file);
|
|
143
|
+
const filePath = path.join(modelBasePath, file);
|
|
138
144
|
console.log(`🔍 Debug: Checking file: ${filePath}`);
|
|
139
|
-
if (!existsSync(filePath)) {
|
|
145
|
+
if (!fs.existsSync(filePath)) {
|
|
140
146
|
console.log(`❌ Missing critical file: ${file} at ${filePath}`);
|
|
141
147
|
return false;
|
|
142
148
|
}
|
|
143
149
|
// Verify size for critical files
|
|
144
150
|
if (CRITICAL_MODEL_CONFIG.modelSize[file]) {
|
|
145
|
-
const stats = await stat(filePath);
|
|
151
|
+
const stats = await fsPromises.stat(filePath);
|
|
146
152
|
const expectedSize = CRITICAL_MODEL_CONFIG.modelSize[file];
|
|
147
153
|
if (Math.abs(stats.size - expectedSize) > 1000) { // Allow 1KB variance
|
|
148
154
|
console.error(`❌ CRITICAL: Model file size mismatch!\n` +
|
|
@@ -220,22 +226,34 @@ export class ModelGuardian {
|
|
|
220
226
|
* Detect where models should be stored
|
|
221
227
|
*/
|
|
222
228
|
detectModelPath() {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
'./models'
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
229
|
+
// Browser always uses default path
|
|
230
|
+
if (typeof window !== 'undefined') {
|
|
231
|
+
return './models';
|
|
232
|
+
}
|
|
233
|
+
// Use require for synchronous access in Node.js
|
|
234
|
+
try {
|
|
235
|
+
const fs = require('node:fs');
|
|
236
|
+
const path = require('node:path');
|
|
237
|
+
const candidates = [
|
|
238
|
+
process.env.BRAINY_MODELS_PATH,
|
|
239
|
+
'./models',
|
|
240
|
+
path.join(process.cwd(), 'models'),
|
|
241
|
+
path.join(process.env.HOME || '', '.brainy', 'models'),
|
|
242
|
+
'/opt/models', // Lambda/container path
|
|
243
|
+
env.cacheDir
|
|
244
|
+
];
|
|
245
|
+
for (const candidatePath of candidates) {
|
|
246
|
+
if (candidatePath && fs.existsSync(candidatePath)) {
|
|
247
|
+
const modelPath = path.join(candidatePath, ...CRITICAL_MODEL_CONFIG.modelName.split('/'));
|
|
248
|
+
if (fs.existsSync(path.join(modelPath, 'onnx', 'model.onnx'))) {
|
|
249
|
+
return candidatePath; // Return the models directory, not its parent
|
|
250
|
+
}
|
|
236
251
|
}
|
|
237
252
|
}
|
|
238
253
|
}
|
|
254
|
+
catch (e) {
|
|
255
|
+
// If Node.js modules not available, return default
|
|
256
|
+
}
|
|
239
257
|
// Default
|
|
240
258
|
return './models';
|
|
241
259
|
}
|
|
@@ -63,8 +63,12 @@ export declare class EmbeddingManager {
|
|
|
63
63
|
getEmbeddingFunction(): EmbeddingFunction;
|
|
64
64
|
/**
|
|
65
65
|
* Get models directory path
|
|
66
|
+
* Note: In browser environments, returns a simple default path
|
|
67
|
+
* In Node.js, checks multiple locations for the models directory
|
|
66
68
|
*/
|
|
67
69
|
private getModelsPath;
|
|
70
|
+
private modelsPathCache;
|
|
71
|
+
private resolveModelsPathSync;
|
|
68
72
|
/**
|
|
69
73
|
* Get memory usage in MB
|
|
70
74
|
*/
|
|
@@ -16,8 +16,7 @@
|
|
|
16
16
|
* hybridModelManager, universalMemoryManager, and more.
|
|
17
17
|
*/
|
|
18
18
|
import { pipeline, env } from '@huggingface/transformers';
|
|
19
|
-
import {
|
|
20
|
-
import { join } from 'node:path';
|
|
19
|
+
import { isNode } from '../utils/environment.js';
|
|
21
20
|
// Global state for true singleton across entire process
|
|
22
21
|
let globalInstance = null;
|
|
23
22
|
let globalInitPromise = null;
|
|
@@ -32,6 +31,7 @@ export class EmbeddingManager {
|
|
|
32
31
|
this.initTime = null;
|
|
33
32
|
this.embedCount = 0;
|
|
34
33
|
this.locked = false;
|
|
34
|
+
this.modelsPathCache = null;
|
|
35
35
|
// Always use Q8 for optimal size/performance (99% accuracy, 75% smaller)
|
|
36
36
|
this.precision = 'q8';
|
|
37
37
|
console.log(`🎯 EmbeddingManager: Using Q8 precision`);
|
|
@@ -95,11 +95,23 @@ export class EmbeddingManager {
|
|
|
95
95
|
env.cacheDir = modelsPath;
|
|
96
96
|
env.allowLocalModels = true;
|
|
97
97
|
env.useFSCache = true;
|
|
98
|
-
// Check if models exist locally
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
98
|
+
// Check if models exist locally (only in Node.js)
|
|
99
|
+
if (isNode()) {
|
|
100
|
+
try {
|
|
101
|
+
const nodeRequire = typeof require !== 'undefined' ? require : null;
|
|
102
|
+
if (nodeRequire) {
|
|
103
|
+
const path = nodeRequire('node:path');
|
|
104
|
+
const fs = nodeRequire('node:fs');
|
|
105
|
+
const modelPath = path.join(modelsPath, ...this.modelName.split('/'));
|
|
106
|
+
const hasLocalModels = fs.existsSync(modelPath);
|
|
107
|
+
if (hasLocalModels) {
|
|
108
|
+
console.log('✅ Using cached models from:', modelPath);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Silently continue if require fails
|
|
114
|
+
}
|
|
103
115
|
}
|
|
104
116
|
// Configure pipeline options for the selected precision
|
|
105
117
|
const pipelineOptions = {
|
|
@@ -206,22 +218,52 @@ export class EmbeddingManager {
|
|
|
206
218
|
}
|
|
207
219
|
/**
|
|
208
220
|
* Get models directory path
|
|
221
|
+
* Note: In browser environments, returns a simple default path
|
|
222
|
+
* In Node.js, checks multiple locations for the models directory
|
|
209
223
|
*/
|
|
210
224
|
getModelsPath() {
|
|
211
|
-
//
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
225
|
+
// In browser environments, use a default path
|
|
226
|
+
if (!isNode()) {
|
|
227
|
+
return './models';
|
|
228
|
+
}
|
|
229
|
+
// Node.js-specific model path resolution
|
|
230
|
+
// Cache the result for performance
|
|
231
|
+
if (!this.modelsPathCache) {
|
|
232
|
+
this.modelsPathCache = this.resolveModelsPathSync();
|
|
233
|
+
}
|
|
234
|
+
return this.modelsPathCache;
|
|
235
|
+
}
|
|
236
|
+
resolveModelsPathSync() {
|
|
237
|
+
// For Node.js environments, we can safely assume these modules exist
|
|
238
|
+
// TypeScript will handle the imports at build time
|
|
239
|
+
// At runtime, these will only be called if isNode() is true
|
|
240
|
+
// Default fallback path
|
|
241
|
+
const defaultPath = './models';
|
|
242
|
+
try {
|
|
243
|
+
// Create a conditional require function that only works in Node
|
|
244
|
+
const nodeRequire = typeof require !== 'undefined' ? require : null;
|
|
245
|
+
if (!nodeRequire)
|
|
246
|
+
return defaultPath;
|
|
247
|
+
const fs = nodeRequire('node:fs');
|
|
248
|
+
const path = nodeRequire('node:path');
|
|
249
|
+
const paths = [
|
|
250
|
+
process.env.BRAINY_MODELS_PATH,
|
|
251
|
+
'./models',
|
|
252
|
+
path.join(process.cwd(), 'models'),
|
|
253
|
+
path.join(process.env.HOME || '', '.brainy', 'models')
|
|
254
|
+
];
|
|
255
|
+
for (const p of paths) {
|
|
256
|
+
if (p && fs.existsSync(p)) {
|
|
257
|
+
return p;
|
|
258
|
+
}
|
|
221
259
|
}
|
|
260
|
+
// Default Node.js path
|
|
261
|
+
return path.join(process.cwd(), 'models');
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
// Fallback if require fails
|
|
265
|
+
return defaultPath;
|
|
222
266
|
}
|
|
223
|
-
// Default
|
|
224
|
-
return join(process.cwd(), 'models');
|
|
225
267
|
}
|
|
226
268
|
/**
|
|
227
269
|
* Get memory usage in MB
|
package/dist/utils/embedding.js
CHANGED
|
@@ -161,8 +161,8 @@ export class TransformerEmbedding {
|
|
|
161
161
|
// Use dynamic import instead of require for ES modules compatibility
|
|
162
162
|
const { createRequire } = await import('module');
|
|
163
163
|
const require = createRequire(import.meta.url);
|
|
164
|
-
const path = require('path');
|
|
165
|
-
const fs = require('fs');
|
|
164
|
+
const path = require('node:path');
|
|
165
|
+
const fs = require('node:fs');
|
|
166
166
|
// Try to resolve the package location
|
|
167
167
|
try {
|
|
168
168
|
const brainyPackagePath = require.resolve('@soulcraft/brainy/package.json');
|
|
@@ -5,7 +5,31 @@
|
|
|
5
5
|
* Only enforces universal truths, learns everything else
|
|
6
6
|
*/
|
|
7
7
|
import { NounType, VerbType } from '../types/graphTypes.js';
|
|
8
|
-
import
|
|
8
|
+
// Dynamic import for Node.js os module
|
|
9
|
+
let os = null;
|
|
10
|
+
if (typeof window === 'undefined') {
|
|
11
|
+
try {
|
|
12
|
+
os = await import('node:os');
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
// OS module not available
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// Browser-safe memory detection
|
|
19
|
+
const getSystemMemory = () => {
|
|
20
|
+
if (os) {
|
|
21
|
+
return os.totalmem();
|
|
22
|
+
}
|
|
23
|
+
// Browser fallback: assume 4GB
|
|
24
|
+
return 4 * 1024 * 1024 * 1024;
|
|
25
|
+
};
|
|
26
|
+
const getAvailableMemory = () => {
|
|
27
|
+
if (os) {
|
|
28
|
+
return os.freemem();
|
|
29
|
+
}
|
|
30
|
+
// Browser fallback: assume 2GB available
|
|
31
|
+
return 2 * 1024 * 1024 * 1024;
|
|
32
|
+
};
|
|
9
33
|
/**
|
|
10
34
|
* Auto-configured limits based on system resources
|
|
11
35
|
* These adapt to available memory and observed performance
|
|
@@ -16,8 +40,8 @@ class ValidationConfig {
|
|
|
16
40
|
this.avgQueryTime = 0;
|
|
17
41
|
this.queryCount = 0;
|
|
18
42
|
// Auto-configure based on system resources
|
|
19
|
-
const totalMemory =
|
|
20
|
-
const availableMemory =
|
|
43
|
+
const totalMemory = getSystemMemory();
|
|
44
|
+
const availableMemory = getAvailableMemory();
|
|
21
45
|
// Scale limits based on available memory
|
|
22
46
|
// 1GB = 10K limit, 8GB = 80K limit, etc.
|
|
23
47
|
this.maxLimit = Math.min(100000, // Absolute max for safety
|
|
@@ -179,8 +203,8 @@ export function getValidationConfig() {
|
|
|
179
203
|
maxLimit: config.maxLimit,
|
|
180
204
|
maxQueryLength: config.maxQueryLength,
|
|
181
205
|
maxVectorDimensions: config.maxVectorDimensions,
|
|
182
|
-
systemMemory:
|
|
183
|
-
availableMemory:
|
|
206
|
+
systemMemory: getSystemMemory(),
|
|
207
|
+
availableMemory: getAvailableMemory()
|
|
184
208
|
};
|
|
185
209
|
}
|
|
186
210
|
/**
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* performance tracking, and multiple transport support
|
|
5
5
|
*/
|
|
6
6
|
import { performance } from 'perf_hooks';
|
|
7
|
-
import {
|
|
8
|
-
import { randomUUID } from 'node:crypto';
|
|
7
|
+
import { randomUUID } from '../universal/crypto.js';
|
|
9
8
|
export var LogLevel;
|
|
10
9
|
(function (LogLevel) {
|
|
11
10
|
LogLevel[LogLevel["SILENT"] = -1] = "SILENT";
|
|
@@ -214,9 +213,21 @@ export class StructuredLogger {
|
|
|
214
213
|
};
|
|
215
214
|
}
|
|
216
215
|
if (this.config.includeHost) {
|
|
217
|
-
|
|
216
|
+
// Use dynamic import for hostname (Node.js only)
|
|
217
|
+
if (typeof window === 'undefined') {
|
|
218
|
+
try {
|
|
219
|
+
const os = require('node:os');
|
|
220
|
+
entry.host = os.hostname();
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
entry.host = 'unknown';
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
entry.host = window.location?.hostname || 'browser';
|
|
228
|
+
}
|
|
218
229
|
}
|
|
219
|
-
if (this.config.includeMemory) {
|
|
230
|
+
if (this.config.includeMemory && typeof process !== 'undefined' && process.memoryUsage) {
|
|
220
231
|
const mem = process.memoryUsage();
|
|
221
232
|
entry.performance = {
|
|
222
233
|
memory: {
|
package/dist/utils/version.d.ts
CHANGED
|
@@ -3,9 +3,17 @@
|
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
5
|
* Get the current Brainy package version
|
|
6
|
+
* In Node.js, attempts to read from package.json
|
|
7
|
+
* In browser, returns the default version
|
|
6
8
|
* @returns The current version string
|
|
7
9
|
*/
|
|
8
10
|
export declare function getBrainyVersion(): string;
|
|
11
|
+
/**
|
|
12
|
+
* Get the current Brainy package version asynchronously
|
|
13
|
+
* Guaranteed to attempt loading from package.json in Node.js
|
|
14
|
+
* @returns Promise resolving to the current version string
|
|
15
|
+
*/
|
|
16
|
+
export declare function getBrainyVersionAsync(): Promise<string>;
|
|
9
17
|
/**
|
|
10
18
|
* Get version information for augmentation metadata
|
|
11
19
|
* @param service The service/augmentation name
|
package/dist/utils/version.js
CHANGED
|
@@ -1,30 +1,77 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Version utilities for Brainy
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// Get package.json path relative to this file
|
|
8
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
-
const __dirname = dirname(__filename);
|
|
10
|
-
const packageJsonPath = join(__dirname, '../../package.json');
|
|
4
|
+
import { isNode } from './environment.js';
|
|
5
|
+
// Default version - this should be replaced at build time
|
|
6
|
+
const DEFAULT_VERSION = '3.5.1';
|
|
11
7
|
let cachedVersion = null;
|
|
8
|
+
let versionPromise = null;
|
|
9
|
+
/**
|
|
10
|
+
* Load version from package.json in Node.js environment
|
|
11
|
+
*/
|
|
12
|
+
async function loadVersionFromPackageJson() {
|
|
13
|
+
if (!isNode()) {
|
|
14
|
+
return DEFAULT_VERSION;
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
// Dynamic imports for Node.js modules - modern approach
|
|
18
|
+
const [{ readFileSync }, { join, dirname }, { fileURLToPath }] = await Promise.all([
|
|
19
|
+
import('node:fs'),
|
|
20
|
+
import('node:path'),
|
|
21
|
+
import('node:url')
|
|
22
|
+
]);
|
|
23
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
24
|
+
const __dirname = dirname(__filename);
|
|
25
|
+
const packageJsonPath = join(__dirname, '../../package.json');
|
|
26
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
27
|
+
return packageJson.version || DEFAULT_VERSION;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
// Silently fall back to default version
|
|
31
|
+
return DEFAULT_VERSION;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
12
34
|
/**
|
|
13
35
|
* Get the current Brainy package version
|
|
36
|
+
* In Node.js, attempts to read from package.json
|
|
37
|
+
* In browser, returns the default version
|
|
14
38
|
* @returns The current version string
|
|
15
39
|
*/
|
|
16
40
|
export function getBrainyVersion() {
|
|
17
|
-
if (
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
41
|
+
if (cachedVersion) {
|
|
42
|
+
return cachedVersion;
|
|
43
|
+
}
|
|
44
|
+
// In browser or if we need immediate response, return default
|
|
45
|
+
if (!isNode()) {
|
|
46
|
+
cachedVersion = DEFAULT_VERSION;
|
|
47
|
+
return cachedVersion;
|
|
48
|
+
}
|
|
49
|
+
// For Node.js, try to load synchronously first time
|
|
50
|
+
// This is a compromise for backward compatibility
|
|
51
|
+
if (!versionPromise) {
|
|
52
|
+
versionPromise = loadVersionFromPackageJson();
|
|
53
|
+
versionPromise.then(version => {
|
|
54
|
+
cachedVersion = version;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// Return default while loading
|
|
58
|
+
return cachedVersion || DEFAULT_VERSION;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get the current Brainy package version asynchronously
|
|
62
|
+
* Guaranteed to attempt loading from package.json in Node.js
|
|
63
|
+
* @returns Promise resolving to the current version string
|
|
64
|
+
*/
|
|
65
|
+
export async function getBrainyVersionAsync() {
|
|
66
|
+
if (cachedVersion) {
|
|
67
|
+
return cachedVersion;
|
|
68
|
+
}
|
|
69
|
+
if (!versionPromise) {
|
|
70
|
+
versionPromise = loadVersionFromPackageJson();
|
|
71
|
+
}
|
|
72
|
+
const version = await versionPromise;
|
|
73
|
+
cachedVersion = version;
|
|
74
|
+
return version;
|
|
28
75
|
}
|
|
29
76
|
/**
|
|
30
77
|
* Get version information for augmentation metadata
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soulcraft/brainy",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.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",
|
|
@@ -41,6 +41,11 @@
|
|
|
41
41
|
"types": "./dist/universal/index.d.ts"
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
|
+
"browser": {
|
|
45
|
+
"./dist/distributed": false,
|
|
46
|
+
"./dist/cli": false,
|
|
47
|
+
"./dist/scripts": false
|
|
48
|
+
},
|
|
44
49
|
"engines": {
|
|
45
50
|
"node": "22.x"
|
|
46
51
|
},
|