@soulcraft/brainy 3.0.0 โ†’ 3.0.1

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 (260) hide show
  1. package/CHANGELOG.md +53 -3
  2. package/README.md +353 -110
  3. package/bin/brainy.js +340 -62
  4. package/dist/api/ConfigAPI.d.ts +67 -0
  5. package/dist/api/ConfigAPI.js +166 -0
  6. package/dist/api/DataAPI.d.ts +123 -0
  7. package/dist/api/DataAPI.js +391 -0
  8. package/dist/api/SecurityAPI.d.ts +50 -0
  9. package/dist/api/SecurityAPI.js +139 -0
  10. package/dist/api/UniversalImportAPI.d.ts +134 -0
  11. package/dist/api/UniversalImportAPI.js +615 -0
  12. package/dist/augmentationManager.js +12 -7
  13. package/dist/augmentationPipeline.d.ts +0 -61
  14. package/dist/augmentationPipeline.js +0 -87
  15. package/dist/augmentationRegistry.d.ts +1 -1
  16. package/dist/augmentationRegistry.js +1 -1
  17. package/dist/augmentations/apiServerAugmentation.d.ts +27 -1
  18. package/dist/augmentations/apiServerAugmentation.js +290 -9
  19. package/dist/augmentations/auditLogAugmentation.d.ts +109 -0
  20. package/dist/augmentations/auditLogAugmentation.js +358 -0
  21. package/dist/augmentations/batchProcessingAugmentation.d.ts +3 -2
  22. package/dist/augmentations/batchProcessingAugmentation.js +123 -22
  23. package/dist/augmentations/brainyAugmentation.d.ts +142 -8
  24. package/dist/augmentations/brainyAugmentation.js +179 -2
  25. package/dist/augmentations/cacheAugmentation.d.ts +8 -5
  26. package/dist/augmentations/cacheAugmentation.js +116 -17
  27. package/dist/augmentations/conduitAugmentations.d.ts +2 -2
  28. package/dist/augmentations/conduitAugmentations.js +2 -2
  29. package/dist/augmentations/configResolver.d.ts +122 -0
  30. package/dist/augmentations/configResolver.js +440 -0
  31. package/dist/augmentations/connectionPoolAugmentation.d.ts +3 -1
  32. package/dist/augmentations/connectionPoolAugmentation.js +37 -12
  33. package/dist/augmentations/defaultAugmentations.d.ts +14 -10
  34. package/dist/augmentations/defaultAugmentations.js +16 -11
  35. package/dist/augmentations/discovery/catalogDiscovery.d.ts +142 -0
  36. package/dist/augmentations/discovery/catalogDiscovery.js +249 -0
  37. package/dist/augmentations/discovery/localDiscovery.d.ts +84 -0
  38. package/dist/augmentations/discovery/localDiscovery.js +246 -0
  39. package/dist/augmentations/discovery/runtimeLoader.d.ts +97 -0
  40. package/dist/augmentations/discovery/runtimeLoader.js +337 -0
  41. package/dist/augmentations/discovery.d.ts +152 -0
  42. package/dist/augmentations/discovery.js +441 -0
  43. package/dist/augmentations/display/cache.d.ts +130 -0
  44. package/dist/augmentations/display/cache.js +319 -0
  45. package/dist/augmentations/display/fieldPatterns.d.ts +52 -0
  46. package/dist/augmentations/display/fieldPatterns.js +393 -0
  47. package/dist/augmentations/display/iconMappings.d.ts +57 -0
  48. package/dist/augmentations/display/iconMappings.js +68 -0
  49. package/dist/augmentations/display/intelligentComputation.d.ts +109 -0
  50. package/dist/augmentations/display/intelligentComputation.js +462 -0
  51. package/dist/augmentations/display/types.d.ts +203 -0
  52. package/dist/augmentations/display/types.js +7 -0
  53. package/dist/augmentations/entityRegistryAugmentation.d.ts +3 -1
  54. package/dist/augmentations/entityRegistryAugmentation.js +5 -1
  55. package/dist/augmentations/indexAugmentation.d.ts +5 -3
  56. package/dist/augmentations/indexAugmentation.js +5 -2
  57. package/dist/augmentations/intelligentVerbScoringAugmentation.d.ts +24 -7
  58. package/dist/augmentations/intelligentVerbScoringAugmentation.js +111 -27
  59. package/dist/augmentations/manifest.d.ts +176 -0
  60. package/dist/augmentations/manifest.js +8 -0
  61. package/dist/augmentations/marketplace/AugmentationMarketplace.d.ts +168 -0
  62. package/dist/augmentations/marketplace/AugmentationMarketplace.js +329 -0
  63. package/dist/augmentations/marketplace/cli.d.ts +47 -0
  64. package/dist/augmentations/marketplace/cli.js +265 -0
  65. package/dist/augmentations/metricsAugmentation.d.ts +3 -3
  66. package/dist/augmentations/metricsAugmentation.js +2 -2
  67. package/dist/augmentations/monitoringAugmentation.d.ts +3 -3
  68. package/dist/augmentations/monitoringAugmentation.js +2 -2
  69. package/dist/augmentations/neuralImport.d.ts +1 -1
  70. package/dist/augmentations/neuralImport.js +4 -4
  71. package/dist/augmentations/rateLimitAugmentation.d.ts +82 -0
  72. package/dist/augmentations/rateLimitAugmentation.js +321 -0
  73. package/dist/augmentations/requestDeduplicatorAugmentation.d.ts +2 -2
  74. package/dist/augmentations/requestDeduplicatorAugmentation.js +1 -1
  75. package/dist/augmentations/storageAugmentation.d.ts +1 -1
  76. package/dist/augmentations/storageAugmentation.js +2 -2
  77. package/dist/augmentations/storageAugmentations.d.ts +37 -8
  78. package/dist/augmentations/storageAugmentations.js +204 -15
  79. package/dist/augmentations/synapseAugmentation.d.ts +1 -1
  80. package/dist/augmentations/synapseAugmentation.js +35 -16
  81. package/dist/augmentations/typeMatching/brainyTypes.d.ts +83 -0
  82. package/dist/augmentations/typeMatching/brainyTypes.js +425 -0
  83. package/dist/augmentations/typeMatching/intelligentTypeMatcher.d.ts +39 -59
  84. package/dist/augmentations/typeMatching/intelligentTypeMatcher.js +103 -389
  85. package/dist/augmentations/universalDisplayAugmentation.d.ts +191 -0
  86. package/dist/augmentations/universalDisplayAugmentation.js +371 -0
  87. package/dist/brainy-unified.d.ts +106 -0
  88. package/dist/brainy-unified.js +327 -0
  89. package/dist/brainy.d.ts +273 -0
  90. package/dist/brainy.js +1181 -0
  91. package/dist/brainyData.d.ts +56 -111
  92. package/dist/brainyData.js +912 -756
  93. package/dist/brainyDataV3.d.ts +186 -0
  94. package/dist/brainyDataV3.js +337 -0
  95. package/dist/browserFramework.d.ts +6 -6
  96. package/dist/browserFramework.js +11 -8
  97. package/dist/browserFramework.minimal.d.ts +5 -5
  98. package/dist/browserFramework.minimal.js +11 -8
  99. package/dist/config/distributedPresets-new.d.ts +118 -0
  100. package/dist/config/distributedPresets-new.js +318 -0
  101. package/dist/config/distributedPresets.d.ts +118 -0
  102. package/dist/config/distributedPresets.js +318 -0
  103. package/dist/config/extensibleConfig.d.ts +99 -0
  104. package/dist/config/extensibleConfig.js +268 -0
  105. package/dist/config/index.d.ts +17 -0
  106. package/dist/config/index.js +35 -0
  107. package/dist/config/modelAutoConfig.d.ts +32 -0
  108. package/dist/config/modelAutoConfig.js +139 -0
  109. package/dist/config/modelPrecisionManager.d.ts +42 -0
  110. package/dist/config/modelPrecisionManager.js +98 -0
  111. package/dist/config/sharedConfigManager.d.ts +67 -0
  112. package/dist/config/sharedConfigManager.js +215 -0
  113. package/dist/config/storageAutoConfig.d.ts +41 -0
  114. package/dist/config/storageAutoConfig.js +328 -0
  115. package/dist/config/zeroConfig.d.ts +68 -0
  116. package/dist/config/zeroConfig.js +301 -0
  117. package/dist/cortex/backupRestore.d.ts +2 -2
  118. package/dist/cortex/backupRestore.js +85 -27
  119. package/dist/cortex/healthCheck.d.ts +2 -2
  120. package/dist/cortex/neuralImport.d.ts +2 -2
  121. package/dist/cortex/neuralImport.js +18 -13
  122. package/dist/cortex/performanceMonitor.d.ts +2 -2
  123. package/dist/critical/model-guardian.d.ts +4 -0
  124. package/dist/critical/model-guardian.js +31 -11
  125. package/dist/demo.d.ts +4 -4
  126. package/dist/demo.js +7 -7
  127. package/dist/distributed/cacheSync.d.ts +112 -0
  128. package/dist/distributed/cacheSync.js +265 -0
  129. package/dist/distributed/coordinator.d.ts +193 -0
  130. package/dist/distributed/coordinator.js +548 -0
  131. package/dist/distributed/httpTransport.d.ts +120 -0
  132. package/dist/distributed/httpTransport.js +446 -0
  133. package/dist/distributed/index.d.ts +8 -0
  134. package/dist/distributed/index.js +5 -0
  135. package/dist/distributed/networkTransport.d.ts +132 -0
  136. package/dist/distributed/networkTransport.js +633 -0
  137. package/dist/distributed/queryPlanner.d.ts +104 -0
  138. package/dist/distributed/queryPlanner.js +327 -0
  139. package/dist/distributed/readWriteSeparation.d.ts +134 -0
  140. package/dist/distributed/readWriteSeparation.js +350 -0
  141. package/dist/distributed/shardManager.d.ts +114 -0
  142. package/dist/distributed/shardManager.js +357 -0
  143. package/dist/distributed/shardMigration.d.ts +110 -0
  144. package/dist/distributed/shardMigration.js +289 -0
  145. package/dist/distributed/storageDiscovery.d.ts +160 -0
  146. package/dist/distributed/storageDiscovery.js +551 -0
  147. package/dist/embeddings/CachedEmbeddings.d.ts +40 -0
  148. package/dist/embeddings/CachedEmbeddings.js +146 -0
  149. package/dist/embeddings/EmbeddingManager.d.ts +102 -0
  150. package/dist/embeddings/EmbeddingManager.js +291 -0
  151. package/dist/embeddings/SingletonModelManager.d.ts +95 -0
  152. package/dist/embeddings/SingletonModelManager.js +220 -0
  153. package/dist/embeddings/index.d.ts +12 -0
  154. package/dist/embeddings/index.js +16 -0
  155. package/dist/embeddings/lightweight-embedder.d.ts +0 -1
  156. package/dist/embeddings/lightweight-embedder.js +4 -12
  157. package/dist/embeddings/model-manager.d.ts +11 -0
  158. package/dist/embeddings/model-manager.js +43 -7
  159. package/dist/embeddings/universal-memory-manager.d.ts +1 -1
  160. package/dist/embeddings/universal-memory-manager.js +27 -67
  161. package/dist/embeddings/worker-embedding.js +4 -8
  162. package/dist/errors/brainyError.d.ts +5 -1
  163. package/dist/errors/brainyError.js +12 -0
  164. package/dist/examples/basicUsage.js +7 -4
  165. package/dist/graph/graphAdjacencyIndex.d.ts +96 -0
  166. package/dist/graph/graphAdjacencyIndex.js +288 -0
  167. package/dist/graph/pathfinding.js +4 -2
  168. package/dist/hnsw/scaledHNSWSystem.js +11 -2
  169. package/dist/importManager.js +8 -5
  170. package/dist/index.d.ts +17 -22
  171. package/dist/index.js +37 -23
  172. package/dist/mcp/brainyMCPAdapter.d.ts +4 -4
  173. package/dist/mcp/brainyMCPAdapter.js +5 -5
  174. package/dist/mcp/brainyMCPService.d.ts +3 -3
  175. package/dist/mcp/brainyMCPService.js +3 -11
  176. package/dist/mcp/mcpAugmentationToolset.js +20 -30
  177. package/dist/neural/embeddedPatterns.d.ts +1 -1
  178. package/dist/neural/embeddedPatterns.js +2 -2
  179. package/dist/neural/entityExtractor.d.ts +65 -0
  180. package/dist/neural/entityExtractor.js +316 -0
  181. package/dist/neural/improvedNeuralAPI.d.ts +357 -0
  182. package/dist/neural/improvedNeuralAPI.js +2628 -0
  183. package/dist/neural/naturalLanguageProcessor.d.ts +155 -10
  184. package/dist/neural/naturalLanguageProcessor.js +941 -66
  185. package/dist/neural/naturalLanguageProcessorStatic.d.ts +2 -2
  186. package/dist/neural/naturalLanguageProcessorStatic.js +3 -3
  187. package/dist/neural/neuralAPI.js +8 -2
  188. package/dist/neural/patternLibrary.d.ts +57 -3
  189. package/dist/neural/patternLibrary.js +348 -13
  190. package/dist/neural/staticPatternMatcher.d.ts +2 -2
  191. package/dist/neural/staticPatternMatcher.js +2 -2
  192. package/dist/neural/types.d.ts +287 -0
  193. package/dist/neural/types.js +24 -0
  194. package/dist/shared/default-augmentations.d.ts +3 -3
  195. package/dist/shared/default-augmentations.js +5 -5
  196. package/dist/storage/adapters/baseStorageAdapter.d.ts +42 -0
  197. package/dist/storage/adapters/fileSystemStorage.d.ts +26 -2
  198. package/dist/storage/adapters/fileSystemStorage.js +218 -15
  199. package/dist/storage/adapters/memoryStorage.d.ts +4 -4
  200. package/dist/storage/adapters/memoryStorage.js +17 -12
  201. package/dist/storage/adapters/opfsStorage.d.ts +2 -2
  202. package/dist/storage/adapters/opfsStorage.js +2 -2
  203. package/dist/storage/adapters/s3CompatibleStorage.d.ts +2 -2
  204. package/dist/storage/adapters/s3CompatibleStorage.js +2 -2
  205. package/dist/storage/backwardCompatibility.d.ts +10 -78
  206. package/dist/storage/backwardCompatibility.js +17 -132
  207. package/dist/storage/baseStorage.d.ts +18 -2
  208. package/dist/storage/baseStorage.js +74 -3
  209. package/dist/storage/cacheManager.js +2 -2
  210. package/dist/storage/readOnlyOptimizations.js +8 -3
  211. package/dist/streaming/pipeline.d.ts +154 -0
  212. package/dist/streaming/pipeline.js +551 -0
  213. package/dist/triple/TripleIntelligence.d.ts +25 -110
  214. package/dist/triple/TripleIntelligence.js +4 -574
  215. package/dist/triple/TripleIntelligenceSystem.d.ts +159 -0
  216. package/dist/triple/TripleIntelligenceSystem.js +519 -0
  217. package/dist/types/apiTypes.d.ts +278 -0
  218. package/dist/types/apiTypes.js +33 -0
  219. package/dist/types/brainy.types.d.ts +308 -0
  220. package/dist/types/brainy.types.js +8 -0
  221. package/dist/types/brainyDataInterface.d.ts +5 -8
  222. package/dist/types/brainyDataInterface.js +2 -2
  223. package/dist/types/graphTypes.js +2 -2
  224. package/dist/utils/brainyTypes.d.ts +217 -0
  225. package/dist/utils/brainyTypes.js +261 -0
  226. package/dist/utils/cacheAutoConfig.d.ts +3 -3
  227. package/dist/utils/embedding.d.ts +9 -4
  228. package/dist/utils/embedding.js +89 -26
  229. package/dist/utils/enhancedLogger.d.ts +104 -0
  230. package/dist/utils/enhancedLogger.js +232 -0
  231. package/dist/utils/hybridModelManager.d.ts +19 -28
  232. package/dist/utils/hybridModelManager.js +36 -200
  233. package/dist/utils/index.d.ts +1 -1
  234. package/dist/utils/index.js +1 -1
  235. package/dist/utils/intelligentTypeMapper.d.ts +60 -0
  236. package/dist/utils/intelligentTypeMapper.js +349 -0
  237. package/dist/utils/metadataIndex.d.ts +118 -1
  238. package/dist/utils/metadataIndex.js +539 -16
  239. package/dist/utils/nodeVersionCheck.d.ts +24 -0
  240. package/dist/utils/nodeVersionCheck.js +65 -0
  241. package/dist/utils/paramValidation.d.ts +39 -0
  242. package/dist/utils/paramValidation.js +192 -0
  243. package/dist/utils/rateLimiter.d.ts +160 -0
  244. package/dist/utils/rateLimiter.js +271 -0
  245. package/dist/utils/statistics.d.ts +4 -4
  246. package/dist/utils/statistics.js +3 -3
  247. package/dist/utils/structuredLogger.d.ts +146 -0
  248. package/dist/utils/structuredLogger.js +394 -0
  249. package/dist/utils/textEncoding.js +2 -1
  250. package/dist/utils/typeValidation.d.ts +59 -0
  251. package/dist/utils/typeValidation.js +374 -0
  252. package/dist/utils/version.js +19 -3
  253. package/package.json +15 -4
  254. package/scripts/download-models.cjs +94 -20
  255. package/dist/augmentations/walAugmentation.d.ts +0 -109
  256. package/dist/augmentations/walAugmentation.js +0 -516
  257. package/dist/chat/BrainyChat.d.ts +0 -121
  258. package/dist/chat/BrainyChat.js +0 -396
  259. package/dist/chat/ChatCLI.d.ts +0 -61
  260. 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
@@ -1,14 +1,30 @@
1
1
  /**
2
2
  * Version utilities for Brainy
3
3
  */
4
- // Package version - this should be updated during the build process
5
- const BRAINY_VERSION = '0.41.0';
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
- return BRAINY_VERSION;
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.0.0",
3
+ "version": "3.0.1",
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": "./bin/brainy.js"
10
+ "brainy": "bin/brainy.js"
11
11
  },
12
12
  "sideEffects": [
13
13
  "./dist/setup.js",
@@ -55,7 +55,7 @@
55
55
  }
56
56
  },
57
57
  "engines": {
58
- "node": ">=18.0.0"
58
+ "node": "22.x"
59
59
  },
60
60
  "scripts": {
61
61
  "build": "npm run build:patterns:if-needed && tsc",
@@ -68,16 +68,22 @@
68
68
  "test:coverage": "vitest run --config tests/configs/vitest.unit.config.ts --coverage",
69
69
  "test:unit": "vitest run --config tests/configs/vitest.unit.config.ts",
70
70
  "test:integration": "NODE_OPTIONS='--max-old-space-size=32768' vitest run --config tests/configs/vitest.integration.config.ts",
71
+ "test:s3": "vitest run tests/integration/s3-storage.test.ts",
72
+ "test:distributed": "vitest run tests/integration/distributed.test.ts",
73
+ "test:cloud": "npm run test:s3 && npm run test:distributed",
71
74
  "test:all": "npm run test:unit && npm run test:integration",
72
75
  "test:ci-unit": "CI=true vitest run --config tests/configs/vitest.unit.config.ts",
73
76
  "test:ci-integration": "NODE_OPTIONS='--max-old-space-size=16384' CI=true vitest run --config tests/configs/vitest.integration.config.ts",
74
77
  "test:ci": "npm run test:ci-unit",
75
78
  "download-models": "node scripts/download-models.cjs",
79
+ "download-models:q8": "node scripts/download-models.cjs",
76
80
  "models:verify": "node scripts/ensure-models.js",
77
81
  "lint": "eslint --ext .ts,.js src/",
78
82
  "lint:fix": "eslint --ext .ts,.js src/ --fix",
79
83
  "format": "prettier --write \"src/**/*.{ts,js}\"",
80
84
  "format:check": "prettier --check \"src/**/*.{ts,js}\"",
85
+ "migrate:logger": "tsx scripts/migrate-to-structured-logger.ts",
86
+ "migrate:logger:dry": "tsx scripts/migrate-to-structured-logger.ts --dry-run",
81
87
  "release": "standard-version",
82
88
  "release:patch": "standard-version --release-as patch",
83
89
  "release:minor": "standard-version --release-as minor",
@@ -130,12 +136,16 @@
130
136
  "@rollup/plugin-node-resolve": "^16.0.1",
131
137
  "@rollup/plugin-replace": "^6.0.2",
132
138
  "@rollup/plugin-terser": "^0.4.4",
139
+ "@testcontainers/redis": "^11.5.1",
133
140
  "@types/node": "^20.11.30",
134
141
  "@types/uuid": "^10.0.0",
142
+ "@types/ws": "^8.18.1",
135
143
  "@typescript-eslint/eslint-plugin": "^8.0.0",
136
144
  "@typescript-eslint/parser": "^8.0.0",
137
145
  "@vitest/coverage-v8": "^3.2.4",
146
+ "minio": "^8.0.5",
138
147
  "standard-version": "^9.5.0",
148
+ "testcontainers": "^11.5.1",
139
149
  "tsx": "^4.19.2",
140
150
  "typescript": "^5.4.5",
141
151
  "vitest": "^3.2.4"
@@ -150,7 +160,8 @@
150
160
  "inquirer": "^12.9.3",
151
161
  "ora": "^8.2.0",
152
162
  "prompts": "^2.4.2",
153
- "uuid": "^9.0.1"
163
+ "uuid": "^9.0.1",
164
+ "ws": "^8.18.3"
154
165
  },
155
166
  "prettier": {
156
167
  "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('๐Ÿ”„ Downloading all-MiniLM-L6-v2 model for offline bundling...')
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
- // Load the model to force download
28
- console.log('๐Ÿ“ฅ Loading model pipeline...')
29
- const extractor = await pipeline('feature-extraction', MODEL_NAME)
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 ALL model files to bundle directory...')
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 })