@soulcraft/brainy 3.0.0 โ 3.1.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 +53 -3
- package/README.md +427 -111
- package/bin/brainy.js +340 -62
- package/dist/api/ConfigAPI.d.ts +67 -0
- package/dist/api/ConfigAPI.js +166 -0
- package/dist/api/DataAPI.d.ts +123 -0
- package/dist/api/DataAPI.js +391 -0
- package/dist/api/SecurityAPI.d.ts +50 -0
- package/dist/api/SecurityAPI.js +139 -0
- package/dist/api/UniversalImportAPI.d.ts +134 -0
- package/dist/api/UniversalImportAPI.js +615 -0
- package/dist/augmentationManager.js +12 -7
- package/dist/augmentationPipeline.d.ts +0 -61
- package/dist/augmentationPipeline.js +0 -87
- package/dist/augmentationRegistry.d.ts +1 -1
- package/dist/augmentationRegistry.js +1 -1
- package/dist/augmentations/apiServerAugmentation.d.ts +27 -1
- package/dist/augmentations/apiServerAugmentation.js +290 -9
- package/dist/augmentations/auditLogAugmentation.d.ts +109 -0
- package/dist/augmentations/auditLogAugmentation.js +358 -0
- package/dist/augmentations/batchProcessingAugmentation.d.ts +3 -2
- package/dist/augmentations/batchProcessingAugmentation.js +123 -22
- package/dist/augmentations/brainyAugmentation.d.ts +142 -8
- package/dist/augmentations/brainyAugmentation.js +179 -2
- package/dist/augmentations/cacheAugmentation.d.ts +8 -5
- package/dist/augmentations/cacheAugmentation.js +116 -17
- package/dist/augmentations/conduitAugmentations.d.ts +2 -2
- package/dist/augmentations/conduitAugmentations.js +2 -2
- package/dist/augmentations/configResolver.d.ts +122 -0
- package/dist/augmentations/configResolver.js +440 -0
- package/dist/augmentations/connectionPoolAugmentation.d.ts +3 -1
- package/dist/augmentations/connectionPoolAugmentation.js +37 -12
- package/dist/augmentations/defaultAugmentations.d.ts +14 -10
- package/dist/augmentations/defaultAugmentations.js +16 -11
- package/dist/augmentations/discovery/catalogDiscovery.d.ts +142 -0
- package/dist/augmentations/discovery/catalogDiscovery.js +249 -0
- package/dist/augmentations/discovery/localDiscovery.d.ts +84 -0
- package/dist/augmentations/discovery/localDiscovery.js +246 -0
- package/dist/augmentations/discovery/runtimeLoader.d.ts +97 -0
- package/dist/augmentations/discovery/runtimeLoader.js +337 -0
- package/dist/augmentations/discovery.d.ts +152 -0
- package/dist/augmentations/discovery.js +441 -0
- package/dist/augmentations/display/cache.d.ts +130 -0
- package/dist/augmentations/display/cache.js +319 -0
- package/dist/augmentations/display/fieldPatterns.d.ts +52 -0
- package/dist/augmentations/display/fieldPatterns.js +393 -0
- package/dist/augmentations/display/iconMappings.d.ts +57 -0
- package/dist/augmentations/display/iconMappings.js +68 -0
- package/dist/augmentations/display/intelligentComputation.d.ts +109 -0
- package/dist/augmentations/display/intelligentComputation.js +462 -0
- package/dist/augmentations/display/types.d.ts +203 -0
- package/dist/augmentations/display/types.js +7 -0
- package/dist/augmentations/entityRegistryAugmentation.d.ts +3 -1
- package/dist/augmentations/entityRegistryAugmentation.js +5 -1
- package/dist/augmentations/indexAugmentation.d.ts +5 -3
- package/dist/augmentations/indexAugmentation.js +5 -2
- package/dist/augmentations/intelligentVerbScoringAugmentation.d.ts +24 -7
- package/dist/augmentations/intelligentVerbScoringAugmentation.js +111 -27
- package/dist/augmentations/manifest.d.ts +176 -0
- package/dist/augmentations/manifest.js +8 -0
- package/dist/augmentations/marketplace/AugmentationMarketplace.d.ts +168 -0
- package/dist/augmentations/marketplace/AugmentationMarketplace.js +329 -0
- package/dist/augmentations/marketplace/cli.d.ts +47 -0
- package/dist/augmentations/marketplace/cli.js +265 -0
- package/dist/augmentations/metricsAugmentation.d.ts +3 -3
- package/dist/augmentations/metricsAugmentation.js +2 -2
- package/dist/augmentations/monitoringAugmentation.d.ts +3 -3
- package/dist/augmentations/monitoringAugmentation.js +2 -2
- package/dist/augmentations/neuralImport.d.ts +1 -1
- package/dist/augmentations/neuralImport.js +4 -4
- package/dist/augmentations/rateLimitAugmentation.d.ts +82 -0
- package/dist/augmentations/rateLimitAugmentation.js +321 -0
- package/dist/augmentations/requestDeduplicatorAugmentation.d.ts +2 -2
- package/dist/augmentations/requestDeduplicatorAugmentation.js +1 -1
- package/dist/augmentations/storageAugmentation.d.ts +1 -1
- package/dist/augmentations/storageAugmentation.js +2 -2
- package/dist/augmentations/storageAugmentations.d.ts +37 -8
- package/dist/augmentations/storageAugmentations.js +204 -15
- package/dist/augmentations/synapseAugmentation.d.ts +1 -1
- package/dist/augmentations/synapseAugmentation.js +35 -16
- package/dist/augmentations/typeMatching/brainyTypes.d.ts +83 -0
- package/dist/augmentations/typeMatching/brainyTypes.js +425 -0
- package/dist/augmentations/typeMatching/intelligentTypeMatcher.d.ts +39 -59
- package/dist/augmentations/typeMatching/intelligentTypeMatcher.js +103 -389
- package/dist/augmentations/universalDisplayAugmentation.d.ts +191 -0
- package/dist/augmentations/universalDisplayAugmentation.js +371 -0
- package/dist/brainy-unified.d.ts +106 -0
- package/dist/brainy-unified.js +327 -0
- package/dist/brainy.d.ts +277 -0
- package/dist/brainy.js +1241 -0
- package/dist/brainyData.d.ts +56 -111
- package/dist/brainyData.js +912 -756
- package/dist/brainyDataV3.d.ts +186 -0
- package/dist/brainyDataV3.js +337 -0
- package/dist/config/distributedPresets-new.d.ts +118 -0
- package/dist/config/distributedPresets-new.js +318 -0
- package/dist/config/distributedPresets.d.ts +118 -0
- package/dist/config/distributedPresets.js +318 -0
- package/dist/config/extensibleConfig.d.ts +99 -0
- package/dist/config/extensibleConfig.js +268 -0
- package/dist/config/index.d.ts +17 -0
- package/dist/config/index.js +35 -0
- package/dist/config/modelAutoConfig.d.ts +32 -0
- package/dist/config/modelAutoConfig.js +139 -0
- package/dist/config/modelPrecisionManager.d.ts +42 -0
- package/dist/config/modelPrecisionManager.js +98 -0
- package/dist/config/sharedConfigManager.d.ts +67 -0
- package/dist/config/sharedConfigManager.js +215 -0
- package/dist/config/storageAutoConfig.d.ts +41 -0
- package/dist/config/storageAutoConfig.js +328 -0
- package/dist/config/zeroConfig.d.ts +68 -0
- package/dist/config/zeroConfig.js +301 -0
- package/dist/cortex/backupRestore.d.ts +2 -2
- package/dist/cortex/backupRestore.js +85 -27
- package/dist/cortex/healthCheck.d.ts +2 -2
- package/dist/cortex/neuralImport.d.ts +2 -2
- package/dist/cortex/neuralImport.js +18 -13
- package/dist/cortex/performanceMonitor.d.ts +2 -2
- package/dist/critical/model-guardian.d.ts +4 -0
- package/dist/critical/model-guardian.js +31 -11
- package/dist/demo.d.ts +4 -4
- package/dist/demo.js +7 -7
- package/dist/distributed/cacheSync.d.ts +112 -0
- package/dist/distributed/cacheSync.js +265 -0
- package/dist/distributed/coordinator.d.ts +193 -0
- package/dist/distributed/coordinator.js +548 -0
- package/dist/distributed/httpTransport.d.ts +120 -0
- package/dist/distributed/httpTransport.js +446 -0
- package/dist/distributed/index.d.ts +8 -0
- package/dist/distributed/index.js +5 -0
- package/dist/distributed/networkTransport.d.ts +132 -0
- package/dist/distributed/networkTransport.js +633 -0
- package/dist/distributed/queryPlanner.d.ts +104 -0
- package/dist/distributed/queryPlanner.js +327 -0
- package/dist/distributed/readWriteSeparation.d.ts +134 -0
- package/dist/distributed/readWriteSeparation.js +350 -0
- package/dist/distributed/shardManager.d.ts +114 -0
- package/dist/distributed/shardManager.js +357 -0
- package/dist/distributed/shardMigration.d.ts +110 -0
- package/dist/distributed/shardMigration.js +289 -0
- package/dist/distributed/storageDiscovery.d.ts +160 -0
- package/dist/distributed/storageDiscovery.js +551 -0
- package/dist/embeddings/CachedEmbeddings.d.ts +40 -0
- package/dist/embeddings/CachedEmbeddings.js +146 -0
- package/dist/embeddings/EmbeddingManager.d.ts +102 -0
- package/dist/embeddings/EmbeddingManager.js +291 -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/model-manager.d.ts +11 -0
- package/dist/embeddings/model-manager.js +43 -7
- package/dist/embeddings/universal-memory-manager.d.ts +1 -1
- package/dist/embeddings/universal-memory-manager.js +27 -67
- package/dist/embeddings/worker-embedding.js +4 -8
- package/dist/errors/brainyError.d.ts +5 -1
- package/dist/errors/brainyError.js +12 -0
- package/dist/examples/basicUsage.js +7 -4
- package/dist/graph/graphAdjacencyIndex.d.ts +96 -0
- package/dist/graph/graphAdjacencyIndex.js +288 -0
- package/dist/graph/pathfinding.js +4 -2
- package/dist/hnsw/scaledHNSWSystem.js +11 -2
- package/dist/importManager.js +8 -5
- package/dist/index.d.ts +17 -22
- package/dist/index.js +37 -23
- package/dist/mcp/brainyMCPAdapter.d.ts +4 -4
- package/dist/mcp/brainyMCPAdapter.js +5 -5
- package/dist/mcp/brainyMCPService.d.ts +3 -3
- package/dist/mcp/brainyMCPService.js +3 -11
- package/dist/mcp/mcpAugmentationToolset.js +20 -30
- package/dist/neural/embeddedPatterns.d.ts +1 -1
- package/dist/neural/embeddedPatterns.js +2 -2
- package/dist/neural/entityExtractor.d.ts +65 -0
- package/dist/neural/entityExtractor.js +316 -0
- package/dist/neural/improvedNeuralAPI.d.ts +357 -0
- package/dist/neural/improvedNeuralAPI.js +2628 -0
- package/dist/neural/naturalLanguageProcessor.d.ts +155 -10
- package/dist/neural/naturalLanguageProcessor.js +941 -66
- package/dist/neural/naturalLanguageProcessorStatic.d.ts +2 -2
- package/dist/neural/naturalLanguageProcessorStatic.js +3 -3
- package/dist/neural/neuralAPI.js +8 -2
- package/dist/neural/patternLibrary.d.ts +57 -3
- package/dist/neural/patternLibrary.js +348 -13
- package/dist/neural/staticPatternMatcher.d.ts +2 -2
- package/dist/neural/staticPatternMatcher.js +2 -2
- package/dist/neural/types.d.ts +287 -0
- package/dist/neural/types.js +24 -0
- package/dist/shared/default-augmentations.d.ts +3 -3
- package/dist/shared/default-augmentations.js +5 -5
- package/dist/storage/adapters/baseStorageAdapter.d.ts +42 -0
- package/dist/storage/adapters/fileSystemStorage.d.ts +26 -2
- package/dist/storage/adapters/fileSystemStorage.js +218 -15
- package/dist/storage/adapters/memoryStorage.d.ts +4 -4
- package/dist/storage/adapters/memoryStorage.js +17 -12
- package/dist/storage/adapters/opfsStorage.d.ts +2 -2
- package/dist/storage/adapters/opfsStorage.js +2 -2
- package/dist/storage/adapters/s3CompatibleStorage.d.ts +2 -2
- package/dist/storage/adapters/s3CompatibleStorage.js +2 -2
- package/dist/storage/backwardCompatibility.d.ts +10 -78
- package/dist/storage/backwardCompatibility.js +17 -132
- package/dist/storage/baseStorage.d.ts +18 -2
- package/dist/storage/baseStorage.js +74 -3
- package/dist/storage/cacheManager.js +2 -2
- package/dist/storage/readOnlyOptimizations.js +8 -3
- package/dist/streaming/pipeline.d.ts +154 -0
- package/dist/streaming/pipeline.js +551 -0
- package/dist/triple/TripleIntelligence.d.ts +25 -110
- package/dist/triple/TripleIntelligence.js +4 -574
- package/dist/triple/TripleIntelligenceSystem.d.ts +159 -0
- package/dist/triple/TripleIntelligenceSystem.js +519 -0
- package/dist/types/apiTypes.d.ts +278 -0
- package/dist/types/apiTypes.js +33 -0
- package/dist/types/brainy.types.d.ts +308 -0
- package/dist/types/brainy.types.js +8 -0
- package/dist/types/brainyDataInterface.d.ts +5 -8
- package/dist/types/brainyDataInterface.js +2 -2
- package/dist/types/graphTypes.js +2 -2
- package/dist/universal/crypto.d.ts +11 -1
- package/dist/universal/crypto.js +24 -93
- package/dist/universal/events.d.ts +3 -2
- package/dist/universal/events.js +6 -75
- package/dist/universal/fs.d.ts +2 -3
- package/dist/universal/fs.js +5 -211
- package/dist/universal/path.d.ts +3 -2
- package/dist/universal/path.js +22 -78
- package/dist/universal/uuid.d.ts +1 -1
- package/dist/universal/uuid.js +1 -1
- package/dist/utils/brainyTypes.d.ts +217 -0
- package/dist/utils/brainyTypes.js +261 -0
- package/dist/utils/cacheAutoConfig.d.ts +3 -3
- package/dist/utils/embedding.d.ts +9 -4
- package/dist/utils/embedding.js +89 -26
- package/dist/utils/enhancedLogger.d.ts +104 -0
- package/dist/utils/enhancedLogger.js +232 -0
- package/dist/utils/hybridModelManager.d.ts +19 -28
- package/dist/utils/hybridModelManager.js +36 -200
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/intelligentTypeMapper.d.ts +60 -0
- package/dist/utils/intelligentTypeMapper.js +349 -0
- package/dist/utils/metadataIndex.d.ts +118 -1
- package/dist/utils/metadataIndex.js +539 -16
- package/dist/utils/nodeVersionCheck.d.ts +24 -0
- package/dist/utils/nodeVersionCheck.js +65 -0
- package/dist/utils/paramValidation.d.ts +39 -0
- package/dist/utils/paramValidation.js +192 -0
- package/dist/utils/rateLimiter.d.ts +160 -0
- package/dist/utils/rateLimiter.js +271 -0
- package/dist/utils/statistics.d.ts +4 -4
- package/dist/utils/statistics.js +3 -3
- package/dist/utils/structuredLogger.d.ts +146 -0
- package/dist/utils/structuredLogger.js +394 -0
- package/dist/utils/textEncoding.js +2 -1
- package/dist/utils/typeValidation.d.ts +59 -0
- package/dist/utils/typeValidation.js +374 -0
- package/dist/utils/version.js +19 -3
- package/package.json +15 -17
- package/scripts/download-models.cjs +94 -20
- package/dist/augmentations/walAugmentation.d.ts +0 -109
- package/dist/augmentations/walAugmentation.js +0 -516
- package/dist/browserFramework.d.ts +0 -15
- package/dist/browserFramework.js +0 -31
- package/dist/browserFramework.minimal.d.ts +0 -14
- package/dist/browserFramework.minimal.js +0 -31
- package/dist/chat/BrainyChat.d.ts +0 -121
- package/dist/chat/BrainyChat.js +0 -396
- package/dist/chat/ChatCLI.d.ts +0 -61
- package/dist/chat/ChatCLI.js +0 -351
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import { NounType, VerbType } from '../types/graphTypes.js';
|
|
2
|
+
// Type sets for O(1) validation
|
|
3
|
+
const VALID_NOUN_TYPES = new Set(Object.values(NounType));
|
|
4
|
+
const VALID_VERB_TYPES = new Set(Object.values(VerbType));
|
|
5
|
+
// Type guards
|
|
6
|
+
export function isValidNounType(type) {
|
|
7
|
+
return typeof type === 'string' && VALID_NOUN_TYPES.has(type);
|
|
8
|
+
}
|
|
9
|
+
export function isValidVerbType(type) {
|
|
10
|
+
return typeof type === 'string' && VALID_VERB_TYPES.has(type);
|
|
11
|
+
}
|
|
12
|
+
// Validators with helpful errors
|
|
13
|
+
export function validateNounType(type) {
|
|
14
|
+
if (!isValidNounType(type)) {
|
|
15
|
+
const suggestion = findClosestMatch(String(type), VALID_NOUN_TYPES);
|
|
16
|
+
throw new Error(`Invalid noun type: '${type}'. ${suggestion ? `Did you mean '${suggestion}'?` : ''} ` +
|
|
17
|
+
`Valid types are: ${[...VALID_NOUN_TYPES].sort().join(', ')}`);
|
|
18
|
+
}
|
|
19
|
+
return type;
|
|
20
|
+
}
|
|
21
|
+
export function validateVerbType(type) {
|
|
22
|
+
if (!isValidVerbType(type)) {
|
|
23
|
+
const suggestion = findClosestMatch(String(type), VALID_VERB_TYPES);
|
|
24
|
+
throw new Error(`Invalid verb type: '${type}'. ${suggestion ? `Did you mean '${suggestion}'?` : ''} ` +
|
|
25
|
+
`Valid types are: ${[...VALID_VERB_TYPES].sort().join(', ')}`);
|
|
26
|
+
}
|
|
27
|
+
return type;
|
|
28
|
+
}
|
|
29
|
+
export function validateGraphNoun(noun) {
|
|
30
|
+
if (!noun || typeof noun !== 'object') {
|
|
31
|
+
throw new Error('Invalid noun: must be an object');
|
|
32
|
+
}
|
|
33
|
+
const n = noun;
|
|
34
|
+
if (!n.noun) {
|
|
35
|
+
throw new Error('Invalid noun: missing required "noun" type field');
|
|
36
|
+
}
|
|
37
|
+
n.noun = validateNounType(n.noun);
|
|
38
|
+
return n;
|
|
39
|
+
}
|
|
40
|
+
export function validateGraphVerb(verb) {
|
|
41
|
+
if (!verb || typeof verb !== 'object') {
|
|
42
|
+
throw new Error('Invalid verb: must be an object');
|
|
43
|
+
}
|
|
44
|
+
const v = verb;
|
|
45
|
+
if (!v.verb) {
|
|
46
|
+
throw new Error('Invalid verb: missing required "verb" type field');
|
|
47
|
+
}
|
|
48
|
+
v.verb = validateVerbType(v.verb);
|
|
49
|
+
return v;
|
|
50
|
+
}
|
|
51
|
+
// Helper for suggestions using Levenshtein distance
|
|
52
|
+
function findClosestMatch(input, validSet) {
|
|
53
|
+
if (!input)
|
|
54
|
+
return null;
|
|
55
|
+
const lower = input.toLowerCase();
|
|
56
|
+
let bestMatch = null;
|
|
57
|
+
let bestScore = Infinity;
|
|
58
|
+
for (const valid of validSet) {
|
|
59
|
+
const validLower = valid.toLowerCase();
|
|
60
|
+
// Exact match (case-insensitive)
|
|
61
|
+
if (validLower === lower) {
|
|
62
|
+
return valid;
|
|
63
|
+
}
|
|
64
|
+
// Substring match
|
|
65
|
+
if (validLower.includes(lower) || lower.includes(validLower)) {
|
|
66
|
+
return valid;
|
|
67
|
+
}
|
|
68
|
+
// Calculate Levenshtein distance
|
|
69
|
+
const distance = levenshteinDistance(lower, validLower);
|
|
70
|
+
if (distance < bestScore && distance <= 3) { // Threshold of 3 for suggestions
|
|
71
|
+
bestScore = distance;
|
|
72
|
+
bestMatch = valid;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return bestMatch;
|
|
76
|
+
}
|
|
77
|
+
// Levenshtein distance implementation
|
|
78
|
+
function levenshteinDistance(str1, str2) {
|
|
79
|
+
const m = str1.length;
|
|
80
|
+
const n = str2.length;
|
|
81
|
+
const dp = Array(m + 1).fill(null).map(() => Array(n + 1).fill(0));
|
|
82
|
+
for (let i = 0; i <= m; i++) {
|
|
83
|
+
dp[i][0] = i;
|
|
84
|
+
}
|
|
85
|
+
for (let j = 0; j <= n; j++) {
|
|
86
|
+
dp[0][j] = j;
|
|
87
|
+
}
|
|
88
|
+
for (let i = 1; i <= m; i++) {
|
|
89
|
+
for (let j = 1; j <= n; j++) {
|
|
90
|
+
if (str1[i - 1] === str2[j - 1]) {
|
|
91
|
+
dp[i][j] = dp[i - 1][j - 1];
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
dp[i][j] = 1 + Math.min(dp[i - 1][j], // deletion
|
|
95
|
+
dp[i][j - 1], // insertion
|
|
96
|
+
dp[i - 1][j - 1] // substitution
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return dp[m][n];
|
|
102
|
+
}
|
|
103
|
+
// Batch validation helpers
|
|
104
|
+
export function validateNounTypes(types) {
|
|
105
|
+
return types.map(validateNounType);
|
|
106
|
+
}
|
|
107
|
+
export function validateVerbTypes(types) {
|
|
108
|
+
return types.map(validateVerbType);
|
|
109
|
+
}
|
|
110
|
+
let stats = {
|
|
111
|
+
validated: 0,
|
|
112
|
+
failed: 0,
|
|
113
|
+
inferred: 0,
|
|
114
|
+
suggestions: 0
|
|
115
|
+
};
|
|
116
|
+
export function getValidationStats() {
|
|
117
|
+
return { ...stats };
|
|
118
|
+
}
|
|
119
|
+
export function resetValidationStats() {
|
|
120
|
+
stats = {
|
|
121
|
+
validated: 0,
|
|
122
|
+
failed: 0,
|
|
123
|
+
inferred: 0,
|
|
124
|
+
suggestions: 0
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
// ================================================================
|
|
128
|
+
// INPUT VALIDATION UTILITIES
|
|
129
|
+
// ================================================================
|
|
130
|
+
// Comprehensive validation for all public API parameters
|
|
131
|
+
// Extends the existing type validation system
|
|
132
|
+
export class ValidationError extends Error {
|
|
133
|
+
constructor(parameter, value, constraint) {
|
|
134
|
+
super(`Invalid ${parameter}: ${constraint}`);
|
|
135
|
+
this.parameter = parameter;
|
|
136
|
+
this.value = value;
|
|
137
|
+
this.constraint = constraint;
|
|
138
|
+
this.name = 'ValidationError';
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Validate required ID parameter
|
|
143
|
+
* Standard validation for all ID-based operations
|
|
144
|
+
*/
|
|
145
|
+
export function validateId(id, paramName = 'id') {
|
|
146
|
+
if (id === null || id === undefined) {
|
|
147
|
+
throw new ValidationError(paramName, id, 'cannot be null or undefined');
|
|
148
|
+
}
|
|
149
|
+
if (typeof id !== 'string') {
|
|
150
|
+
throw new ValidationError(paramName, id, 'must be a string');
|
|
151
|
+
}
|
|
152
|
+
if (id.trim().length === 0) {
|
|
153
|
+
throw new ValidationError(paramName, id, 'cannot be empty string');
|
|
154
|
+
}
|
|
155
|
+
if (id.length > 512) {
|
|
156
|
+
throw new ValidationError(paramName, id, 'cannot exceed 512 characters');
|
|
157
|
+
}
|
|
158
|
+
return id.trim();
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Validate search query input
|
|
162
|
+
* Handles string queries, vectors, and objects for search operations
|
|
163
|
+
*/
|
|
164
|
+
export function validateSearchQuery(query, paramName = 'query') {
|
|
165
|
+
if (query === null || query === undefined) {
|
|
166
|
+
throw new ValidationError(paramName, query, 'cannot be null or undefined');
|
|
167
|
+
}
|
|
168
|
+
// Allow strings, arrays (vectors), or objects
|
|
169
|
+
if (typeof query === 'string') {
|
|
170
|
+
if (query.trim().length === 0) {
|
|
171
|
+
throw new ValidationError(paramName, query, 'query string cannot be empty');
|
|
172
|
+
}
|
|
173
|
+
if (query.length > 10000) {
|
|
174
|
+
throw new ValidationError(paramName, query, 'query string too long (max 10000 characters)');
|
|
175
|
+
}
|
|
176
|
+
return query.trim();
|
|
177
|
+
}
|
|
178
|
+
if (Array.isArray(query)) {
|
|
179
|
+
if (query.length === 0) {
|
|
180
|
+
throw new ValidationError(paramName, query, 'array cannot be empty');
|
|
181
|
+
}
|
|
182
|
+
// Validate vector arrays contain only numbers
|
|
183
|
+
if (query.every(item => typeof item === 'number')) {
|
|
184
|
+
if (query.some(num => !isFinite(num))) {
|
|
185
|
+
throw new ValidationError(paramName, query, 'vector contains invalid numbers (NaN or Infinity)');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return query;
|
|
189
|
+
}
|
|
190
|
+
if (typeof query === 'object') {
|
|
191
|
+
return query;
|
|
192
|
+
}
|
|
193
|
+
throw new ValidationError(paramName, query, 'must be string, array, or object');
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Validate data input for addNoun/updateNoun operations
|
|
197
|
+
* Handles vectors, objects, strings, and validates structure
|
|
198
|
+
*/
|
|
199
|
+
export function validateDataInput(data, paramName = 'data', allowNull = false) {
|
|
200
|
+
// Handle null/undefined
|
|
201
|
+
if (data === null) {
|
|
202
|
+
if (!allowNull) {
|
|
203
|
+
throw new ValidationError(paramName, data, 'Input cannot be null or undefined');
|
|
204
|
+
}
|
|
205
|
+
return data;
|
|
206
|
+
}
|
|
207
|
+
if (data === undefined) {
|
|
208
|
+
throw new ValidationError(paramName, data, 'Input cannot be null or undefined');
|
|
209
|
+
}
|
|
210
|
+
// Handle strings (including empty strings which are valid)
|
|
211
|
+
if (typeof data === 'string') {
|
|
212
|
+
// Empty strings are valid - they get converted to embeddings
|
|
213
|
+
// This matches the behavior in the embed function
|
|
214
|
+
if (data.length > 1000000) {
|
|
215
|
+
throw new ValidationError(paramName, data, 'string too long (max 1MB)');
|
|
216
|
+
}
|
|
217
|
+
return data;
|
|
218
|
+
}
|
|
219
|
+
// Handle arrays (vectors)
|
|
220
|
+
if (Array.isArray(data)) {
|
|
221
|
+
if (data.length === 0) {
|
|
222
|
+
throw new ValidationError(paramName, data, 'array cannot be empty');
|
|
223
|
+
}
|
|
224
|
+
if (data.length > 100000) {
|
|
225
|
+
throw new ValidationError(paramName, data, 'array too large (max 100k elements)');
|
|
226
|
+
}
|
|
227
|
+
// Validate vector arrays contain only numbers
|
|
228
|
+
if (data.every(item => typeof item === 'number')) {
|
|
229
|
+
if (data.some(num => !isFinite(num))) {
|
|
230
|
+
throw new ValidationError(paramName, data, 'vector contains invalid numbers (NaN or Infinity)');
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return data;
|
|
234
|
+
}
|
|
235
|
+
// Handle objects
|
|
236
|
+
if (typeof data === 'object') {
|
|
237
|
+
try {
|
|
238
|
+
// Quick check if object can be serialized (avoids circular references)
|
|
239
|
+
JSON.stringify(data);
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
throw new ValidationError(paramName, data, 'object contains circular references or unserializable values');
|
|
243
|
+
}
|
|
244
|
+
return data;
|
|
245
|
+
}
|
|
246
|
+
// Handle primitive types
|
|
247
|
+
if (typeof data === 'number') {
|
|
248
|
+
if (!isFinite(data)) {
|
|
249
|
+
throw new ValidationError(paramName, data, 'number must be finite (not NaN or Infinity)');
|
|
250
|
+
}
|
|
251
|
+
return data;
|
|
252
|
+
}
|
|
253
|
+
if (typeof data === 'boolean') {
|
|
254
|
+
return data;
|
|
255
|
+
}
|
|
256
|
+
throw new ValidationError(paramName, data, 'must be string, number, boolean, array, or object');
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Validate search options
|
|
260
|
+
* Comprehensive validation for search API options
|
|
261
|
+
*/
|
|
262
|
+
export function validateSearchOptions(options, paramName = 'options') {
|
|
263
|
+
if (options === null || options === undefined) {
|
|
264
|
+
return {}; // Default to empty options
|
|
265
|
+
}
|
|
266
|
+
if (typeof options !== 'object' || Array.isArray(options)) {
|
|
267
|
+
throw new ValidationError(paramName, options, 'must be an object');
|
|
268
|
+
}
|
|
269
|
+
const opts = options;
|
|
270
|
+
// Validate limit
|
|
271
|
+
if ('limit' in opts) {
|
|
272
|
+
const limit = opts.limit;
|
|
273
|
+
if (typeof limit !== 'number' || limit < 1 || limit > 10000 || !Number.isInteger(limit)) {
|
|
274
|
+
throw new ValidationError(`${paramName}.limit`, limit, 'must be integer between 1 and 10000');
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// Validate offset
|
|
278
|
+
if ('offset' in opts) {
|
|
279
|
+
const offset = opts.offset;
|
|
280
|
+
if (typeof offset !== 'number' || offset < 0 || !Number.isInteger(offset)) {
|
|
281
|
+
throw new ValidationError(`${paramName}.offset`, offset, 'must be non-negative integer');
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// Validate threshold
|
|
285
|
+
if ('threshold' in opts) {
|
|
286
|
+
const threshold = opts.threshold;
|
|
287
|
+
if (typeof threshold !== 'number' || threshold < 0 || threshold > 1) {
|
|
288
|
+
throw new ValidationError(`${paramName}.threshold`, threshold, 'must be number between 0 and 1');
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
// Validate timeout
|
|
292
|
+
if ('timeout' in opts) {
|
|
293
|
+
const timeout = opts.timeout;
|
|
294
|
+
if (typeof timeout !== 'number' || timeout < 1 || timeout > 300000 || !Number.isInteger(timeout)) {
|
|
295
|
+
throw new ValidationError(`${paramName}.timeout`, timeout, 'must be integer between 1 and 300000 milliseconds');
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Validate nounTypes array
|
|
299
|
+
if ('nounTypes' in opts) {
|
|
300
|
+
if (!Array.isArray(opts.nounTypes)) {
|
|
301
|
+
throw new ValidationError(`${paramName}.nounTypes`, opts.nounTypes, 'must be an array');
|
|
302
|
+
}
|
|
303
|
+
if (opts.nounTypes.length > 100) {
|
|
304
|
+
throw new ValidationError(`${paramName}.nounTypes`, opts.nounTypes, 'too many noun types (max 100)');
|
|
305
|
+
}
|
|
306
|
+
// Validate each noun type
|
|
307
|
+
opts.nounTypes = opts.nounTypes.map((type, index) => {
|
|
308
|
+
try {
|
|
309
|
+
return validateNounType(type);
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
if (error instanceof Error) {
|
|
313
|
+
throw new ValidationError(`${paramName}.nounTypes[${index}]`, type, error.message);
|
|
314
|
+
}
|
|
315
|
+
throw error;
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
// Validate itemIds array
|
|
320
|
+
if ('itemIds' in opts) {
|
|
321
|
+
if (!Array.isArray(opts.itemIds)) {
|
|
322
|
+
throw new ValidationError(`${paramName}.itemIds`, opts.itemIds, 'must be an array');
|
|
323
|
+
}
|
|
324
|
+
if (opts.itemIds.length > 10000) {
|
|
325
|
+
throw new ValidationError(`${paramName}.itemIds`, opts.itemIds, 'too many item IDs (max 10000)');
|
|
326
|
+
}
|
|
327
|
+
opts.itemIds = opts.itemIds.map((id, index) => {
|
|
328
|
+
try {
|
|
329
|
+
return validateId(id, `${paramName}.itemIds[${index}]`);
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
throw error; // Re-throw with proper context
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
return opts;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Validate ID arrays (for bulk operations)
|
|
340
|
+
*/
|
|
341
|
+
export function validateIdArray(ids, paramName = 'ids') {
|
|
342
|
+
if (ids === null || ids === undefined) {
|
|
343
|
+
throw new ValidationError(paramName, ids, 'cannot be null or undefined');
|
|
344
|
+
}
|
|
345
|
+
if (!Array.isArray(ids)) {
|
|
346
|
+
throw new ValidationError(paramName, ids, 'must be an array');
|
|
347
|
+
}
|
|
348
|
+
if (ids.length === 0) {
|
|
349
|
+
throw new ValidationError(paramName, ids, 'cannot be empty');
|
|
350
|
+
}
|
|
351
|
+
if (ids.length > 10000) {
|
|
352
|
+
throw new ValidationError(paramName, ids, 'too large (max 10000 items)');
|
|
353
|
+
}
|
|
354
|
+
return ids.map((id, index) => {
|
|
355
|
+
try {
|
|
356
|
+
return validateId(id, `${paramName}[${index}]`);
|
|
357
|
+
}
|
|
358
|
+
catch (error) {
|
|
359
|
+
throw error; // Re-throw with proper array context
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Track validation stats for monitoring
|
|
365
|
+
*/
|
|
366
|
+
export function recordValidation(success) {
|
|
367
|
+
if (success) {
|
|
368
|
+
stats.validated++;
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
stats.failed++;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
//# sourceMappingURL=typeValidation.js.map
|
package/dist/utils/version.js
CHANGED
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Version utilities for Brainy
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import { readFileSync } from 'fs';
|
|
5
|
+
import { join, dirname } from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
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');
|
|
11
|
+
let cachedVersion = null;
|
|
6
12
|
/**
|
|
7
13
|
* Get the current Brainy package version
|
|
8
14
|
* @returns The current version string
|
|
9
15
|
*/
|
|
10
16
|
export function getBrainyVersion() {
|
|
11
|
-
|
|
17
|
+
if (!cachedVersion) {
|
|
18
|
+
try {
|
|
19
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
20
|
+
cachedVersion = packageJson.version;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// Fallback version if package.json can't be read
|
|
24
|
+
cachedVersion = '2.7.1';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return cachedVersion;
|
|
12
28
|
}
|
|
13
29
|
/**
|
|
14
30
|
* Get version information for augmentation metadata
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soulcraft/brainy",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.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",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"bin": {
|
|
10
|
-
"brainy": "
|
|
10
|
+
"brainy": "bin/brainy.js"
|
|
11
11
|
},
|
|
12
12
|
"sideEffects": [
|
|
13
13
|
"./dist/setup.js",
|
|
@@ -15,17 +15,8 @@
|
|
|
15
15
|
"./src/setup.ts",
|
|
16
16
|
"./src/utils/textEncoding.ts"
|
|
17
17
|
],
|
|
18
|
-
"browser": {
|
|
19
|
-
"fs": false,
|
|
20
|
-
"fs/promises": false,
|
|
21
|
-
"path": "path-browserify",
|
|
22
|
-
"crypto": "crypto-browserify",
|
|
23
|
-
"./dist/cortex/cortex.js": "./dist/browserFramework.js"
|
|
24
|
-
},
|
|
25
18
|
"exports": {
|
|
26
19
|
".": {
|
|
27
|
-
"browser": "./dist/browserFramework.js",
|
|
28
|
-
"node": "./dist/index.js",
|
|
29
20
|
"import": "./dist/index.js",
|
|
30
21
|
"types": "./dist/index.d.ts"
|
|
31
22
|
},
|
|
@@ -45,17 +36,13 @@
|
|
|
45
36
|
"import": "./dist/utils/textEncoding.js",
|
|
46
37
|
"types": "./dist/utils/textEncoding.d.ts"
|
|
47
38
|
},
|
|
48
|
-
"./browserFramework": {
|
|
49
|
-
"import": "./dist/browserFramework.js",
|
|
50
|
-
"types": "./dist/browserFramework.d.ts"
|
|
51
|
-
},
|
|
52
39
|
"./universal": {
|
|
53
40
|
"import": "./dist/universal/index.js",
|
|
54
41
|
"types": "./dist/universal/index.d.ts"
|
|
55
42
|
}
|
|
56
43
|
},
|
|
57
44
|
"engines": {
|
|
58
|
-
"node": "
|
|
45
|
+
"node": "22.x"
|
|
59
46
|
},
|
|
60
47
|
"scripts": {
|
|
61
48
|
"build": "npm run build:patterns:if-needed && tsc",
|
|
@@ -68,16 +55,22 @@
|
|
|
68
55
|
"test:coverage": "vitest run --config tests/configs/vitest.unit.config.ts --coverage",
|
|
69
56
|
"test:unit": "vitest run --config tests/configs/vitest.unit.config.ts",
|
|
70
57
|
"test:integration": "NODE_OPTIONS='--max-old-space-size=32768' vitest run --config tests/configs/vitest.integration.config.ts",
|
|
58
|
+
"test:s3": "vitest run tests/integration/s3-storage.test.ts",
|
|
59
|
+
"test:distributed": "vitest run tests/integration/distributed.test.ts",
|
|
60
|
+
"test:cloud": "npm run test:s3 && npm run test:distributed",
|
|
71
61
|
"test:all": "npm run test:unit && npm run test:integration",
|
|
72
62
|
"test:ci-unit": "CI=true vitest run --config tests/configs/vitest.unit.config.ts",
|
|
73
63
|
"test:ci-integration": "NODE_OPTIONS='--max-old-space-size=16384' CI=true vitest run --config tests/configs/vitest.integration.config.ts",
|
|
74
64
|
"test:ci": "npm run test:ci-unit",
|
|
75
65
|
"download-models": "node scripts/download-models.cjs",
|
|
66
|
+
"download-models:q8": "node scripts/download-models.cjs",
|
|
76
67
|
"models:verify": "node scripts/ensure-models.js",
|
|
77
68
|
"lint": "eslint --ext .ts,.js src/",
|
|
78
69
|
"lint:fix": "eslint --ext .ts,.js src/ --fix",
|
|
79
70
|
"format": "prettier --write \"src/**/*.{ts,js}\"",
|
|
80
71
|
"format:check": "prettier --check \"src/**/*.{ts,js}\"",
|
|
72
|
+
"migrate:logger": "tsx scripts/migrate-to-structured-logger.ts",
|
|
73
|
+
"migrate:logger:dry": "tsx scripts/migrate-to-structured-logger.ts --dry-run",
|
|
81
74
|
"release": "standard-version",
|
|
82
75
|
"release:patch": "standard-version --release-as patch",
|
|
83
76
|
"release:minor": "standard-version --release-as minor",
|
|
@@ -130,12 +123,16 @@
|
|
|
130
123
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
131
124
|
"@rollup/plugin-replace": "^6.0.2",
|
|
132
125
|
"@rollup/plugin-terser": "^0.4.4",
|
|
126
|
+
"@testcontainers/redis": "^11.5.1",
|
|
133
127
|
"@types/node": "^20.11.30",
|
|
134
128
|
"@types/uuid": "^10.0.0",
|
|
129
|
+
"@types/ws": "^8.18.1",
|
|
135
130
|
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
136
131
|
"@typescript-eslint/parser": "^8.0.0",
|
|
137
132
|
"@vitest/coverage-v8": "^3.2.4",
|
|
133
|
+
"minio": "^8.0.5",
|
|
138
134
|
"standard-version": "^9.5.0",
|
|
135
|
+
"testcontainers": "^11.5.1",
|
|
139
136
|
"tsx": "^4.19.2",
|
|
140
137
|
"typescript": "^5.4.5",
|
|
141
138
|
"vitest": "^3.2.4"
|
|
@@ -150,7 +147,8 @@
|
|
|
150
147
|
"inquirer": "^12.9.3",
|
|
151
148
|
"ora": "^8.2.0",
|
|
152
149
|
"prompts": "^2.4.2",
|
|
153
|
-
"uuid": "^9.0.1"
|
|
150
|
+
"uuid": "^9.0.1",
|
|
151
|
+
"ws": "^8.18.3"
|
|
154
152
|
},
|
|
155
153
|
"prettier": {
|
|
156
154
|
"arrowParens": "always",
|
|
@@ -9,6 +9,9 @@ const path = require('path')
|
|
|
9
9
|
const MODEL_NAME = 'Xenova/all-MiniLM-L6-v2'
|
|
10
10
|
const OUTPUT_DIR = './models'
|
|
11
11
|
|
|
12
|
+
// Always download Q8 model only
|
|
13
|
+
const downloadType = 'q8'
|
|
14
|
+
|
|
12
15
|
async function downloadModels() {
|
|
13
16
|
// Use dynamic import for ES modules in CommonJS
|
|
14
17
|
const { pipeline, env } = await import('@huggingface/transformers')
|
|
@@ -16,29 +19,24 @@ async function downloadModels() {
|
|
|
16
19
|
// Configure transformers.js to use local cache
|
|
17
20
|
env.cacheDir = './models-cache'
|
|
18
21
|
env.allowRemoteModels = true
|
|
22
|
+
|
|
19
23
|
try {
|
|
20
|
-
console.log('
|
|
24
|
+
console.log('๐ง Brainy Model Downloader v2.8.0')
|
|
25
|
+
console.log('===================================')
|
|
21
26
|
console.log(` Model: ${MODEL_NAME}`)
|
|
27
|
+
console.log(` Type: Q8 (optimized, 99% accuracy)`)
|
|
22
28
|
console.log(` Cache: ${env.cacheDir}`)
|
|
29
|
+
console.log('')
|
|
23
30
|
|
|
24
31
|
// Create output directory
|
|
25
32
|
await fs.mkdir(OUTPUT_DIR, { recursive: true })
|
|
26
33
|
|
|
27
|
-
//
|
|
28
|
-
console.log('๐ฅ
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
// Test the model to make sure it works
|
|
32
|
-
console.log('๐งช Testing model...')
|
|
33
|
-
const testResult = await extractor(['Hello world!'], {
|
|
34
|
-
pooling: 'mean',
|
|
35
|
-
normalize: true
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
console.log(`โ
Model test successful! Embedding dimensions: ${testResult.data.length}`)
|
|
34
|
+
// Download Q8 model only
|
|
35
|
+
console.log('๐ฅ Downloading Q8 model (quantized, 33MB, 99% accuracy)...')
|
|
36
|
+
await downloadModelVariant('q8')
|
|
39
37
|
|
|
40
38
|
// Copy ALL model files from cache to our models directory
|
|
41
|
-
console.log('๐ Copying
|
|
39
|
+
console.log('๐ Copying model files to bundle directory...')
|
|
42
40
|
|
|
43
41
|
const cacheDir = path.resolve(env.cacheDir)
|
|
44
42
|
const outputDir = path.resolve(OUTPUT_DIR)
|
|
@@ -62,22 +60,89 @@ async function downloadModels() {
|
|
|
62
60
|
console.log(` Total size: ${await calculateDirectorySize(outputDir)} MB`)
|
|
63
61
|
console.log(` Location: ${outputDir}`)
|
|
64
62
|
|
|
65
|
-
// Create a marker file
|
|
63
|
+
// Create a marker file with downloaded model info
|
|
64
|
+
const markerData = {
|
|
65
|
+
model: MODEL_NAME,
|
|
66
|
+
bundledAt: new Date().toISOString(),
|
|
67
|
+
version: '2.8.0',
|
|
68
|
+
downloadType: downloadType,
|
|
69
|
+
models: {}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Check which models were downloaded
|
|
73
|
+
const fp32Path = path.join(outputDir, 'Xenova/all-MiniLM-L6-v2/onnx/model.onnx')
|
|
74
|
+
const q8Path = path.join(outputDir, 'Xenova/all-MiniLM-L6-v2/onnx/model_quantized.onnx')
|
|
75
|
+
|
|
76
|
+
if (await fileExists(fp32Path)) {
|
|
77
|
+
const stats = await fs.stat(fp32Path)
|
|
78
|
+
markerData.models.fp32 = {
|
|
79
|
+
file: 'onnx/model.onnx',
|
|
80
|
+
size: stats.size,
|
|
81
|
+
sizeFormatted: `${Math.round(stats.size / (1024 * 1024))}MB`
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (await fileExists(q8Path)) {
|
|
86
|
+
const stats = await fs.stat(q8Path)
|
|
87
|
+
markerData.models.q8 = {
|
|
88
|
+
file: 'onnx/model_quantized.onnx',
|
|
89
|
+
size: stats.size,
|
|
90
|
+
sizeFormatted: `${Math.round(stats.size / (1024 * 1024))}MB`
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
66
94
|
await fs.writeFile(
|
|
67
95
|
path.join(outputDir, '.brainy-models-bundled'),
|
|
68
|
-
JSON.stringify(
|
|
69
|
-
model: MODEL_NAME,
|
|
70
|
-
bundledAt: new Date().toISOString(),
|
|
71
|
-
version: '1.0.0'
|
|
72
|
-
}, null, 2)
|
|
96
|
+
JSON.stringify(markerData, null, 2)
|
|
73
97
|
)
|
|
74
98
|
|
|
99
|
+
console.log('')
|
|
100
|
+
console.log('โ
Download complete! Available models:')
|
|
101
|
+
if (markerData.models.fp32) {
|
|
102
|
+
console.log(` โข FP32: ${markerData.models.fp32.sizeFormatted} (full precision)`)
|
|
103
|
+
}
|
|
104
|
+
if (markerData.models.q8) {
|
|
105
|
+
console.log(` โข Q8: ${markerData.models.q8.sizeFormatted} (quantized, 75% smaller)`)
|
|
106
|
+
}
|
|
107
|
+
console.log('')
|
|
108
|
+
console.log('Air-gap deployment ready! ๐')
|
|
109
|
+
|
|
75
110
|
} catch (error) {
|
|
76
111
|
console.error('โ Error downloading models:', error)
|
|
77
112
|
process.exit(1)
|
|
78
113
|
}
|
|
79
114
|
}
|
|
80
115
|
|
|
116
|
+
// Download a specific model variant
|
|
117
|
+
async function downloadModelVariant(dtype) {
|
|
118
|
+
const { pipeline } = await import('@huggingface/transformers')
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
// Load the model to force download
|
|
122
|
+
const extractor = await pipeline('feature-extraction', MODEL_NAME, {
|
|
123
|
+
dtype: dtype,
|
|
124
|
+
cache_dir: './models-cache'
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
// Test the model
|
|
128
|
+
const testResult = await extractor(['Hello world!'], {
|
|
129
|
+
pooling: 'mean',
|
|
130
|
+
normalize: true
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
console.log(` โ
${dtype.toUpperCase()} model downloaded and tested (${testResult.data.length} dimensions)`)
|
|
134
|
+
|
|
135
|
+
// Dispose to free memory
|
|
136
|
+
if (extractor.dispose) {
|
|
137
|
+
await extractor.dispose()
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
} catch (error) {
|
|
141
|
+
console.error(` โ Failed to download ${dtype} model:`, error)
|
|
142
|
+
throw error
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
81
146
|
async function findModelDirectories(baseDir, modelName) {
|
|
82
147
|
const dirs = []
|
|
83
148
|
|
|
@@ -141,6 +206,15 @@ async function dirExists(dir) {
|
|
|
141
206
|
}
|
|
142
207
|
}
|
|
143
208
|
|
|
209
|
+
async function fileExists(file) {
|
|
210
|
+
try {
|
|
211
|
+
const stats = await fs.stat(file)
|
|
212
|
+
return stats.isFile()
|
|
213
|
+
} catch (error) {
|
|
214
|
+
return false
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
144
218
|
async function copyDirectory(src, dest) {
|
|
145
219
|
await fs.mkdir(dest, { recursive: true })
|
|
146
220
|
const entries = await fs.readdir(src, { withFileTypes: true })
|