@soulcraft/brainy 2.15.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 (204) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +249 -152
  3. package/dist/api/ConfigAPI.d.ts +67 -0
  4. package/dist/api/ConfigAPI.js +166 -0
  5. package/dist/api/DataAPI.d.ts +123 -0
  6. package/dist/api/DataAPI.js +391 -0
  7. package/dist/api/SecurityAPI.d.ts +50 -0
  8. package/dist/api/SecurityAPI.js +139 -0
  9. package/dist/api/UniversalImportAPI.d.ts +134 -0
  10. package/dist/api/UniversalImportAPI.js +615 -0
  11. package/dist/augmentationManager.js +12 -7
  12. package/dist/augmentationPipeline.d.ts +0 -61
  13. package/dist/augmentationPipeline.js +0 -87
  14. package/dist/augmentationRegistry.d.ts +1 -1
  15. package/dist/augmentationRegistry.js +1 -1
  16. package/dist/augmentations/apiServerAugmentation.d.ts +27 -1
  17. package/dist/augmentations/apiServerAugmentation.js +288 -7
  18. package/dist/augmentations/auditLogAugmentation.d.ts +109 -0
  19. package/dist/augmentations/auditLogAugmentation.js +358 -0
  20. package/dist/augmentations/batchProcessingAugmentation.d.ts +3 -2
  21. package/dist/augmentations/batchProcessingAugmentation.js +123 -22
  22. package/dist/augmentations/brainyAugmentation.d.ts +87 -8
  23. package/dist/augmentations/brainyAugmentation.js +159 -2
  24. package/dist/augmentations/cacheAugmentation.d.ts +6 -5
  25. package/dist/augmentations/cacheAugmentation.js +113 -17
  26. package/dist/augmentations/conduitAugmentations.d.ts +2 -2
  27. package/dist/augmentations/conduitAugmentations.js +2 -2
  28. package/dist/augmentations/configResolver.d.ts +122 -0
  29. package/dist/augmentations/configResolver.js +440 -0
  30. package/dist/augmentations/connectionPoolAugmentation.d.ts +3 -1
  31. package/dist/augmentations/connectionPoolAugmentation.js +37 -12
  32. package/dist/augmentations/defaultAugmentations.d.ts +9 -11
  33. package/dist/augmentations/defaultAugmentations.js +4 -11
  34. package/dist/augmentations/discovery/catalogDiscovery.d.ts +142 -0
  35. package/dist/augmentations/discovery/catalogDiscovery.js +249 -0
  36. package/dist/augmentations/discovery/localDiscovery.d.ts +84 -0
  37. package/dist/augmentations/discovery/localDiscovery.js +246 -0
  38. package/dist/augmentations/discovery/runtimeLoader.d.ts +97 -0
  39. package/dist/augmentations/discovery/runtimeLoader.js +337 -0
  40. package/dist/augmentations/discovery.d.ts +152 -0
  41. package/dist/augmentations/discovery.js +441 -0
  42. package/dist/augmentations/display/intelligentComputation.d.ts +1 -1
  43. package/dist/augmentations/display/intelligentComputation.js +4 -4
  44. package/dist/augmentations/entityRegistryAugmentation.d.ts +3 -1
  45. package/dist/augmentations/entityRegistryAugmentation.js +5 -1
  46. package/dist/augmentations/indexAugmentation.d.ts +3 -3
  47. package/dist/augmentations/indexAugmentation.js +2 -2
  48. package/dist/augmentations/intelligentVerbScoringAugmentation.d.ts +22 -6
  49. package/dist/augmentations/intelligentVerbScoringAugmentation.js +106 -23
  50. package/dist/augmentations/manifest.d.ts +176 -0
  51. package/dist/augmentations/manifest.js +8 -0
  52. package/dist/augmentations/marketplace/AugmentationMarketplace.d.ts +168 -0
  53. package/dist/augmentations/marketplace/AugmentationMarketplace.js +329 -0
  54. package/dist/augmentations/marketplace/cli.d.ts +47 -0
  55. package/dist/augmentations/marketplace/cli.js +265 -0
  56. package/dist/augmentations/metricsAugmentation.d.ts +3 -3
  57. package/dist/augmentations/metricsAugmentation.js +2 -2
  58. package/dist/augmentations/monitoringAugmentation.d.ts +3 -3
  59. package/dist/augmentations/monitoringAugmentation.js +2 -2
  60. package/dist/augmentations/neuralImport.d.ts +1 -1
  61. package/dist/augmentations/rateLimitAugmentation.d.ts +82 -0
  62. package/dist/augmentations/rateLimitAugmentation.js +321 -0
  63. package/dist/augmentations/requestDeduplicatorAugmentation.d.ts +2 -2
  64. package/dist/augmentations/requestDeduplicatorAugmentation.js +1 -1
  65. package/dist/augmentations/storageAugmentation.d.ts +1 -1
  66. package/dist/augmentations/storageAugmentation.js +2 -2
  67. package/dist/augmentations/storageAugmentations.d.ts +37 -8
  68. package/dist/augmentations/storageAugmentations.js +204 -15
  69. package/dist/augmentations/synapseAugmentation.d.ts +1 -1
  70. package/dist/augmentations/synapseAugmentation.js +35 -16
  71. package/dist/augmentations/typeMatching/intelligentTypeMatcher.d.ts +39 -59
  72. package/dist/augmentations/typeMatching/intelligentTypeMatcher.js +103 -389
  73. package/dist/augmentations/universalDisplayAugmentation.d.ts +2 -2
  74. package/dist/augmentations/universalDisplayAugmentation.js +2 -2
  75. package/dist/brainy-unified.d.ts +106 -0
  76. package/dist/brainy-unified.js +327 -0
  77. package/dist/brainy.d.ts +273 -0
  78. package/dist/brainy.js +1181 -0
  79. package/dist/brainyData.d.ts +29 -72
  80. package/dist/brainyData.js +350 -304
  81. package/dist/brainyDataV3.d.ts +186 -0
  82. package/dist/brainyDataV3.js +337 -0
  83. package/dist/browserFramework.d.ts +6 -6
  84. package/dist/browserFramework.js +11 -8
  85. package/dist/browserFramework.minimal.d.ts +5 -5
  86. package/dist/browserFramework.minimal.js +11 -8
  87. package/dist/config/index.d.ts +2 -2
  88. package/dist/config/index.js +3 -3
  89. package/dist/config/modelAutoConfig.d.ts +6 -7
  90. package/dist/config/modelAutoConfig.js +17 -76
  91. package/dist/cortex/backupRestore.d.ts +2 -2
  92. package/dist/cortex/backupRestore.js +85 -27
  93. package/dist/cortex/healthCheck.d.ts +2 -2
  94. package/dist/cortex/neuralImport.d.ts +2 -2
  95. package/dist/cortex/neuralImport.js +18 -13
  96. package/dist/cortex/performanceMonitor.d.ts +2 -2
  97. package/dist/critical/model-guardian.d.ts +4 -0
  98. package/dist/critical/model-guardian.js +31 -11
  99. package/dist/demo.d.ts +4 -4
  100. package/dist/demo.js +7 -7
  101. package/dist/distributed/cacheSync.d.ts +112 -0
  102. package/dist/distributed/cacheSync.js +265 -0
  103. package/dist/distributed/coordinator.d.ts +193 -0
  104. package/dist/distributed/coordinator.js +548 -0
  105. package/dist/distributed/httpTransport.d.ts +120 -0
  106. package/dist/distributed/httpTransport.js +446 -0
  107. package/dist/distributed/index.d.ts +8 -0
  108. package/dist/distributed/index.js +5 -0
  109. package/dist/distributed/networkTransport.d.ts +132 -0
  110. package/dist/distributed/networkTransport.js +633 -0
  111. package/dist/distributed/queryPlanner.d.ts +104 -0
  112. package/dist/distributed/queryPlanner.js +327 -0
  113. package/dist/distributed/readWriteSeparation.d.ts +134 -0
  114. package/dist/distributed/readWriteSeparation.js +350 -0
  115. package/dist/distributed/shardManager.d.ts +114 -0
  116. package/dist/distributed/shardManager.js +357 -0
  117. package/dist/distributed/shardMigration.d.ts +110 -0
  118. package/dist/distributed/shardMigration.js +289 -0
  119. package/dist/distributed/storageDiscovery.d.ts +160 -0
  120. package/dist/distributed/storageDiscovery.js +551 -0
  121. package/dist/embeddings/EmbeddingManager.d.ts +0 -4
  122. package/dist/embeddings/EmbeddingManager.js +21 -26
  123. package/dist/errors/brainyError.d.ts +5 -1
  124. package/dist/errors/brainyError.js +12 -0
  125. package/dist/examples/basicUsage.js +3 -3
  126. package/dist/graph/graphAdjacencyIndex.d.ts +96 -0
  127. package/dist/graph/graphAdjacencyIndex.js +288 -0
  128. package/dist/graph/pathfinding.js +4 -2
  129. package/dist/hnsw/scaledHNSWSystem.js +11 -2
  130. package/dist/importManager.js +6 -3
  131. package/dist/index.d.ts +12 -21
  132. package/dist/index.js +14 -22
  133. package/dist/mcp/brainyMCPAdapter.d.ts +4 -4
  134. package/dist/mcp/brainyMCPAdapter.js +5 -5
  135. package/dist/mcp/brainyMCPService.d.ts +3 -3
  136. package/dist/mcp/brainyMCPService.js +3 -11
  137. package/dist/mcp/mcpAugmentationToolset.js +20 -30
  138. package/dist/neural/embeddedPatterns.d.ts +1 -1
  139. package/dist/neural/embeddedPatterns.js +2 -2
  140. package/dist/neural/entityExtractor.d.ts +65 -0
  141. package/dist/neural/entityExtractor.js +316 -0
  142. package/dist/neural/improvedNeuralAPI.js +90 -79
  143. package/dist/neural/naturalLanguageProcessor.d.ts +155 -10
  144. package/dist/neural/naturalLanguageProcessor.js +941 -66
  145. package/dist/neural/naturalLanguageProcessorStatic.d.ts +2 -2
  146. package/dist/neural/naturalLanguageProcessorStatic.js +3 -3
  147. package/dist/neural/neuralAPI.js +8 -2
  148. package/dist/neural/patternLibrary.d.ts +57 -3
  149. package/dist/neural/patternLibrary.js +348 -13
  150. package/dist/neural/staticPatternMatcher.d.ts +2 -2
  151. package/dist/neural/staticPatternMatcher.js +2 -2
  152. package/dist/shared/default-augmentations.d.ts +3 -3
  153. package/dist/shared/default-augmentations.js +5 -5
  154. package/dist/storage/adapters/fileSystemStorage.d.ts +4 -0
  155. package/dist/storage/adapters/fileSystemStorage.js +54 -1
  156. package/dist/storage/adapters/memoryStorage.js +13 -8
  157. package/dist/storage/backwardCompatibility.d.ts +10 -78
  158. package/dist/storage/backwardCompatibility.js +17 -132
  159. package/dist/storage/baseStorage.d.ts +6 -0
  160. package/dist/storage/baseStorage.js +17 -0
  161. package/dist/storage/cacheManager.js +2 -2
  162. package/dist/storage/readOnlyOptimizations.js +8 -3
  163. package/dist/streaming/pipeline.d.ts +154 -0
  164. package/dist/streaming/pipeline.js +551 -0
  165. package/dist/triple/TripleIntelligence.d.ts +25 -110
  166. package/dist/triple/TripleIntelligence.js +4 -574
  167. package/dist/triple/TripleIntelligenceSystem.d.ts +159 -0
  168. package/dist/triple/TripleIntelligenceSystem.js +519 -0
  169. package/dist/types/apiTypes.d.ts +278 -0
  170. package/dist/types/apiTypes.js +33 -0
  171. package/dist/types/brainy.types.d.ts +308 -0
  172. package/dist/types/brainy.types.js +8 -0
  173. package/dist/types/brainyDataInterface.d.ts +3 -3
  174. package/dist/types/brainyDataInterface.js +2 -2
  175. package/dist/types/graphTypes.js +2 -2
  176. package/dist/utils/cacheAutoConfig.d.ts +3 -3
  177. package/dist/utils/embedding.js +8 -14
  178. package/dist/utils/enhancedLogger.d.ts +104 -0
  179. package/dist/utils/enhancedLogger.js +232 -0
  180. package/dist/utils/index.d.ts +1 -1
  181. package/dist/utils/index.js +1 -1
  182. package/dist/utils/intelligentTypeMapper.d.ts +60 -0
  183. package/dist/utils/intelligentTypeMapper.js +349 -0
  184. package/dist/utils/metadataIndex.d.ts +118 -1
  185. package/dist/utils/metadataIndex.js +539 -16
  186. package/dist/utils/paramValidation.d.ts +39 -0
  187. package/dist/utils/paramValidation.js +192 -0
  188. package/dist/utils/rateLimiter.d.ts +160 -0
  189. package/dist/utils/rateLimiter.js +271 -0
  190. package/dist/utils/statistics.d.ts +4 -4
  191. package/dist/utils/statistics.js +3 -3
  192. package/dist/utils/structuredLogger.d.ts +146 -0
  193. package/dist/utils/structuredLogger.js +394 -0
  194. package/dist/utils/textEncoding.js +2 -1
  195. package/dist/utils/typeValidation.d.ts +34 -0
  196. package/dist/utils/typeValidation.js +247 -0
  197. package/package.json +14 -6
  198. package/scripts/download-models.cjs +6 -15
  199. package/dist/augmentations/walAugmentation.d.ts +0 -111
  200. package/dist/augmentations/walAugmentation.js +0 -519
  201. package/dist/chat/BrainyChat.d.ts +0 -121
  202. package/dist/chat/BrainyChat.js +0 -396
  203. package/dist/chat/ChatCLI.d.ts +0 -61
  204. package/dist/chat/ChatCLI.js +0 -351
@@ -1,578 +1,8 @@
1
1
  /**
2
- * Triple Intelligence Engine
3
- * Revolutionary unified search combining Vector + Graph + Field intelligence
2
+ * Triple Intelligence Types
3
+ * Defines the query and result types for Triple Intelligence
4
4
  *
5
- * This is Brainy's killer feature - no other database can do this!
5
+ * The actual implementation is in TripleIntelligenceSystem
6
6
  */
7
- /**
8
- * The Triple Intelligence Engine
9
- * Unifies vector, graph, and field search into one beautiful API
10
- */
11
- export class TripleIntelligenceEngine {
12
- constructor(brain) {
13
- this.planCache = new Map();
14
- this.brain = brain;
15
- // Query history removed - unnecessary complexity for minimal gain
16
- }
17
- /**
18
- * The magic happens here - one query to rule them all
19
- */
20
- async find(query) {
21
- const startTime = Date.now();
22
- // Generate optimal query plan
23
- const plan = await this.optimizeQuery(query);
24
- // Execute based on plan
25
- let results;
26
- if (plan.canParallelize) {
27
- // Run all three paths in parallel for maximum speed
28
- results = await this.parallelSearch(query, plan);
29
- }
30
- else {
31
- // Progressive filtering for efficiency
32
- results = await this.progressiveSearch(query, plan);
33
- }
34
- // Apply boosts if requested
35
- if (query.boost) {
36
- results = this.applyBoosts(results, query.boost);
37
- }
38
- // Add explanations if requested
39
- if (query.explain) {
40
- const timing = Date.now() - startTime;
41
- results = this.addExplanations(results, plan, timing);
42
- }
43
- // Query history removed - no learning needed
44
- // Apply limit
45
- if (query.limit) {
46
- results = results.slice(0, query.limit);
47
- }
48
- return results;
49
- }
50
- /**
51
- * Generate optimal execution plan based on query shape
52
- */
53
- async optimizeQuery(query) {
54
- // Short-circuit optimization for single-signal queries
55
- const hasVector = !!(query.like || query.similar);
56
- const hasGraph = !!(query.connected);
57
- const hasField = !!(query.where && Object.keys(query.where).length > 0);
58
- const signalCount = [hasVector, hasGraph, hasField].filter(Boolean).length;
59
- // Single signal - skip fusion entirely!
60
- if (signalCount === 1) {
61
- const singleType = hasVector ? 'vector' : hasGraph ? 'graph' : 'field';
62
- return {
63
- startWith: singleType,
64
- canParallelize: false,
65
- estimatedCost: 1,
66
- steps: [{
67
- type: singleType,
68
- operation: 'direct', // Direct execution, no fusion
69
- estimated: 50
70
- }]
71
- };
72
- }
73
- // Check cache first
74
- const cacheKey = JSON.stringify(query);
75
- if (this.planCache.has(cacheKey)) {
76
- return this.planCache.get(cacheKey);
77
- }
78
- // Multiple operations - optimize
79
- let plan;
80
- if (hasField && this.isSelectiveFilter(query.where)) {
81
- // Start with field filter if it's selective
82
- plan = {
83
- startWith: 'field',
84
- canParallelize: false,
85
- estimatedCost: 2,
86
- steps: [
87
- { type: 'field', operation: 'filter', estimated: 50 },
88
- { type: hasVector ? 'vector' : 'graph', operation: 'search', estimated: 200 },
89
- { type: 'fusion', operation: 'rank', estimated: 50 }
90
- ]
91
- };
92
- }
93
- else if (hasVector && hasGraph) {
94
- // Parallelize vector and graph for speed
95
- plan = {
96
- startWith: 'vector',
97
- canParallelize: true,
98
- estimatedCost: 3,
99
- steps: [
100
- { type: 'vector', operation: 'search', estimated: 150 },
101
- { type: 'graph', operation: 'traverse', estimated: 150 },
102
- { type: 'field', operation: 'filter', estimated: 50 },
103
- { type: 'fusion', operation: 'rank', estimated: 100 }
104
- ]
105
- };
106
- }
107
- else {
108
- // Default progressive plan
109
- plan = {
110
- startWith: 'vector',
111
- canParallelize: false,
112
- estimatedCost: 2,
113
- steps: [
114
- { type: 'vector', operation: 'search', estimated: 150 },
115
- { type: hasGraph ? 'graph' : 'field', operation: 'filter', estimated: 100 },
116
- { type: 'fusion', operation: 'rank', estimated: 50 }
117
- ]
118
- };
119
- }
120
- // Query history removed - use default plan
121
- this.planCache.set(cacheKey, plan);
122
- return plan;
123
- }
124
- /**
125
- * Execute searches in parallel for maximum speed
126
- */
127
- async parallelSearch(query, plan) {
128
- // Check for single-signal optimization
129
- if (plan.steps.length === 1 && plan.steps[0].operation === 'direct') {
130
- // Skip fusion for single signal queries
131
- const results = await this.executeSingleSignal(query, plan.steps[0].type);
132
- return results.map(r => ({
133
- ...r,
134
- fusionScore: r.score || 1.0,
135
- score: r.score || 1.0
136
- }));
137
- }
138
- const tasks = [];
139
- // Vector search
140
- if (query.like || query.similar) {
141
- tasks.push(this.vectorSearch(query.like || query.similar, query.limit));
142
- }
143
- // Graph traversal
144
- if (query.connected) {
145
- tasks.push(this.graphTraversal(query.connected));
146
- }
147
- // Field filtering
148
- if (query.where) {
149
- tasks.push(this.fieldFilter(query.where));
150
- }
151
- // Run all in parallel
152
- const results = await Promise.all(tasks);
153
- // Fusion ranking combines all signals
154
- return this.fusionRank(results, query);
155
- }
156
- /**
157
- * Progressive filtering for efficiency
158
- */
159
- async progressiveSearch(query, plan) {
160
- let candidates = [];
161
- for (const step of plan.steps) {
162
- switch (step.type) {
163
- case 'field':
164
- if (candidates.length === 0) {
165
- // Initial field filter
166
- candidates = await this.fieldFilter(query.where);
167
- }
168
- else {
169
- // Filter existing candidates
170
- candidates = this.applyFieldFilter(candidates, query.where);
171
- }
172
- break;
173
- case 'vector':
174
- // CRITICAL: If we have a previous step that returned 0 candidates,
175
- // we must respect that and not do a fresh search
176
- if (candidates.length === 0 && plan.steps[0].type === 'vector') {
177
- // This is the first step - do initial vector search
178
- const results = await this.vectorSearch(query.like || query.similar, query.limit);
179
- candidates = results;
180
- }
181
- else if (candidates.length > 0) {
182
- // Vector search within existing candidates
183
- candidates = await this.vectorSearchWithin(query.like || query.similar, candidates);
184
- }
185
- // If candidates.length === 0 and this isn't the first step, keep empty candidates
186
- break;
187
- case 'graph':
188
- // CRITICAL: Same logic as vector - respect empty candidates from previous steps
189
- if (candidates.length === 0 && plan.steps[0].type === 'graph') {
190
- // This is the first step - do initial graph traversal
191
- candidates = await this.graphTraversal(query.connected);
192
- }
193
- else if (candidates.length > 0) {
194
- // Graph expansion from existing candidates
195
- candidates = await this.graphExpand(candidates, query.connected);
196
- }
197
- // If candidates.length === 0 and this isn't the first step, keep empty candidates
198
- break;
199
- case 'fusion':
200
- // Final fusion ranking
201
- return this.fusionRank([candidates], query);
202
- }
203
- }
204
- return candidates;
205
- }
206
- /**
207
- * Vector similarity search
208
- */
209
- async vectorSearch(query, limit) {
210
- // Use clean internal vector search to avoid circular dependency
211
- // This is the proper architecture: find() uses internal methods, not public search()
212
- return this.brain._internalVectorSearch(query, limit || 100);
213
- }
214
- /**
215
- * Graph traversal
216
- */
217
- async graphTraversal(connected) {
218
- const results = [];
219
- // Get starting nodes
220
- const startNodes = connected.from ?
221
- (Array.isArray(connected.from) ? connected.from : [connected.from]) :
222
- connected.to ?
223
- (Array.isArray(connected.to) ? connected.to : [connected.to]) :
224
- [];
225
- // Traverse graph
226
- for (const nodeId of startNodes) {
227
- // Get verbs connected to this node (both as source and target)
228
- const [sourceVerbs, targetVerbs] = await Promise.all([
229
- this.brain.getVerbsBySource(nodeId),
230
- this.brain.getVerbsByTarget(nodeId)
231
- ]);
232
- const allVerbs = [...sourceVerbs, ...targetVerbs];
233
- const connections = allVerbs.map((v) => ({
234
- id: v.targetId === nodeId ? v.sourceId : v.targetId,
235
- type: v.type,
236
- score: v.weight || 0.5
237
- }));
238
- results.push(...connections);
239
- }
240
- return results;
241
- }
242
- /**
243
- * Field-based filtering
244
- */
245
- async fieldFilter(where) {
246
- // CRITICAL OPTIMIZATION: Use MetadataIndex directly for O(log n) performance!
247
- // NOT vector search which would be O(n) and slow
248
- if (!where || Object.keys(where).length === 0) {
249
- // Return all items (should use a more efficient method)
250
- const allNouns = this.brain.index.getNouns();
251
- return Array.from(allNouns.keys()).slice(0, 1000).map(id => ({ id, score: 1.0 }));
252
- }
253
- // Use the MetadataIndex directly for FAST field queries!
254
- // This uses B-tree indexes for O(log n) range queries
255
- // and hash indexes for O(1) exact matches
256
- const metadataIndex = this.brain.metadataIndex;
257
- // Check if metadata index is properly initialized
258
- if (!metadataIndex || typeof metadataIndex.getIdsForFilter !== 'function') {
259
- // Fallback to manual filtering - slower but works
260
- return this.manualMetadataFilter(where);
261
- }
262
- const matchingIds = await metadataIndex.getIdsForFilter(where) || [];
263
- // Convert to result format with metadata
264
- const results = [];
265
- for (const id of matchingIds.slice(0, 1000)) {
266
- const noun = await this.brain.getNoun(id);
267
- if (noun) {
268
- results.push({
269
- id,
270
- score: 1.0, // Field matches are binary - either match or don't
271
- metadata: noun.metadata || {}
272
- });
273
- }
274
- }
275
- return results;
276
- }
277
- /**
278
- * Fallback manual metadata filtering when index is not available
279
- */
280
- async manualMetadataFilter(where) {
281
- const { matchesMetadataFilter } = await import('../utils/metadataFilter.js');
282
- const results = [];
283
- // Get all nouns and manually filter them
284
- const allNouns = this.brain.index.getNouns();
285
- for (const [id, noun] of Array.from(allNouns.entries()).slice(0, 1000)) {
286
- if (noun && matchesMetadataFilter(noun.metadata || {}, where)) {
287
- results.push({
288
- id,
289
- score: 1.0,
290
- metadata: noun.metadata || {}
291
- });
292
- }
293
- }
294
- return results;
295
- }
296
- /**
297
- * Fusion ranking combines all signals
298
- */
299
- fusionRank(resultSets, query) {
300
- // PERFORMANCE CRITICAL: When metadata filters are present, use INTERSECTION not UNION
301
- // This ensures O(log n) performance with millions of items
302
- // Determine which result sets we have based on query
303
- let vectorResultsIdx = -1;
304
- let graphResultsIdx = -1;
305
- let metadataResultsIdx = -1;
306
- let currentIdx = 0;
307
- if (query.like || query.similar) {
308
- vectorResultsIdx = currentIdx++;
309
- }
310
- if (query.connected) {
311
- graphResultsIdx = currentIdx++;
312
- }
313
- if (query.where) {
314
- metadataResultsIdx = currentIdx++;
315
- }
316
- // If we have metadata filters AND other searches, apply intersection
317
- if (metadataResultsIdx >= 0 && resultSets.length > 1) {
318
- const metadataResults = resultSets[metadataResultsIdx];
319
- // CRITICAL: If metadata filter returned no results, entire query should return empty
320
- // This ensures correct behavior for non-matching filters
321
- if (metadataResults.length === 0) {
322
- // Return empty results immediately
323
- return [];
324
- }
325
- const metadataIds = new Set(metadataResults.map(r => r.id || r));
326
- // Filter ALL other result sets to only include items that match metadata
327
- for (let i = 0; i < resultSets.length; i++) {
328
- if (i !== metadataResultsIdx) {
329
- resultSets[i] = resultSets[i].filter(r => metadataIds.has(r.id || r));
330
- }
331
- }
332
- }
333
- // Combine and deduplicate results
334
- const allResults = new Map();
335
- // Need to capture indices for closure
336
- const vectorIdx = vectorResultsIdx;
337
- const graphIdx = graphResultsIdx;
338
- const metadataIdx = metadataResultsIdx;
339
- // Process each result set
340
- resultSets.forEach((results, index) => {
341
- const weight = 1.0 / resultSets.length;
342
- results.forEach(r => {
343
- const id = r.id || r;
344
- if (!allResults.has(id)) {
345
- allResults.set(id, {
346
- ...r,
347
- id,
348
- vectorScore: 0,
349
- graphScore: 0,
350
- fieldScore: 0,
351
- fusionScore: 0
352
- });
353
- }
354
- const result = allResults.get(id);
355
- // Assign scores based on source (using the indices we calculated)
356
- if (index === vectorIdx) {
357
- result.vectorScore = r.score || 1.0;
358
- }
359
- else if (index === graphIdx) {
360
- result.graphScore = r.score || 1.0;
361
- }
362
- else if (index === metadataIdx) {
363
- result.fieldScore = r.score || 1.0;
364
- }
365
- });
366
- });
367
- // Calculate fusion scores
368
- const results = Array.from(allResults.values());
369
- results.forEach(r => {
370
- // Weighted combination of signals
371
- const vectorWeight = (query.like || query.similar) ? 0.4 : 0;
372
- const graphWeight = query.connected ? 0.3 : 0;
373
- const fieldWeight = query.where ? 0.3 : 0;
374
- // Normalize weights
375
- const totalWeight = vectorWeight + graphWeight + fieldWeight;
376
- if (totalWeight > 0) {
377
- r.fusionScore = ((r.vectorScore || 0) * vectorWeight +
378
- (r.graphScore || 0) * graphWeight +
379
- (r.fieldScore || 0) * fieldWeight) / totalWeight;
380
- }
381
- else {
382
- r.fusionScore = r.score || 0;
383
- }
384
- });
385
- // Sort by fusion score
386
- results.sort((a, b) => b.fusionScore - a.fusionScore);
387
- return results;
388
- }
389
- /**
390
- * Check if a filter is selective enough to use first
391
- */
392
- isSelectiveFilter(where) {
393
- // Heuristic: filters with exact matches or small ranges are selective
394
- for (const [key, value] of Object.entries(where)) {
395
- if (typeof value === 'object' && value !== null) {
396
- // Check for operators that are selective
397
- if (value.equals || value.is || value.oneOf) {
398
- return true;
399
- }
400
- if (value.between && Array.isArray(value.between)) {
401
- const [min, max] = value.between;
402
- if (typeof min === 'number' && typeof max === 'number') {
403
- // Small numeric range is selective
404
- if ((max - min) / Math.max(Math.abs(min), Math.abs(max), 1) < 0.1) {
405
- return true;
406
- }
407
- }
408
- }
409
- }
410
- else {
411
- // Exact match is selective
412
- return true;
413
- }
414
- }
415
- return false;
416
- }
417
- /**
418
- * Apply field filter to existing candidates
419
- */
420
- applyFieldFilter(candidates, where) {
421
- return candidates.filter(c => {
422
- for (const [key, condition] of Object.entries(where)) {
423
- const value = c.metadata?.[key] ?? c[key];
424
- if (typeof condition === 'object' && condition !== null) {
425
- // Handle operators
426
- for (const [op, operand] of Object.entries(condition)) {
427
- if (!this.checkCondition(value, op, operand)) {
428
- return false;
429
- }
430
- }
431
- }
432
- else {
433
- // Direct equality
434
- if (value !== condition) {
435
- return false;
436
- }
437
- }
438
- }
439
- return true;
440
- });
441
- }
442
- /**
443
- * Check a single condition
444
- */
445
- checkCondition(value, operator, operand) {
446
- switch (operator) {
447
- case 'equals':
448
- case 'is':
449
- return value === operand;
450
- case 'greaterThan':
451
- return value > operand;
452
- case 'lessThan':
453
- return value < operand;
454
- case 'oneOf':
455
- return Array.isArray(operand) && operand.includes(value);
456
- case 'contains':
457
- return Array.isArray(value) && value.includes(operand);
458
- default:
459
- return true;
460
- }
461
- }
462
- /**
463
- * Vector search within specific candidates
464
- */
465
- async vectorSearchWithin(query, candidates) {
466
- const ids = candidates.map(c => c.id || c);
467
- return this.brain.searchWithinItems(query, ids, candidates.length);
468
- }
469
- /**
470
- * Expand graph from candidates
471
- */
472
- async graphExpand(candidates, connected) {
473
- const expanded = [];
474
- for (const candidate of candidates) {
475
- // Get verbs connected to this candidate
476
- const nodeId = candidate.id || candidate;
477
- const [sourceVerbs, targetVerbs] = await Promise.all([
478
- this.brain.getVerbsBySource(nodeId),
479
- this.brain.getVerbsByTarget(nodeId)
480
- ]);
481
- const allVerbs = [...sourceVerbs, ...targetVerbs];
482
- const connections = allVerbs.map((v) => ({
483
- id: v.targetId === nodeId ? v.sourceId : v.targetId,
484
- type: v.type,
485
- score: v.weight || 0.5
486
- }));
487
- expanded.push(...connections);
488
- }
489
- return expanded;
490
- }
491
- /**
492
- * Apply boost strategies
493
- */
494
- applyBoosts(results, boost) {
495
- return results.map(r => {
496
- let boostFactor = 1.0;
497
- switch (boost) {
498
- case 'recent':
499
- // Boost recent items
500
- const age = Date.now() - (r.metadata?.timestamp || 0);
501
- boostFactor = Math.exp(-age / (30 * 24 * 60 * 60 * 1000)); // 30-day half-life
502
- break;
503
- case 'popular':
504
- // Boost by view count or connections
505
- boostFactor = Math.log10((r.metadata?.views || 0) + 10) / 2;
506
- break;
507
- case 'verified':
508
- // Boost verified content
509
- boostFactor = r.metadata?.verified ? 1.5 : 1.0;
510
- break;
511
- }
512
- return {
513
- ...r,
514
- fusionScore: r.fusionScore * boostFactor
515
- };
516
- });
517
- }
518
- /**
519
- * Add query explanations for debugging
520
- */
521
- addExplanations(results, plan, totalTime) {
522
- return results.map(r => ({
523
- ...r,
524
- explanation: {
525
- plan: plan.steps.map(s => `${s.type}:${s.operation}`).join(' → '),
526
- timing: {
527
- total: totalTime,
528
- ...plan.steps.reduce((acc, step) => ({
529
- ...acc,
530
- [step.type]: step.estimated
531
- }), {})
532
- },
533
- boosts: []
534
- }
535
- }));
536
- }
537
- // Query learning removed - unnecessary complexity
538
- /**
539
- * Optimize plan based on historical patterns
540
- */
541
- // Query optimization from history removed
542
- /**
543
- * Execute single signal query without fusion
544
- */
545
- async executeSingleSignal(query, type) {
546
- switch (type) {
547
- case 'vector':
548
- return this.vectorSearch(query.like || query.similar, query.limit);
549
- case 'graph':
550
- return this.graphTraversal(query.connected);
551
- case 'field':
552
- return this.fieldFilter(query.where);
553
- default:
554
- return [];
555
- }
556
- }
557
- /**
558
- * Clear query optimization cache
559
- */
560
- clearCache() {
561
- this.planCache.clear();
562
- }
563
- /**
564
- * Get optimization statistics
565
- */
566
- getStats() {
567
- return {
568
- cachedPlans: this.planCache.size,
569
- historySize: 0 // Query history removed
570
- };
571
- }
572
- }
573
- // Export a beautiful, simple API
574
- export async function find(brain, query) {
575
- const engine = new TripleIntelligenceEngine(brain);
576
- return engine.find(query);
577
- }
7
+ export {};
578
8
  //# sourceMappingURL=TripleIntelligence.js.map