@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.
- package/CHANGELOG.md +18 -0
- package/README.md +249 -152
- 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 +288 -7
- 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 +87 -8
- package/dist/augmentations/brainyAugmentation.js +159 -2
- package/dist/augmentations/cacheAugmentation.d.ts +6 -5
- package/dist/augmentations/cacheAugmentation.js +113 -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 +9 -11
- package/dist/augmentations/defaultAugmentations.js +4 -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/intelligentComputation.d.ts +1 -1
- package/dist/augmentations/display/intelligentComputation.js +4 -4
- package/dist/augmentations/entityRegistryAugmentation.d.ts +3 -1
- package/dist/augmentations/entityRegistryAugmentation.js +5 -1
- package/dist/augmentations/indexAugmentation.d.ts +3 -3
- package/dist/augmentations/indexAugmentation.js +2 -2
- package/dist/augmentations/intelligentVerbScoringAugmentation.d.ts +22 -6
- package/dist/augmentations/intelligentVerbScoringAugmentation.js +106 -23
- 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/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/intelligentTypeMatcher.d.ts +39 -59
- package/dist/augmentations/typeMatching/intelligentTypeMatcher.js +103 -389
- package/dist/augmentations/universalDisplayAugmentation.d.ts +2 -2
- package/dist/augmentations/universalDisplayAugmentation.js +2 -2
- package/dist/brainy-unified.d.ts +106 -0
- package/dist/brainy-unified.js +327 -0
- package/dist/brainy.d.ts +273 -0
- package/dist/brainy.js +1181 -0
- package/dist/brainyData.d.ts +29 -72
- package/dist/brainyData.js +350 -304
- package/dist/brainyDataV3.d.ts +186 -0
- package/dist/brainyDataV3.js +337 -0
- package/dist/browserFramework.d.ts +6 -6
- package/dist/browserFramework.js +11 -8
- package/dist/browserFramework.minimal.d.ts +5 -5
- package/dist/browserFramework.minimal.js +11 -8
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.js +3 -3
- package/dist/config/modelAutoConfig.d.ts +6 -7
- package/dist/config/modelAutoConfig.js +17 -76
- 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/EmbeddingManager.d.ts +0 -4
- package/dist/embeddings/EmbeddingManager.js +21 -26
- package/dist/errors/brainyError.d.ts +5 -1
- package/dist/errors/brainyError.js +12 -0
- package/dist/examples/basicUsage.js +3 -3
- 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 +6 -3
- package/dist/index.d.ts +12 -21
- package/dist/index.js +14 -22
- 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.js +90 -79
- 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/shared/default-augmentations.d.ts +3 -3
- package/dist/shared/default-augmentations.js +5 -5
- package/dist/storage/adapters/fileSystemStorage.d.ts +4 -0
- package/dist/storage/adapters/fileSystemStorage.js +54 -1
- package/dist/storage/adapters/memoryStorage.js +13 -8
- package/dist/storage/backwardCompatibility.d.ts +10 -78
- package/dist/storage/backwardCompatibility.js +17 -132
- package/dist/storage/baseStorage.d.ts +6 -0
- package/dist/storage/baseStorage.js +17 -0
- 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 +3 -3
- package/dist/types/brainyDataInterface.js +2 -2
- package/dist/types/graphTypes.js +2 -2
- package/dist/utils/cacheAutoConfig.d.ts +3 -3
- package/dist/utils/embedding.js +8 -14
- package/dist/utils/enhancedLogger.d.ts +104 -0
- package/dist/utils/enhancedLogger.js +232 -0
- 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/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 +34 -0
- package/dist/utils/typeValidation.js +247 -0
- package/package.json +14 -6
- package/scripts/download-models.cjs +6 -15
- package/dist/augmentations/walAugmentation.d.ts +0 -111
- package/dist/augmentations/walAugmentation.js +0 -519
- 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,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Triple Intelligence System - Consolidated, Production-Ready Implementation
|
|
3
|
+
*
|
|
4
|
+
* NO FALLBACKS - NO MOCKS - NO STUBS - REAL PERFORMANCE
|
|
5
|
+
*
|
|
6
|
+
* This is the single source of truth for Triple Intelligence operations.
|
|
7
|
+
* All operations MUST use fast paths or FAIL LOUDLY.
|
|
8
|
+
*
|
|
9
|
+
* Performance Guarantees:
|
|
10
|
+
* - Vector search: O(log n) via HNSW
|
|
11
|
+
* - Range queries: O(log n) via B-tree indexes
|
|
12
|
+
* - Graph traversal: O(1) adjacency list lookups
|
|
13
|
+
* - Fusion: O(k log k) where k = result count
|
|
14
|
+
*/
|
|
15
|
+
import { HNSWIndex } from '../hnsw/hnswIndex.js';
|
|
16
|
+
import { MetadataIndexManager } from '../utils/metadataIndex.js';
|
|
17
|
+
import { Vector } from '../coreTypes.js';
|
|
18
|
+
export interface TripleQuery {
|
|
19
|
+
similar?: string;
|
|
20
|
+
like?: string;
|
|
21
|
+
vector?: Vector;
|
|
22
|
+
where?: Record<string, any>;
|
|
23
|
+
connected?: {
|
|
24
|
+
from?: string;
|
|
25
|
+
to?: string;
|
|
26
|
+
type?: string;
|
|
27
|
+
direction?: 'in' | 'out' | 'both';
|
|
28
|
+
depth?: number;
|
|
29
|
+
};
|
|
30
|
+
limit?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface TripleOptions {
|
|
33
|
+
fusion?: {
|
|
34
|
+
strategy?: 'rrf' | 'weighted' | 'adaptive';
|
|
35
|
+
weights?: Record<string, number>;
|
|
36
|
+
k?: number;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
interface GraphAdjacencyIndex {
|
|
40
|
+
getNeighbors(id: string, direction?: 'in' | 'out' | 'both'): Promise<string[]>;
|
|
41
|
+
size(): number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Performance metrics for monitoring and assertions
|
|
45
|
+
*/
|
|
46
|
+
export declare class PerformanceMetrics {
|
|
47
|
+
private operations;
|
|
48
|
+
private slowQueries;
|
|
49
|
+
private totalItems;
|
|
50
|
+
recordOperation(type: string, elapsed: number, itemCount?: number): void;
|
|
51
|
+
private getExpectedTime;
|
|
52
|
+
setTotalItems(count: number): void;
|
|
53
|
+
getReport(): PerformanceReport;
|
|
54
|
+
reset(): void;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The main Triple Intelligence System
|
|
58
|
+
*/
|
|
59
|
+
export declare class TripleIntelligenceSystem {
|
|
60
|
+
private metadataIndex;
|
|
61
|
+
private hnswIndex;
|
|
62
|
+
private graphIndex;
|
|
63
|
+
private metrics;
|
|
64
|
+
private planner;
|
|
65
|
+
private embedder;
|
|
66
|
+
private storage;
|
|
67
|
+
constructor(metadataIndex: MetadataIndexManager, hnswIndex: HNSWIndex, graphIndex: GraphAdjacencyIndex, embedder: (text: string) => Promise<Vector>, storage: any);
|
|
68
|
+
/**
|
|
69
|
+
* Main find method - executes Triple Intelligence queries
|
|
70
|
+
*/
|
|
71
|
+
find(query: TripleQuery, options?: TripleOptions): Promise<TripleResult[]>;
|
|
72
|
+
/**
|
|
73
|
+
* Vector search using HNSW for O(log n) performance
|
|
74
|
+
*/
|
|
75
|
+
private vectorSearch;
|
|
76
|
+
/**
|
|
77
|
+
* Field filtering using MetadataIndex for O(log n) performance
|
|
78
|
+
*/
|
|
79
|
+
private fieldFilter;
|
|
80
|
+
/**
|
|
81
|
+
* Graph traversal using adjacency lists for O(1) lookups
|
|
82
|
+
*/
|
|
83
|
+
private graphTraversal;
|
|
84
|
+
/**
|
|
85
|
+
* Execute the query plan
|
|
86
|
+
*/
|
|
87
|
+
private executeQueryPlan;
|
|
88
|
+
/**
|
|
89
|
+
* Fuse results using Reciprocal Rank Fusion (RRF)
|
|
90
|
+
*/
|
|
91
|
+
private fuseResults;
|
|
92
|
+
/**
|
|
93
|
+
* Validate query parameters
|
|
94
|
+
*/
|
|
95
|
+
private validateQuery;
|
|
96
|
+
/**
|
|
97
|
+
* Verify required indexes are available
|
|
98
|
+
*/
|
|
99
|
+
private verifyIndexes;
|
|
100
|
+
/**
|
|
101
|
+
* Assert performance guarantees
|
|
102
|
+
*/
|
|
103
|
+
private assertPerformance;
|
|
104
|
+
/**
|
|
105
|
+
* Check if where clause has range operators
|
|
106
|
+
*/
|
|
107
|
+
private hasRangeOperators;
|
|
108
|
+
/**
|
|
109
|
+
* Update item count for metrics
|
|
110
|
+
*/
|
|
111
|
+
private updateItemCount;
|
|
112
|
+
/**
|
|
113
|
+
* Get total item count across all indexes
|
|
114
|
+
*/
|
|
115
|
+
private getTotalItems;
|
|
116
|
+
/**
|
|
117
|
+
* Get performance metrics
|
|
118
|
+
*/
|
|
119
|
+
getMetrics(): PerformanceMetrics;
|
|
120
|
+
/**
|
|
121
|
+
* Reset performance metrics
|
|
122
|
+
*/
|
|
123
|
+
resetMetrics(): void;
|
|
124
|
+
}
|
|
125
|
+
interface QueryLog {
|
|
126
|
+
type: string;
|
|
127
|
+
elapsed: number;
|
|
128
|
+
expectedTime: number;
|
|
129
|
+
timestamp: number;
|
|
130
|
+
itemCount: number;
|
|
131
|
+
}
|
|
132
|
+
interface PerformanceReport {
|
|
133
|
+
operations: Record<string, {
|
|
134
|
+
avgTime: number;
|
|
135
|
+
maxTime: number;
|
|
136
|
+
minTime: number;
|
|
137
|
+
violations: number;
|
|
138
|
+
violationRate: number;
|
|
139
|
+
totalCalls: number;
|
|
140
|
+
}>;
|
|
141
|
+
violations: Array<{
|
|
142
|
+
type: string;
|
|
143
|
+
count: number;
|
|
144
|
+
rate: number;
|
|
145
|
+
}>;
|
|
146
|
+
slowQueries: QueryLog[];
|
|
147
|
+
}
|
|
148
|
+
interface TripleResult {
|
|
149
|
+
id: string;
|
|
150
|
+
score: number;
|
|
151
|
+
entity: any;
|
|
152
|
+
metadata: Record<string, any>;
|
|
153
|
+
vectorScore?: number;
|
|
154
|
+
fieldScore?: number;
|
|
155
|
+
graphScore?: number;
|
|
156
|
+
fusionScore?: number;
|
|
157
|
+
depth?: number;
|
|
158
|
+
}
|
|
159
|
+
export {};
|
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Triple Intelligence System - Consolidated, Production-Ready Implementation
|
|
3
|
+
*
|
|
4
|
+
* NO FALLBACKS - NO MOCKS - NO STUBS - REAL PERFORMANCE
|
|
5
|
+
*
|
|
6
|
+
* This is the single source of truth for Triple Intelligence operations.
|
|
7
|
+
* All operations MUST use fast paths or FAIL LOUDLY.
|
|
8
|
+
*
|
|
9
|
+
* Performance Guarantees:
|
|
10
|
+
* - Vector search: O(log n) via HNSW
|
|
11
|
+
* - Range queries: O(log n) via B-tree indexes
|
|
12
|
+
* - Graph traversal: O(1) adjacency list lookups
|
|
13
|
+
* - Fusion: O(k log k) where k = result count
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Performance metrics for monitoring and assertions
|
|
17
|
+
*/
|
|
18
|
+
export class PerformanceMetrics {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.operations = new Map();
|
|
21
|
+
this.slowQueries = [];
|
|
22
|
+
this.totalItems = 0;
|
|
23
|
+
}
|
|
24
|
+
recordOperation(type, elapsed, itemCount) {
|
|
25
|
+
const stats = this.operations.get(type) || {
|
|
26
|
+
count: 0,
|
|
27
|
+
totalTime: 0,
|
|
28
|
+
maxTime: 0,
|
|
29
|
+
minTime: Infinity,
|
|
30
|
+
violations: 0
|
|
31
|
+
};
|
|
32
|
+
stats.count++;
|
|
33
|
+
stats.totalTime += elapsed;
|
|
34
|
+
stats.maxTime = Math.max(stats.maxTime, elapsed);
|
|
35
|
+
stats.minTime = Math.min(stats.minTime, elapsed);
|
|
36
|
+
// Check for O(log n) violation
|
|
37
|
+
const expectedTime = this.getExpectedTime(type, itemCount || this.totalItems);
|
|
38
|
+
if (elapsed > expectedTime * 2) {
|
|
39
|
+
stats.violations++;
|
|
40
|
+
console.error(`⚠️ Performance violation in ${type}: ${elapsed.toFixed(2)}ms > expected ${expectedTime.toFixed(2)}ms`);
|
|
41
|
+
this.slowQueries.push({
|
|
42
|
+
type,
|
|
43
|
+
elapsed,
|
|
44
|
+
expectedTime,
|
|
45
|
+
timestamp: Date.now(),
|
|
46
|
+
itemCount: itemCount || this.totalItems
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
this.operations.set(type, stats);
|
|
50
|
+
}
|
|
51
|
+
getExpectedTime(type, itemCount) {
|
|
52
|
+
// O(log n) operations should complete in roughly log2(n) * k milliseconds
|
|
53
|
+
// where k is a constant based on the operation type
|
|
54
|
+
const logN = Math.log2(Math.max(1, itemCount));
|
|
55
|
+
switch (type) {
|
|
56
|
+
case 'vector_search':
|
|
57
|
+
return logN * 5; // HNSW is very efficient
|
|
58
|
+
case 'field_filter':
|
|
59
|
+
return logN * 3; // B-tree operations are fast
|
|
60
|
+
case 'graph_traversal':
|
|
61
|
+
return 10; // O(1) adjacency list lookups
|
|
62
|
+
case 'fusion':
|
|
63
|
+
return Math.log2(Math.max(1, itemCount)) * 2; // O(k log k) sorting
|
|
64
|
+
default:
|
|
65
|
+
return logN * 10; // Conservative estimate
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
setTotalItems(count) {
|
|
69
|
+
this.totalItems = count;
|
|
70
|
+
}
|
|
71
|
+
getReport() {
|
|
72
|
+
const report = {
|
|
73
|
+
operations: {},
|
|
74
|
+
violations: [],
|
|
75
|
+
slowQueries: this.slowQueries.slice(-100) // Last 100 slow queries
|
|
76
|
+
};
|
|
77
|
+
for (const [type, stats] of this.operations) {
|
|
78
|
+
report.operations[type] = {
|
|
79
|
+
avgTime: stats.totalTime / stats.count,
|
|
80
|
+
maxTime: stats.maxTime,
|
|
81
|
+
minTime: stats.minTime,
|
|
82
|
+
violations: stats.violations,
|
|
83
|
+
violationRate: stats.violations / stats.count,
|
|
84
|
+
totalCalls: stats.count
|
|
85
|
+
};
|
|
86
|
+
if (stats.violations > 0) {
|
|
87
|
+
report.violations.push({
|
|
88
|
+
type,
|
|
89
|
+
count: stats.violations,
|
|
90
|
+
rate: stats.violations / stats.count
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return report;
|
|
95
|
+
}
|
|
96
|
+
reset() {
|
|
97
|
+
this.operations.clear();
|
|
98
|
+
this.slowQueries = [];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Query execution planner - optimizes query execution order
|
|
103
|
+
*/
|
|
104
|
+
class QueryPlanner {
|
|
105
|
+
/**
|
|
106
|
+
* Build an optimized execution plan for a query
|
|
107
|
+
*/
|
|
108
|
+
buildPlan(query) {
|
|
109
|
+
const plan = {
|
|
110
|
+
steps: [],
|
|
111
|
+
estimatedCost: 0,
|
|
112
|
+
requiresIndexes: []
|
|
113
|
+
};
|
|
114
|
+
// Determine which indexes are required
|
|
115
|
+
if (query.similar || query.like) {
|
|
116
|
+
plan.requiresIndexes.push('hnsw');
|
|
117
|
+
}
|
|
118
|
+
if (query.where) {
|
|
119
|
+
plan.requiresIndexes.push('metadata');
|
|
120
|
+
}
|
|
121
|
+
if (query.connected) {
|
|
122
|
+
plan.requiresIndexes.push('graph');
|
|
123
|
+
}
|
|
124
|
+
// Order operations by selectivity (most selective first)
|
|
125
|
+
// This minimizes the working set for subsequent operations
|
|
126
|
+
// 1. Field filters are usually most selective
|
|
127
|
+
if (query.where) {
|
|
128
|
+
plan.steps.push({
|
|
129
|
+
type: 'field',
|
|
130
|
+
operation: 'filter',
|
|
131
|
+
requiresFastPath: true,
|
|
132
|
+
estimatedSelectivity: 0.1 // Assume 10% match rate
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
// 2. Graph traversal is moderately selective
|
|
136
|
+
if (query.connected) {
|
|
137
|
+
plan.steps.push({
|
|
138
|
+
type: 'graph',
|
|
139
|
+
operation: 'traverse',
|
|
140
|
+
requiresFastPath: true,
|
|
141
|
+
estimatedSelectivity: 0.3
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
// 3. Vector search is least selective (returns top-k)
|
|
145
|
+
if (query.similar || query.like) {
|
|
146
|
+
plan.steps.push({
|
|
147
|
+
type: 'vector',
|
|
148
|
+
operation: 'search',
|
|
149
|
+
requiresFastPath: true,
|
|
150
|
+
estimatedSelectivity: 1.0
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Calculate estimated cost
|
|
154
|
+
plan.estimatedCost = plan.steps.reduce((cost, step) => {
|
|
155
|
+
return cost + (1 / step.estimatedSelectivity);
|
|
156
|
+
}, 0);
|
|
157
|
+
return plan;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* The main Triple Intelligence System
|
|
162
|
+
*/
|
|
163
|
+
export class TripleIntelligenceSystem {
|
|
164
|
+
constructor(metadataIndex, hnswIndex, graphIndex, embedder, storage) {
|
|
165
|
+
// REQUIRE all components - no fallbacks
|
|
166
|
+
if (!metadataIndex) {
|
|
167
|
+
throw new Error('MetadataIndex required for Triple Intelligence');
|
|
168
|
+
}
|
|
169
|
+
if (!hnswIndex) {
|
|
170
|
+
throw new Error('HNSW index required for Triple Intelligence');
|
|
171
|
+
}
|
|
172
|
+
if (!graphIndex) {
|
|
173
|
+
throw new Error('Graph index required for Triple Intelligence');
|
|
174
|
+
}
|
|
175
|
+
if (!embedder) {
|
|
176
|
+
throw new Error('Embedding function required for Triple Intelligence');
|
|
177
|
+
}
|
|
178
|
+
if (!storage) {
|
|
179
|
+
throw new Error('Storage adapter required for Triple Intelligence');
|
|
180
|
+
}
|
|
181
|
+
this.metadataIndex = metadataIndex;
|
|
182
|
+
this.hnswIndex = hnswIndex;
|
|
183
|
+
this.graphIndex = graphIndex;
|
|
184
|
+
this.embedder = embedder;
|
|
185
|
+
this.storage = storage;
|
|
186
|
+
this.metrics = new PerformanceMetrics();
|
|
187
|
+
this.planner = new QueryPlanner();
|
|
188
|
+
// Set initial item count for metrics
|
|
189
|
+
this.updateItemCount();
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Main find method - executes Triple Intelligence queries
|
|
193
|
+
*/
|
|
194
|
+
async find(query, options) {
|
|
195
|
+
const startTime = performance.now();
|
|
196
|
+
// Validate query
|
|
197
|
+
this.validateQuery(query);
|
|
198
|
+
// Build optimized query plan
|
|
199
|
+
const plan = this.planner.buildPlan(query);
|
|
200
|
+
// Verify all required indexes are available
|
|
201
|
+
this.verifyIndexes(plan.requiresIndexes);
|
|
202
|
+
// Execute query plan with NO FALLBACKS
|
|
203
|
+
const results = await this.executeQueryPlan(plan, query, options);
|
|
204
|
+
// Record metrics
|
|
205
|
+
const elapsed = performance.now() - startTime;
|
|
206
|
+
this.metrics.recordOperation('find_query', elapsed, results.length);
|
|
207
|
+
// ASSERT performance guarantees
|
|
208
|
+
this.assertPerformance(elapsed, results.length);
|
|
209
|
+
return results;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Vector search using HNSW for O(log n) performance
|
|
213
|
+
*/
|
|
214
|
+
async vectorSearch(query, limit) {
|
|
215
|
+
const startTime = performance.now();
|
|
216
|
+
// Convert text to vector if needed
|
|
217
|
+
const vector = typeof query === 'string'
|
|
218
|
+
? await this.embedder(query)
|
|
219
|
+
: query;
|
|
220
|
+
// Search using HNSW index - O(log n) guaranteed
|
|
221
|
+
const searchResults = await this.hnswIndex.search(vector, limit);
|
|
222
|
+
// Convert to result format
|
|
223
|
+
const results = [];
|
|
224
|
+
for (const [id, score] of searchResults) {
|
|
225
|
+
const entity = await this.storage.getNoun(id);
|
|
226
|
+
if (entity) {
|
|
227
|
+
results.push({
|
|
228
|
+
id,
|
|
229
|
+
score,
|
|
230
|
+
entity,
|
|
231
|
+
metadata: entity.metadata || {},
|
|
232
|
+
vectorScore: score
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const elapsed = performance.now() - startTime;
|
|
237
|
+
this.metrics.recordOperation('vector_search', elapsed, results.length);
|
|
238
|
+
// Assert O(log n) performance
|
|
239
|
+
const expectedTime = Math.log2(this.hnswIndex.size()) * 5;
|
|
240
|
+
if (elapsed > expectedTime * 2) {
|
|
241
|
+
throw new Error(`Vector search O(log n) violation: ${elapsed.toFixed(2)}ms > ${expectedTime.toFixed(2)}ms`);
|
|
242
|
+
}
|
|
243
|
+
return results;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Field filtering using MetadataIndex for O(log n) performance
|
|
247
|
+
*/
|
|
248
|
+
async fieldFilter(where, limit) {
|
|
249
|
+
const startTime = performance.now();
|
|
250
|
+
// Use MetadataIndex for O(log n) performance
|
|
251
|
+
const matchingIds = await this.metadataIndex.getIdsForFilter(where);
|
|
252
|
+
if (!matchingIds || matchingIds.length === 0) {
|
|
253
|
+
return [];
|
|
254
|
+
}
|
|
255
|
+
// Convert to results with full entities
|
|
256
|
+
const results = [];
|
|
257
|
+
const idsToProcess = limit
|
|
258
|
+
? matchingIds.slice(0, limit)
|
|
259
|
+
: matchingIds;
|
|
260
|
+
// Process in parallel batches for efficiency
|
|
261
|
+
const batchSize = 100;
|
|
262
|
+
for (let i = 0; i < idsToProcess.length; i += batchSize) {
|
|
263
|
+
const batch = idsToProcess.slice(i, i + batchSize);
|
|
264
|
+
const entities = await Promise.all(batch.map(id => this.storage.getNoun(id)));
|
|
265
|
+
for (let j = 0; j < entities.length; j++) {
|
|
266
|
+
const entity = entities[j];
|
|
267
|
+
if (entity) {
|
|
268
|
+
results.push({
|
|
269
|
+
id: batch[j],
|
|
270
|
+
score: 1.0, // Field matches are binary
|
|
271
|
+
entity,
|
|
272
|
+
metadata: entity.metadata || {},
|
|
273
|
+
fieldScore: 1.0
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
const elapsed = performance.now() - startTime;
|
|
279
|
+
this.metrics.recordOperation('field_filter', elapsed, results.length);
|
|
280
|
+
// Assert O(log n) for range queries
|
|
281
|
+
if (this.hasRangeOperators(where)) {
|
|
282
|
+
const expectedTime = Math.log2(1000000) * 3; // Assume max 1M items
|
|
283
|
+
if (elapsed > expectedTime * 2) {
|
|
284
|
+
throw new Error(`Field filter O(log n) violation: ${elapsed.toFixed(2)}ms > ${expectedTime.toFixed(2)}ms`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return results;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Graph traversal using adjacency lists for O(1) lookups
|
|
291
|
+
*/
|
|
292
|
+
async graphTraversal(params) {
|
|
293
|
+
const startTime = performance.now();
|
|
294
|
+
const maxDepth = params.depth || 2;
|
|
295
|
+
const results = [];
|
|
296
|
+
const visited = new Set();
|
|
297
|
+
// BFS traversal with O(1) adjacency lookups
|
|
298
|
+
const queue = [];
|
|
299
|
+
// Initialize queue with starting node(s)
|
|
300
|
+
if (params.from) {
|
|
301
|
+
queue.push({ id: params.from, depth: 0, score: 1.0 });
|
|
302
|
+
}
|
|
303
|
+
while (queue.length > 0) {
|
|
304
|
+
const { id, depth, score } = queue.shift();
|
|
305
|
+
if (visited.has(id) || depth > maxDepth) {
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
visited.add(id);
|
|
309
|
+
// Get entity
|
|
310
|
+
const entity = await this.storage.getNoun(id);
|
|
311
|
+
if (entity) {
|
|
312
|
+
results.push({
|
|
313
|
+
id,
|
|
314
|
+
score: score * Math.pow(0.8, depth), // Decay by distance
|
|
315
|
+
entity,
|
|
316
|
+
metadata: entity.metadata || {},
|
|
317
|
+
graphScore: score,
|
|
318
|
+
depth
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
// Get neighbors - O(1) adjacency list lookup
|
|
322
|
+
if (depth < maxDepth) {
|
|
323
|
+
const neighbors = await this.graphIndex.getNeighbors(id, params.direction);
|
|
324
|
+
for (const neighborId of neighbors) {
|
|
325
|
+
if (!visited.has(neighborId)) {
|
|
326
|
+
queue.push({
|
|
327
|
+
id: neighborId,
|
|
328
|
+
depth: depth + 1,
|
|
329
|
+
score: score * 0.8
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
const elapsed = performance.now() - startTime;
|
|
336
|
+
this.metrics.recordOperation('graph_traversal', elapsed, results.length);
|
|
337
|
+
// Graph traversal should be fast due to O(1) adjacency lookups
|
|
338
|
+
const expectedTime = visited.size * 0.5; // 0.5ms per node
|
|
339
|
+
if (elapsed > expectedTime * 3) {
|
|
340
|
+
throw new Error(`Graph traversal performance warning: ${elapsed.toFixed(2)}ms > ${expectedTime.toFixed(2)}ms`);
|
|
341
|
+
}
|
|
342
|
+
return results;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Execute the query plan
|
|
346
|
+
*/
|
|
347
|
+
async executeQueryPlan(plan, query, options) {
|
|
348
|
+
const limit = query.limit || 10;
|
|
349
|
+
const intermediateResults = new Map();
|
|
350
|
+
// Execute each step in the plan
|
|
351
|
+
for (const step of plan.steps) {
|
|
352
|
+
const stepStartTime = performance.now();
|
|
353
|
+
let stepResults = [];
|
|
354
|
+
switch (step.type) {
|
|
355
|
+
case 'vector':
|
|
356
|
+
stepResults = await this.vectorSearch(query.similar || query.like, limit * 3 // Over-fetch for fusion
|
|
357
|
+
);
|
|
358
|
+
break;
|
|
359
|
+
case 'field':
|
|
360
|
+
stepResults = await this.fieldFilter(query.where, limit * 3);
|
|
361
|
+
break;
|
|
362
|
+
case 'graph':
|
|
363
|
+
stepResults = await this.graphTraversal(query.connected);
|
|
364
|
+
break;
|
|
365
|
+
default:
|
|
366
|
+
throw new Error(`Unknown query step type: ${step.type}`);
|
|
367
|
+
}
|
|
368
|
+
intermediateResults.set(step.type, stepResults);
|
|
369
|
+
const stepElapsed = performance.now() - stepStartTime;
|
|
370
|
+
console.log(`Step ${step.type}:${step.operation} completed in ${stepElapsed.toFixed(2)}ms with ${stepResults.length} results`);
|
|
371
|
+
}
|
|
372
|
+
// Fuse results if multiple signals
|
|
373
|
+
if (intermediateResults.size > 1) {
|
|
374
|
+
return this.fuseResults(intermediateResults, limit, options);
|
|
375
|
+
}
|
|
376
|
+
// Single signal - return as is
|
|
377
|
+
const singleResults = Array.from(intermediateResults.values())[0];
|
|
378
|
+
return singleResults.slice(0, limit);
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Fuse results using Reciprocal Rank Fusion (RRF)
|
|
382
|
+
*/
|
|
383
|
+
fuseResults(resultSets, limit, options) {
|
|
384
|
+
const startTime = performance.now();
|
|
385
|
+
const k = options?.fusion?.k || 60; // RRF constant
|
|
386
|
+
const weights = options?.fusion?.weights || {
|
|
387
|
+
vector: 0.5,
|
|
388
|
+
field: 0.3,
|
|
389
|
+
graph: 0.2
|
|
390
|
+
};
|
|
391
|
+
// Calculate RRF scores
|
|
392
|
+
const fusionScores = new Map();
|
|
393
|
+
const entityMap = new Map();
|
|
394
|
+
for (const [signalType, results] of resultSets) {
|
|
395
|
+
const weight = weights[signalType] || 1.0;
|
|
396
|
+
results.forEach((result, rank) => {
|
|
397
|
+
const rrfScore = weight / (k + rank + 1);
|
|
398
|
+
const currentScore = fusionScores.get(result.id) || 0;
|
|
399
|
+
fusionScores.set(result.id, currentScore + rrfScore);
|
|
400
|
+
// Keep the result with the most information
|
|
401
|
+
if (!entityMap.has(result.id)) {
|
|
402
|
+
entityMap.set(result.id, result);
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
// Sort by fusion score
|
|
407
|
+
const sortedIds = Array.from(fusionScores.entries())
|
|
408
|
+
.sort((a, b) => b[1] - a[1])
|
|
409
|
+
.slice(0, limit);
|
|
410
|
+
// Build final results
|
|
411
|
+
const results = [];
|
|
412
|
+
for (const [id, fusionScore] of sortedIds) {
|
|
413
|
+
const result = entityMap.get(id);
|
|
414
|
+
results.push({
|
|
415
|
+
...result,
|
|
416
|
+
fusionScore,
|
|
417
|
+
score: fusionScore // Use fusion score as primary score
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
const elapsed = performance.now() - startTime;
|
|
421
|
+
this.metrics.recordOperation('fusion', elapsed, results.length);
|
|
422
|
+
// Fusion should be O(k log k)
|
|
423
|
+
const expectedTime = Math.log2(Math.max(1, fusionScores.size)) * 2;
|
|
424
|
+
if (elapsed > expectedTime * 3) {
|
|
425
|
+
console.warn(`Fusion performance warning: ${elapsed.toFixed(2)}ms > ${expectedTime.toFixed(2)}ms`);
|
|
426
|
+
}
|
|
427
|
+
return results;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Validate query parameters
|
|
431
|
+
*/
|
|
432
|
+
validateQuery(query) {
|
|
433
|
+
if (!query.similar && !query.like && !query.where && !query.connected) {
|
|
434
|
+
throw new Error('Query must specify at least one of: similar, like, where, or connected');
|
|
435
|
+
}
|
|
436
|
+
if (query.limit && (query.limit < 1 || query.limit > 10000)) {
|
|
437
|
+
throw new Error('Query limit must be between 1 and 10000');
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Verify required indexes are available
|
|
442
|
+
*/
|
|
443
|
+
verifyIndexes(required) {
|
|
444
|
+
for (const index of required) {
|
|
445
|
+
switch (index) {
|
|
446
|
+
case 'hnsw':
|
|
447
|
+
if (!this.hnswIndex || this.hnswIndex.size() === 0) {
|
|
448
|
+
throw new Error('HNSW index not available or empty');
|
|
449
|
+
}
|
|
450
|
+
break;
|
|
451
|
+
case 'metadata':
|
|
452
|
+
if (!this.metadataIndex) {
|
|
453
|
+
throw new Error('Metadata index not available');
|
|
454
|
+
}
|
|
455
|
+
break;
|
|
456
|
+
case 'graph':
|
|
457
|
+
if (!this.graphIndex) {
|
|
458
|
+
throw new Error('Graph index not available');
|
|
459
|
+
}
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Assert performance guarantees
|
|
466
|
+
*/
|
|
467
|
+
assertPerformance(elapsed, resultCount) {
|
|
468
|
+
const itemCount = this.getTotalItems();
|
|
469
|
+
const expectedTime = Math.log2(Math.max(1, itemCount)) * 20; // 20ms per log operation
|
|
470
|
+
if (elapsed > expectedTime * 3) {
|
|
471
|
+
throw new Error(`Query performance violation: ${elapsed.toFixed(2)}ms > expected ${expectedTime.toFixed(2)}ms ` +
|
|
472
|
+
`for ${itemCount} items`);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Check if where clause has range operators
|
|
477
|
+
*/
|
|
478
|
+
hasRangeOperators(where) {
|
|
479
|
+
for (const value of Object.values(where)) {
|
|
480
|
+
if (typeof value === 'object' && value !== null) {
|
|
481
|
+
const keys = Object.keys(value);
|
|
482
|
+
if (keys.some(k => ['$gt', '$gte', '$lt', '$lte', '$between'].includes(k))) {
|
|
483
|
+
return true;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
return false;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Update item count for metrics
|
|
491
|
+
*/
|
|
492
|
+
updateItemCount() {
|
|
493
|
+
const count = this.getTotalItems();
|
|
494
|
+
this.metrics.setTotalItems(count);
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Get total item count across all indexes
|
|
498
|
+
*/
|
|
499
|
+
getTotalItems() {
|
|
500
|
+
// Get the largest count from available indexes
|
|
501
|
+
// Note: MetadataIndexManager might not have a size() method
|
|
502
|
+
// so we'll use HNSW index size as primary indicator
|
|
503
|
+
return Math.max(this.hnswIndex?.size() || 0, 1000000, // Assume max 1M items for now
|
|
504
|
+
this.graphIndex?.size() || 0);
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Get performance metrics
|
|
508
|
+
*/
|
|
509
|
+
getMetrics() {
|
|
510
|
+
return this.metrics;
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Reset performance metrics
|
|
514
|
+
*/
|
|
515
|
+
resetMetrics() {
|
|
516
|
+
this.metrics.reset();
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
//# sourceMappingURL=TripleIntelligenceSystem.js.map
|