@soulcraft/brainy 1.5.0 → 2.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 +188 -0
- package/LICENSE +2 -2
- package/README.md +200 -595
- package/bin/brainy-interactive.js +564 -0
- package/bin/brainy-ts.js +18 -0
- package/bin/brainy.js +672 -81
- package/dist/augmentationPipeline.d.ts +48 -220
- package/dist/augmentationPipeline.js +60 -508
- package/dist/augmentationRegistry.d.ts +22 -31
- package/dist/augmentationRegistry.js +28 -79
- package/dist/augmentations/apiServerAugmentation.d.ts +108 -0
- package/dist/augmentations/apiServerAugmentation.js +502 -0
- package/dist/augmentations/batchProcessingAugmentation.d.ts +95 -0
- package/dist/augmentations/batchProcessingAugmentation.js +567 -0
- package/dist/augmentations/brainyAugmentation.d.ts +153 -0
- package/dist/augmentations/brainyAugmentation.js +145 -0
- package/dist/augmentations/cacheAugmentation.d.ts +105 -0
- package/dist/augmentations/cacheAugmentation.js +238 -0
- package/dist/augmentations/conduitAugmentations.d.ts +54 -156
- package/dist/augmentations/conduitAugmentations.js +156 -1082
- package/dist/augmentations/connectionPoolAugmentation.d.ts +62 -0
- package/dist/augmentations/connectionPoolAugmentation.js +316 -0
- package/dist/augmentations/defaultAugmentations.d.ts +53 -0
- package/dist/augmentations/defaultAugmentations.js +88 -0
- package/dist/augmentations/entityRegistryAugmentation.d.ts +126 -0
- package/dist/augmentations/entityRegistryAugmentation.js +386 -0
- package/dist/augmentations/indexAugmentation.d.ts +117 -0
- package/dist/augmentations/indexAugmentation.js +284 -0
- package/dist/augmentations/intelligentVerbScoringAugmentation.d.ts +152 -0
- package/dist/augmentations/intelligentVerbScoringAugmentation.js +554 -0
- package/dist/augmentations/metricsAugmentation.d.ts +202 -0
- package/dist/augmentations/metricsAugmentation.js +291 -0
- package/dist/augmentations/monitoringAugmentation.d.ts +94 -0
- package/dist/augmentations/monitoringAugmentation.js +227 -0
- package/dist/augmentations/neuralImport.d.ts +50 -117
- package/dist/augmentations/neuralImport.js +255 -629
- package/dist/augmentations/requestDeduplicatorAugmentation.d.ts +52 -0
- package/dist/augmentations/requestDeduplicatorAugmentation.js +162 -0
- package/dist/augmentations/serverSearchAugmentations.d.ts +43 -22
- package/dist/augmentations/serverSearchAugmentations.js +125 -72
- package/dist/augmentations/storageAugmentation.d.ts +54 -0
- package/dist/augmentations/storageAugmentation.js +93 -0
- package/dist/augmentations/storageAugmentations.d.ts +96 -0
- package/dist/augmentations/storageAugmentations.js +182 -0
- package/dist/augmentations/synapseAugmentation.d.ts +156 -0
- package/dist/augmentations/synapseAugmentation.js +312 -0
- package/dist/augmentations/walAugmentation.d.ts +108 -0
- package/dist/augmentations/walAugmentation.js +515 -0
- package/dist/brainyData.d.ts +404 -130
- package/dist/brainyData.js +1331 -853
- package/dist/chat/BrainyChat.d.ts +16 -8
- package/dist/chat/BrainyChat.js +60 -32
- package/dist/chat/ChatCLI.d.ts +1 -1
- package/dist/chat/ChatCLI.js +6 -6
- package/dist/cli/catalog.d.ts +3 -3
- package/dist/cli/catalog.js +116 -70
- package/dist/cli/commands/core.d.ts +61 -0
- package/dist/cli/commands/core.js +348 -0
- package/dist/cli/commands/neural.d.ts +25 -0
- package/dist/cli/commands/neural.js +508 -0
- package/dist/cli/commands/utility.d.ts +37 -0
- package/dist/cli/commands/utility.js +276 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.js +167 -0
- package/dist/cli/interactive.d.ts +164 -0
- package/dist/cli/interactive.js +542 -0
- package/dist/cortex/neuralImport.js +5 -5
- package/dist/critical/model-guardian.js +11 -4
- package/dist/embeddings/lightweight-embedder.d.ts +23 -0
- package/dist/embeddings/lightweight-embedder.js +136 -0
- package/dist/embeddings/universal-memory-manager.d.ts +38 -0
- package/dist/embeddings/universal-memory-manager.js +206 -0
- package/dist/embeddings/worker-embedding.d.ts +7 -0
- package/dist/embeddings/worker-embedding.js +77 -0
- package/dist/embeddings/worker-manager.d.ts +28 -0
- package/dist/embeddings/worker-manager.js +162 -0
- package/dist/examples/basicUsage.js +7 -7
- package/dist/graph/pathfinding.d.ts +78 -0
- package/dist/graph/pathfinding.js +393 -0
- package/dist/hnsw/hnswIndex.d.ts +13 -0
- package/dist/hnsw/hnswIndex.js +35 -0
- package/dist/hnsw/hnswIndexOptimized.d.ts +1 -0
- package/dist/hnsw/hnswIndexOptimized.js +3 -0
- package/dist/index.d.ts +9 -11
- package/dist/index.js +21 -11
- package/dist/indices/fieldIndex.d.ts +76 -0
- package/dist/indices/fieldIndex.js +357 -0
- package/dist/mcp/brainyMCPAdapter.js +3 -2
- package/dist/mcp/mcpAugmentationToolset.js +11 -17
- package/dist/neural/embeddedPatterns.d.ts +41 -0
- package/dist/neural/embeddedPatterns.js +4044 -0
- package/dist/neural/naturalLanguageProcessor.d.ts +94 -0
- package/dist/neural/naturalLanguageProcessor.js +317 -0
- package/dist/neural/naturalLanguageProcessorStatic.d.ts +64 -0
- package/dist/neural/naturalLanguageProcessorStatic.js +151 -0
- package/dist/neural/neuralAPI.d.ts +255 -0
- package/dist/neural/neuralAPI.js +612 -0
- package/dist/neural/patternLibrary.d.ts +101 -0
- package/dist/neural/patternLibrary.js +313 -0
- package/dist/neural/patterns.d.ts +27 -0
- package/dist/neural/patterns.js +68 -0
- package/dist/neural/staticPatternMatcher.d.ts +35 -0
- package/dist/neural/staticPatternMatcher.js +153 -0
- package/dist/scripts/precomputePatternEmbeddings.d.ts +19 -0
- package/dist/scripts/precomputePatternEmbeddings.js +100 -0
- package/dist/storage/adapters/fileSystemStorage.d.ts +5 -0
- package/dist/storage/adapters/fileSystemStorage.js +20 -0
- package/dist/storage/adapters/s3CompatibleStorage.d.ts +5 -0
- package/dist/storage/adapters/s3CompatibleStorage.js +16 -0
- package/dist/storage/enhancedClearOperations.d.ts +83 -0
- package/dist/storage/enhancedClearOperations.js +345 -0
- package/dist/storage/storageFactory.js +31 -27
- package/dist/triple/TripleIntelligence.d.ts +134 -0
- package/dist/triple/TripleIntelligence.js +548 -0
- package/dist/types/augmentations.d.ts +45 -344
- package/dist/types/augmentations.js +5 -2
- package/dist/types/brainyDataInterface.d.ts +20 -10
- package/dist/types/graphTypes.d.ts +46 -0
- package/dist/types/graphTypes.js +16 -2
- package/dist/utils/BoundedRegistry.d.ts +29 -0
- package/dist/utils/BoundedRegistry.js +54 -0
- package/dist/utils/embedding.js +20 -3
- package/dist/utils/hybridModelManager.js +10 -5
- package/dist/utils/metadataFilter.d.ts +33 -19
- package/dist/utils/metadataFilter.js +58 -23
- package/dist/utils/metadataIndex.d.ts +37 -6
- package/dist/utils/metadataIndex.js +427 -64
- package/dist/utils/requestDeduplicator.d.ts +10 -0
- package/dist/utils/requestDeduplicator.js +24 -0
- package/dist/utils/unifiedCache.d.ts +103 -0
- package/dist/utils/unifiedCache.js +311 -0
- package/package.json +40 -125
- package/scripts/ensure-models.js +108 -0
- package/scripts/prepare-models.js +387 -0
- package/OFFLINE_MODELS.md +0 -56
- package/dist/intelligence/neuralEngine.d.ts +0 -207
- package/dist/intelligence/neuralEngine.js +0 -706
- package/dist/utils/modelLoader.d.ts +0 -32
- package/dist/utils/modelLoader.js +0 -219
- package/dist/utils/modelManager.d.ts +0 -77
- package/dist/utils/modelManager.js +0 -219
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🧠 Natural Language Query Processor
|
|
3
|
+
* Auto-breaks down natural language into structured Triple Intelligence queries
|
|
4
|
+
*
|
|
5
|
+
* Uses all of Brainy's sophisticated features:
|
|
6
|
+
* - Embedding model for semantic understanding
|
|
7
|
+
* - Pattern library with 100+ research-based patterns
|
|
8
|
+
* - Entity Registry for concept mapping
|
|
9
|
+
* - Progressive learning from usage
|
|
10
|
+
*/
|
|
11
|
+
import { TripleQuery } from '../triple/TripleIntelligence.js';
|
|
12
|
+
import { BrainyData } from '../brainyData.js';
|
|
13
|
+
export interface NaturalQueryIntent {
|
|
14
|
+
type: 'vector' | 'field' | 'graph' | 'combined';
|
|
15
|
+
confidence: number;
|
|
16
|
+
extractedTerms: {
|
|
17
|
+
searchTerms?: string[];
|
|
18
|
+
fields?: Record<string, any>;
|
|
19
|
+
connections?: {
|
|
20
|
+
entities: string[];
|
|
21
|
+
relationships: string[];
|
|
22
|
+
};
|
|
23
|
+
filters?: Record<string, any>;
|
|
24
|
+
modifiers?: {
|
|
25
|
+
recent?: boolean;
|
|
26
|
+
popular?: boolean;
|
|
27
|
+
limit?: number;
|
|
28
|
+
boost?: string;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export declare class NaturalLanguageProcessor {
|
|
33
|
+
private brain;
|
|
34
|
+
private patternLibrary;
|
|
35
|
+
private queryHistory;
|
|
36
|
+
private initialized;
|
|
37
|
+
constructor(brain: BrainyData);
|
|
38
|
+
/**
|
|
39
|
+
* Initialize the pattern library (lazy loading)
|
|
40
|
+
*/
|
|
41
|
+
private ensureInitialized;
|
|
42
|
+
/**
|
|
43
|
+
* 🎯 MAIN METHOD: Convert natural language to Triple Intelligence query
|
|
44
|
+
*/
|
|
45
|
+
processNaturalQuery(naturalQuery: string): Promise<TripleQuery>;
|
|
46
|
+
/**
|
|
47
|
+
* Hybrid parse when pattern matching fails
|
|
48
|
+
*/
|
|
49
|
+
private hybridParse;
|
|
50
|
+
/**
|
|
51
|
+
* Analyze intent using keywords and structure
|
|
52
|
+
*/
|
|
53
|
+
private analyzeIntent;
|
|
54
|
+
/**
|
|
55
|
+
* Step 2: Use neural analysis to decompose complex queries
|
|
56
|
+
*/
|
|
57
|
+
private decomposeQuery;
|
|
58
|
+
/**
|
|
59
|
+
* Step 3: Map concepts using Entity Registry and taxonomy
|
|
60
|
+
*/
|
|
61
|
+
private mapConcepts;
|
|
62
|
+
/**
|
|
63
|
+
* Step 4: Construct final Triple Intelligence query
|
|
64
|
+
*/
|
|
65
|
+
private constructTripleQuery;
|
|
66
|
+
/**
|
|
67
|
+
* Initialize pattern recognition for common query types
|
|
68
|
+
*/
|
|
69
|
+
private initializePatterns;
|
|
70
|
+
/**
|
|
71
|
+
* Detect field query patterns
|
|
72
|
+
*/
|
|
73
|
+
private hasFieldPatterns;
|
|
74
|
+
/**
|
|
75
|
+
* Detect connection query patterns
|
|
76
|
+
*/
|
|
77
|
+
private hasConnectionPatterns;
|
|
78
|
+
/**
|
|
79
|
+
* Extract terms and modifiers from query
|
|
80
|
+
*/
|
|
81
|
+
private extractTerms;
|
|
82
|
+
/**
|
|
83
|
+
* Find entity matches using Brainy's search capabilities
|
|
84
|
+
*/
|
|
85
|
+
private findEntityMatches;
|
|
86
|
+
/**
|
|
87
|
+
* Check if term is a known field name
|
|
88
|
+
*/
|
|
89
|
+
private isKnownField;
|
|
90
|
+
/**
|
|
91
|
+
* Map colloquial terms to actual field names
|
|
92
|
+
*/
|
|
93
|
+
private mapToFieldName;
|
|
94
|
+
}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🧠 Natural Language Query Processor
|
|
3
|
+
* Auto-breaks down natural language into structured Triple Intelligence queries
|
|
4
|
+
*
|
|
5
|
+
* Uses all of Brainy's sophisticated features:
|
|
6
|
+
* - Embedding model for semantic understanding
|
|
7
|
+
* - Pattern library with 100+ research-based patterns
|
|
8
|
+
* - Entity Registry for concept mapping
|
|
9
|
+
* - Progressive learning from usage
|
|
10
|
+
*/
|
|
11
|
+
import { PatternLibrary } from './patternLibrary.js';
|
|
12
|
+
export class NaturalLanguageProcessor {
|
|
13
|
+
constructor(brain) {
|
|
14
|
+
this.initialized = false;
|
|
15
|
+
this.brain = brain;
|
|
16
|
+
this.patternLibrary = new PatternLibrary(brain);
|
|
17
|
+
this.queryHistory = [];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Initialize the pattern library (lazy loading)
|
|
21
|
+
*/
|
|
22
|
+
async ensureInitialized() {
|
|
23
|
+
if (!this.initialized) {
|
|
24
|
+
await this.patternLibrary.init();
|
|
25
|
+
this.initialized = true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 🎯 MAIN METHOD: Convert natural language to Triple Intelligence query
|
|
30
|
+
*/
|
|
31
|
+
async processNaturalQuery(naturalQuery) {
|
|
32
|
+
await this.ensureInitialized();
|
|
33
|
+
// Step 1: Embed the query for semantic matching
|
|
34
|
+
const queryEmbedding = await this.brain.embed(naturalQuery);
|
|
35
|
+
// Step 2: Find best matching patterns from our library
|
|
36
|
+
const matches = await this.patternLibrary.findBestPatterns(queryEmbedding, 3);
|
|
37
|
+
// Step 3: Try each pattern until we get a good match
|
|
38
|
+
for (const { pattern, similarity } of matches) {
|
|
39
|
+
if (similarity < 0.5)
|
|
40
|
+
break; // Too low similarity, skip
|
|
41
|
+
// Extract slots from the query based on pattern
|
|
42
|
+
const extraction = this.patternLibrary.extractSlots(naturalQuery, pattern);
|
|
43
|
+
if (extraction.confidence > 0.6) {
|
|
44
|
+
// Fill the template with extracted slots
|
|
45
|
+
const query = this.patternLibrary.fillTemplate(pattern.template, extraction.slots);
|
|
46
|
+
// Track this query for learning
|
|
47
|
+
this.queryHistory.push({
|
|
48
|
+
query: naturalQuery,
|
|
49
|
+
result: query,
|
|
50
|
+
success: true // Will be updated based on user behavior
|
|
51
|
+
});
|
|
52
|
+
// Update pattern success metric
|
|
53
|
+
this.patternLibrary.updateSuccessMetric(pattern.id, true);
|
|
54
|
+
return query;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Step 4: Fall back to hybrid approach if no pattern matches well
|
|
58
|
+
return this.hybridParse(naturalQuery, queryEmbedding);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Hybrid parse when pattern matching fails
|
|
62
|
+
*/
|
|
63
|
+
async hybridParse(query, queryEmbedding) {
|
|
64
|
+
// Analyze intent using embeddings and keywords
|
|
65
|
+
const intent = await this.analyzeIntent(query);
|
|
66
|
+
// Find similar successful queries from history
|
|
67
|
+
// TODO: Implement findSimilarQueries method
|
|
68
|
+
// const similar = await this.findSimilarQueries(queryEmbedding)
|
|
69
|
+
// if (similar.length > 0 && similar[0].similarity > 0.9) {
|
|
70
|
+
// // Adapt a very similar previous query
|
|
71
|
+
// return this.adaptQuery(query, similar[0].result)
|
|
72
|
+
// }
|
|
73
|
+
// Extract entities using Brainy's search
|
|
74
|
+
// TODO: Implement extractEntities method
|
|
75
|
+
// const entities = await this.extractEntities(query)
|
|
76
|
+
// Build query based on intent and entities
|
|
77
|
+
// TODO: Implement buildQuery method
|
|
78
|
+
// return this.buildQuery(query, intent, entities)
|
|
79
|
+
// Return a basic query for now
|
|
80
|
+
return {
|
|
81
|
+
like: query,
|
|
82
|
+
limit: 10
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Analyze intent using keywords and structure
|
|
87
|
+
*/
|
|
88
|
+
async analyzeIntent(query) {
|
|
89
|
+
// Use Brainy's embedding function to get semantic representation
|
|
90
|
+
const queryEmbedding = await this.brain.embed(query);
|
|
91
|
+
// Search for similar queries in history (if available)
|
|
92
|
+
let confidence = 0.7; // Base confidence
|
|
93
|
+
let type = 'vector'; // Default
|
|
94
|
+
// Analyze query structure patterns
|
|
95
|
+
const lowerQuery = query.toLowerCase();
|
|
96
|
+
// Detect field queries
|
|
97
|
+
if (this.hasFieldPatterns(lowerQuery)) {
|
|
98
|
+
type = 'field';
|
|
99
|
+
confidence += 0.2;
|
|
100
|
+
}
|
|
101
|
+
// Detect connection queries
|
|
102
|
+
if (this.hasConnectionPatterns(lowerQuery)) {
|
|
103
|
+
type = type === 'field' ? 'combined' : 'graph';
|
|
104
|
+
confidence += 0.1;
|
|
105
|
+
}
|
|
106
|
+
// Extract basic terms
|
|
107
|
+
const extractedTerms = this.extractTerms(query);
|
|
108
|
+
return {
|
|
109
|
+
type,
|
|
110
|
+
confidence: Math.min(confidence, 1.0),
|
|
111
|
+
extractedTerms
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Step 2: Use neural analysis to decompose complex queries
|
|
116
|
+
*/
|
|
117
|
+
async decomposeQuery(query, intent) {
|
|
118
|
+
// Use Brainy's neural clustering to find similar patterns
|
|
119
|
+
const queryTerms = query.split(/\\s+/).filter(term => term.length > 2);
|
|
120
|
+
// Try to find existing entities that match query terms
|
|
121
|
+
const entityMatches = await this.findEntityMatches(queryTerms);
|
|
122
|
+
return {
|
|
123
|
+
originalQuery: query,
|
|
124
|
+
intent,
|
|
125
|
+
entityMatches,
|
|
126
|
+
queryTerms
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Step 3: Map concepts using Entity Registry and taxonomy
|
|
131
|
+
*/
|
|
132
|
+
async mapConcepts(decomposition) {
|
|
133
|
+
const mappedFields = {};
|
|
134
|
+
const searchTerms = [];
|
|
135
|
+
const connections = {};
|
|
136
|
+
// Use Entity Registry to map known entities
|
|
137
|
+
for (const term of decomposition.queryTerms) {
|
|
138
|
+
const entityMatch = decomposition.entityMatches.find((m) => m.term.toLowerCase() === term.toLowerCase());
|
|
139
|
+
if (entityMatch) {
|
|
140
|
+
if (entityMatch.type === 'field') {
|
|
141
|
+
mappedFields[entityMatch.field] = entityMatch.value;
|
|
142
|
+
}
|
|
143
|
+
else if (entityMatch.type === 'entity') {
|
|
144
|
+
connections[entityMatch.id] = entityMatch;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
searchTerms.push(term);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
searchTerms,
|
|
153
|
+
mappedFields,
|
|
154
|
+
connections
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Step 4: Construct final Triple Intelligence query
|
|
159
|
+
*/
|
|
160
|
+
constructTripleQuery(originalQuery, intent, mapped) {
|
|
161
|
+
const query = {};
|
|
162
|
+
// Set vector search if we have search terms
|
|
163
|
+
if (mapped.searchTerms.length > 0) {
|
|
164
|
+
query.like = mapped.searchTerms.join(' ');
|
|
165
|
+
}
|
|
166
|
+
else if (intent.type === 'vector') {
|
|
167
|
+
query.like = originalQuery;
|
|
168
|
+
}
|
|
169
|
+
// Set field filters if we found field mappings
|
|
170
|
+
if (Object.keys(mapped.mappedFields).length > 0) {
|
|
171
|
+
query.where = mapped.mappedFields;
|
|
172
|
+
}
|
|
173
|
+
// Set connection searches if we found entity connections
|
|
174
|
+
if (Object.keys(mapped.connections).length > 0) {
|
|
175
|
+
const entities = Object.keys(mapped.connections);
|
|
176
|
+
if (entities.length > 0) {
|
|
177
|
+
query.connected = { to: entities };
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Apply extracted modifiers
|
|
181
|
+
if (intent.extractedTerms.modifiers) {
|
|
182
|
+
const mods = intent.extractedTerms.modifiers;
|
|
183
|
+
if (mods.limit)
|
|
184
|
+
query.limit = mods.limit;
|
|
185
|
+
if (mods.boost)
|
|
186
|
+
query.boost = mods.boost;
|
|
187
|
+
}
|
|
188
|
+
return query;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Initialize pattern recognition for common query types
|
|
192
|
+
*/
|
|
193
|
+
initializePatterns() {
|
|
194
|
+
const patterns = new Map();
|
|
195
|
+
// "Find papers about AI from 2023"
|
|
196
|
+
patterns.set(/find\\s+(.+?)\\s+about\\s+(.+?)\\s+from\\s+(\\d{4})/i, (match) => ({
|
|
197
|
+
like: match[2],
|
|
198
|
+
where: { year: parseInt(match[3]) }
|
|
199
|
+
}));
|
|
200
|
+
// "Show me recent posts by John"
|
|
201
|
+
patterns.set(/show\\s+me\\s+recent\\s+(.+?)\\s+by\\s+(.+)/i, (match) => ({
|
|
202
|
+
like: match[1],
|
|
203
|
+
boost: 'recent',
|
|
204
|
+
connected: { from: match[2] }
|
|
205
|
+
}));
|
|
206
|
+
// "Papers with more than 100 citations"
|
|
207
|
+
patterns.set(/(.+?)\\s+with\\s+more\\s+than\\s+(\\d+)\\s+(.+)/i, (match) => ({
|
|
208
|
+
like: match[1],
|
|
209
|
+
where: { [match[3]]: { greaterThan: parseInt(match[2]) } }
|
|
210
|
+
}));
|
|
211
|
+
// "Documents related to Stanford"
|
|
212
|
+
patterns.set(/(.+?)\\s+related\\s+to\\s+(.+)/i, (match) => ({
|
|
213
|
+
like: match[1],
|
|
214
|
+
connected: { to: match[2] }
|
|
215
|
+
}));
|
|
216
|
+
return patterns;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Detect field query patterns
|
|
220
|
+
*/
|
|
221
|
+
hasFieldPatterns(query) {
|
|
222
|
+
const fieldIndicators = [
|
|
223
|
+
'from', 'after', 'before', 'with more than', 'with less than',
|
|
224
|
+
'published', 'created', 'year', 'date', 'citations', 'score'
|
|
225
|
+
];
|
|
226
|
+
return fieldIndicators.some(indicator => query.includes(indicator));
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Detect connection query patterns
|
|
230
|
+
*/
|
|
231
|
+
hasConnectionPatterns(query) {
|
|
232
|
+
const connectionIndicators = [
|
|
233
|
+
'by', 'from', 'connected to', 'related to', 'authored by',
|
|
234
|
+
'created by', 'associated with', 'linked to'
|
|
235
|
+
];
|
|
236
|
+
return connectionIndicators.some(indicator => query.includes(indicator));
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Extract terms and modifiers from query
|
|
240
|
+
*/
|
|
241
|
+
extractTerms(query) {
|
|
242
|
+
const extracted = {};
|
|
243
|
+
// Extract limit numbers
|
|
244
|
+
const limitMatch = query.match(/(?:top|first|limit)\\s+(\\d+)/i);
|
|
245
|
+
if (limitMatch) {
|
|
246
|
+
extracted.modifiers = { limit: parseInt(limitMatch[1]) };
|
|
247
|
+
}
|
|
248
|
+
// Extract boost indicators
|
|
249
|
+
if (query.toLowerCase().includes('recent')) {
|
|
250
|
+
extracted.modifiers = { ...extracted.modifiers, boost: 'recent' };
|
|
251
|
+
}
|
|
252
|
+
if (query.toLowerCase().includes('popular')) {
|
|
253
|
+
extracted.modifiers = { ...extracted.modifiers, boost: 'popular' };
|
|
254
|
+
}
|
|
255
|
+
return extracted;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Find entity matches using Brainy's search capabilities
|
|
259
|
+
*/
|
|
260
|
+
async findEntityMatches(terms) {
|
|
261
|
+
const matches = [];
|
|
262
|
+
for (const term of terms) {
|
|
263
|
+
try {
|
|
264
|
+
// Search for similar entities in the knowledge base
|
|
265
|
+
const results = await this.brain.search(term, { limit: 5 });
|
|
266
|
+
for (const result of results) {
|
|
267
|
+
if (result.score > 0.8) { // High similarity threshold
|
|
268
|
+
matches.push({
|
|
269
|
+
term,
|
|
270
|
+
id: result.id,
|
|
271
|
+
type: 'entity',
|
|
272
|
+
confidence: result.score,
|
|
273
|
+
metadata: result.metadata
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// Check if term matches known field names
|
|
278
|
+
if (this.isKnownField(term)) {
|
|
279
|
+
matches.push({
|
|
280
|
+
term,
|
|
281
|
+
type: 'field',
|
|
282
|
+
field: this.mapToFieldName(term),
|
|
283
|
+
confidence: 0.9
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
// If search fails, continue with other terms
|
|
289
|
+
console.debug(`Failed to search for term: ${term}`, error);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return matches;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Check if term is a known field name
|
|
296
|
+
*/
|
|
297
|
+
isKnownField(term) {
|
|
298
|
+
const knownFields = [
|
|
299
|
+
'year', 'date', 'created', 'published', 'author', 'title',
|
|
300
|
+
'citations', 'views', 'score', 'rating', 'category', 'type'
|
|
301
|
+
];
|
|
302
|
+
return knownFields.includes(term.toLowerCase());
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Map colloquial terms to actual field names
|
|
306
|
+
*/
|
|
307
|
+
mapToFieldName(term) {
|
|
308
|
+
const fieldMappings = {
|
|
309
|
+
'published': 'publishDate',
|
|
310
|
+
'created': 'createdAt',
|
|
311
|
+
'author': 'authorId',
|
|
312
|
+
'citations': 'citationCount'
|
|
313
|
+
};
|
|
314
|
+
return fieldMappings[term.toLowerCase()] || term.toLowerCase();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=naturalLanguageProcessor.js.map
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🧠 Natural Language Query Processor - STATIC VERSION
|
|
3
|
+
* No runtime initialization, no memory leaks, patterns pre-built at compile time
|
|
4
|
+
*
|
|
5
|
+
* Uses static pattern matching with 220 pre-built patterns
|
|
6
|
+
*/
|
|
7
|
+
import { Vector } from '../coreTypes.js';
|
|
8
|
+
import { TripleQuery } from '../triple/TripleIntelligence.js';
|
|
9
|
+
export interface NaturalQueryIntent {
|
|
10
|
+
type: 'vector' | 'field' | 'graph' | 'combined';
|
|
11
|
+
confidence: number;
|
|
12
|
+
extractedTerms: {
|
|
13
|
+
entities?: string[];
|
|
14
|
+
fields?: string[];
|
|
15
|
+
relationships?: string[];
|
|
16
|
+
modifiers?: string[];
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export declare class NaturalLanguageProcessor {
|
|
20
|
+
private queryHistory;
|
|
21
|
+
constructor();
|
|
22
|
+
/**
|
|
23
|
+
* No initialization needed - patterns are pre-built!
|
|
24
|
+
*/
|
|
25
|
+
init(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Process natural language query into structured Triple Intelligence query
|
|
28
|
+
* @param naturalQuery The natural language query string
|
|
29
|
+
* @param queryEmbedding Pre-computed embedding from BrainyData (passed in to avoid circular dependency)
|
|
30
|
+
*/
|
|
31
|
+
processNaturalQuery(naturalQuery: string, queryEmbedding?: Vector): Promise<TripleQuery>;
|
|
32
|
+
/**
|
|
33
|
+
* Analyze query intent using keywords
|
|
34
|
+
*/
|
|
35
|
+
private analyzeIntent;
|
|
36
|
+
/**
|
|
37
|
+
* Extract field terms from query
|
|
38
|
+
*/
|
|
39
|
+
private extractFieldTerms;
|
|
40
|
+
/**
|
|
41
|
+
* Extract relationship terms
|
|
42
|
+
*/
|
|
43
|
+
private extractRelationshipTerms;
|
|
44
|
+
/**
|
|
45
|
+
* Build field constraints from extracted terms
|
|
46
|
+
*/
|
|
47
|
+
private buildFieldConstraints;
|
|
48
|
+
/**
|
|
49
|
+
* Find similar queries from history (without using BrainyData)
|
|
50
|
+
*/
|
|
51
|
+
private findSimilarQueries;
|
|
52
|
+
/**
|
|
53
|
+
* Adapt a previous query for new input
|
|
54
|
+
*/
|
|
55
|
+
private adaptQuery;
|
|
56
|
+
/**
|
|
57
|
+
* Extract entities from query
|
|
58
|
+
*/
|
|
59
|
+
private extractEntities;
|
|
60
|
+
/**
|
|
61
|
+
* Build query from components
|
|
62
|
+
*/
|
|
63
|
+
private buildQuery;
|
|
64
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 🧠 Natural Language Query Processor - STATIC VERSION
|
|
3
|
+
* No runtime initialization, no memory leaks, patterns pre-built at compile time
|
|
4
|
+
*
|
|
5
|
+
* Uses static pattern matching with 220 pre-built patterns
|
|
6
|
+
*/
|
|
7
|
+
import { patternMatchQuery } from './staticPatternMatcher.js';
|
|
8
|
+
export class NaturalLanguageProcessor {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.queryHistory = [];
|
|
11
|
+
// Patterns are static - no initialization needed!
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* No initialization needed - patterns are pre-built!
|
|
15
|
+
*/
|
|
16
|
+
async init() {
|
|
17
|
+
// Nothing to do - patterns are compiled into the code
|
|
18
|
+
return Promise.resolve();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Process natural language query into structured Triple Intelligence query
|
|
22
|
+
* @param naturalQuery The natural language query string
|
|
23
|
+
* @param queryEmbedding Pre-computed embedding from BrainyData (passed in to avoid circular dependency)
|
|
24
|
+
*/
|
|
25
|
+
async processNaturalQuery(naturalQuery, queryEmbedding) {
|
|
26
|
+
// Use static pattern matcher (no async, no memory allocation!)
|
|
27
|
+
const structuredQuery = patternMatchQuery(naturalQuery, queryEmbedding);
|
|
28
|
+
// Step 3: Enhance with intent analysis if needed
|
|
29
|
+
if (!structuredQuery.where && !structuredQuery.connected) {
|
|
30
|
+
const intent = await this.analyzeIntent(naturalQuery);
|
|
31
|
+
// Add metadata based on intent
|
|
32
|
+
if (intent.type === 'field' && intent.extractedTerms.fields) {
|
|
33
|
+
structuredQuery.where = this.buildFieldConstraints(intent.extractedTerms.fields);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Track for learning (but don't create new BrainyData!)
|
|
37
|
+
this.queryHistory.push({
|
|
38
|
+
query: naturalQuery,
|
|
39
|
+
result: structuredQuery,
|
|
40
|
+
success: false // Will be updated based on user interaction
|
|
41
|
+
});
|
|
42
|
+
// Keep history limited to prevent memory growth
|
|
43
|
+
if (this.queryHistory.length > 100) {
|
|
44
|
+
this.queryHistory.shift();
|
|
45
|
+
}
|
|
46
|
+
return structuredQuery;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Analyze query intent using keywords
|
|
50
|
+
*/
|
|
51
|
+
async analyzeIntent(query) {
|
|
52
|
+
const lowerQuery = query.toLowerCase();
|
|
53
|
+
// Check for field-specific keywords
|
|
54
|
+
const fieldKeywords = ['where', 'filter', 'with', 'has', 'contains', 'equals', 'greater', 'less', 'between'];
|
|
55
|
+
const hasFieldIntent = fieldKeywords.some(kw => lowerQuery.includes(kw));
|
|
56
|
+
// Check for graph keywords
|
|
57
|
+
const graphKeywords = ['related', 'connected', 'linked', 'associated', 'references'];
|
|
58
|
+
const hasGraphIntent = graphKeywords.some(kw => lowerQuery.includes(kw));
|
|
59
|
+
// Determine type
|
|
60
|
+
let type = 'vector';
|
|
61
|
+
if (hasFieldIntent && hasGraphIntent) {
|
|
62
|
+
type = 'combined';
|
|
63
|
+
}
|
|
64
|
+
else if (hasFieldIntent) {
|
|
65
|
+
type = 'field';
|
|
66
|
+
}
|
|
67
|
+
else if (hasGraphIntent) {
|
|
68
|
+
type = 'graph';
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
type,
|
|
72
|
+
confidence: 0.8,
|
|
73
|
+
extractedTerms: {
|
|
74
|
+
fields: hasFieldIntent ? this.extractFieldTerms(query) : undefined,
|
|
75
|
+
relationships: hasGraphIntent ? this.extractRelationshipTerms(query) : undefined
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Extract field terms from query
|
|
81
|
+
*/
|
|
82
|
+
extractFieldTerms(query) {
|
|
83
|
+
const terms = [];
|
|
84
|
+
// Simple extraction of potential field names
|
|
85
|
+
const words = query.split(/\s+/);
|
|
86
|
+
const fieldIndicators = ['year', 'date', 'author', 'type', 'category', 'status', 'price'];
|
|
87
|
+
for (const word of words) {
|
|
88
|
+
if (fieldIndicators.includes(word.toLowerCase())) {
|
|
89
|
+
terms.push(word.toLowerCase());
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return terms;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Extract relationship terms
|
|
96
|
+
*/
|
|
97
|
+
extractRelationshipTerms(query) {
|
|
98
|
+
const terms = [];
|
|
99
|
+
const relationshipWords = ['related', 'connected', 'linked', 'references', 'cites'];
|
|
100
|
+
const words = query.toLowerCase().split(/\s+/);
|
|
101
|
+
for (const word of words) {
|
|
102
|
+
if (relationshipWords.includes(word)) {
|
|
103
|
+
terms.push(word);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return terms;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Build field constraints from extracted terms
|
|
110
|
+
*/
|
|
111
|
+
buildFieldConstraints(fields) {
|
|
112
|
+
const constraints = {};
|
|
113
|
+
// Simple mapping for common fields
|
|
114
|
+
for (const field of fields) {
|
|
115
|
+
// This would be enhanced with actual value extraction
|
|
116
|
+
constraints[field] = { exists: true };
|
|
117
|
+
}
|
|
118
|
+
return constraints;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Find similar queries from history (without using BrainyData)
|
|
122
|
+
*/
|
|
123
|
+
findSimilarQueries(embedding) {
|
|
124
|
+
// Simple similarity check against recent history
|
|
125
|
+
// This is just a placeholder - real implementation would use cosine similarity
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Adapt a previous query for new input
|
|
130
|
+
*/
|
|
131
|
+
adaptQuery(newQuery, previousResult) {
|
|
132
|
+
return previousResult;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Extract entities from query
|
|
136
|
+
*/
|
|
137
|
+
async extractEntities(query) {
|
|
138
|
+
// Could use the Entity Registry here if available
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Build query from components
|
|
143
|
+
*/
|
|
144
|
+
buildQuery(query, intent, entities) {
|
|
145
|
+
return {
|
|
146
|
+
like: query,
|
|
147
|
+
limit: 10
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=naturalLanguageProcessorStatic.js.map
|