regen-koi-mcp 1.2.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +165 -64
- package/dist/auth-store.d.ts +47 -0
- package/dist/auth-store.d.ts.map +1 -0
- package/dist/auth-store.js +86 -0
- package/dist/auth-store.js.map +1 -0
- package/dist/auth.d.ts +33 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +85 -0
- package/dist/auth.js.map +1 -0
- package/dist/graph_tool.d.ts.map +1 -1
- package/dist/graph_tool.js +16 -20
- package/dist/graph_tool.js.map +1 -1
- package/dist/index.js +434 -278
- package/dist/index.js.map +1 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +93 -27
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
- package/dist/hybrid-client.d.ts +0 -61
- package/dist/hybrid-client.d.ts.map +0 -1
- package/dist/hybrid-client.js +0 -303
- package/dist/hybrid-client.js.map +0 -1
- package/dist/query_router.d.ts +0 -81
- package/dist/query_router.d.ts.map +0 -1
- package/dist/query_router.js +0 -205
- package/dist/query_router.js.map +0 -1
- package/dist/unified_search.d.ts +0 -109
- package/dist/unified_search.d.ts.map +0 -1
- package/dist/unified_search.js +0 -352
- package/dist/unified_search.js.map +0 -1
package/dist/hybrid-client.js
DELETED
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* True Hybrid Search Client
|
|
3
|
-
* Combines SPARQL knowledge graph queries with vector similarity search
|
|
4
|
-
*/
|
|
5
|
-
import axios from 'axios';
|
|
6
|
-
import dotenv from 'dotenv';
|
|
7
|
-
dotenv.config();
|
|
8
|
-
const JENA_ENDPOINT = process.env.JENA_ENDPOINT || 'http://localhost:3030/koi/sparql';
|
|
9
|
-
// Prefer KOI API if available; fallback to legacy 8910
|
|
10
|
-
const VECTOR_API_URL = process.env.API_URL ||
|
|
11
|
-
process.env.KOI_API_ENDPOINT ||
|
|
12
|
-
'https://regen.gaiaai.xyz/api/koi';
|
|
13
|
-
const OPENAI_API_KEY = process.env.OPENAI_API_KEY;
|
|
14
|
-
export class HybridSearchClient {
|
|
15
|
-
/**
|
|
16
|
-
* Execute SPARQL query
|
|
17
|
-
*/
|
|
18
|
-
async querySPARQL(query, filters) {
|
|
19
|
-
try {
|
|
20
|
-
// Build SPARQL query based on natural language
|
|
21
|
-
const sparql = await this.buildSPARQLQuery(query, { dateRange: filters?.date_range, includeUndated: !!filters?.include_undated });
|
|
22
|
-
const response = await axios.post(JENA_ENDPOINT, `query=${encodeURIComponent(sparql)}`, {
|
|
23
|
-
headers: {
|
|
24
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
25
|
-
'Accept': 'application/sparql-results+json'
|
|
26
|
-
},
|
|
27
|
-
auth: {
|
|
28
|
-
username: 'admin',
|
|
29
|
-
password: 'admin'
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
const data = response.data;
|
|
33
|
-
const bindings = data?.results?.bindings || [];
|
|
34
|
-
return bindings.map((b) => ({
|
|
35
|
-
subject: b.subject?.value || '',
|
|
36
|
-
predicate: b.predicate?.value || '',
|
|
37
|
-
object: b.object?.value || '',
|
|
38
|
-
score: 1.0 // SPARQL results get high confidence
|
|
39
|
-
}));
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
console.error('SPARQL query failed:', error);
|
|
43
|
-
return [];
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Execute vector similarity search
|
|
48
|
-
*/
|
|
49
|
-
async queryVector(query, limit = 10, filters) {
|
|
50
|
-
try {
|
|
51
|
-
const body = { question: query, limit, include_metadata: true };
|
|
52
|
-
if (filters && Object.keys(filters).length > 0)
|
|
53
|
-
body.filters = filters;
|
|
54
|
-
const response = await axios.post(`${VECTOR_API_URL}/query`, body);
|
|
55
|
-
const data = response.data;
|
|
56
|
-
const results = data?.results || [];
|
|
57
|
-
return results.map((r) => ({
|
|
58
|
-
content: r.content || r.text || '',
|
|
59
|
-
metadata: r.metadata || {},
|
|
60
|
-
score: r.score || 0,
|
|
61
|
-
rid: r.rid
|
|
62
|
-
}));
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
console.error('Vector search failed:', error);
|
|
66
|
-
return [];
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* True hybrid search - parallel execution
|
|
71
|
-
*/
|
|
72
|
-
async hybridSearch(query, options = {}) {
|
|
73
|
-
const { sparqlLimit = 20, vectorLimit = 10, fusionStrategy = 'rrf', filters } = options;
|
|
74
|
-
console.log(`🔍 Hybrid search for: "${query}"`);
|
|
75
|
-
// Execute both queries in parallel
|
|
76
|
-
const [sparqlResults, vectorResults] = await Promise.all([
|
|
77
|
-
this.querySPARQL(query, filters),
|
|
78
|
-
this.queryVector(query, vectorLimit, filters)
|
|
79
|
-
]);
|
|
80
|
-
console.log(` SPARQL: ${sparqlResults.length} results`);
|
|
81
|
-
console.log(` Vector: ${vectorResults.length} results`);
|
|
82
|
-
// Fuse results based on strategy
|
|
83
|
-
let fusedResults;
|
|
84
|
-
switch (fusionStrategy) {
|
|
85
|
-
case 'rrf':
|
|
86
|
-
fusedResults = this.reciprocalRankFusion(sparqlResults, vectorResults);
|
|
87
|
-
break;
|
|
88
|
-
case 'weighted':
|
|
89
|
-
fusedResults = this.weightedFusion(sparqlResults, vectorResults, 0.6, 0.4);
|
|
90
|
-
break;
|
|
91
|
-
case 'interleave':
|
|
92
|
-
fusedResults = this.interleaveFusion(sparqlResults, vectorResults);
|
|
93
|
-
break;
|
|
94
|
-
default:
|
|
95
|
-
fusedResults = this.reciprocalRankFusion(sparqlResults, vectorResults);
|
|
96
|
-
}
|
|
97
|
-
return fusedResults.slice(0, Math.max(sparqlLimit, vectorLimit));
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Reciprocal Rank Fusion (RRF)
|
|
101
|
-
*/
|
|
102
|
-
reciprocalRankFusion(sparqlResults, vectorResults) {
|
|
103
|
-
const k = 60; // RRF constant
|
|
104
|
-
const scoreMap = new Map();
|
|
105
|
-
// Process SPARQL results
|
|
106
|
-
sparqlResults.forEach((result, rank) => {
|
|
107
|
-
const key = `${result.subject}-${result.predicate}-${result.object}`;
|
|
108
|
-
const rrfScore = 1 / (k + rank + 1);
|
|
109
|
-
scoreMap.set(key, {
|
|
110
|
-
type: 'sparql',
|
|
111
|
-
content: `${result.subject} ${result.predicate} ${result.object}`,
|
|
112
|
-
metadata: { source: 'sparql' },
|
|
113
|
-
score: rrfScore,
|
|
114
|
-
sparqlTriple: result
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
// Process vector results
|
|
118
|
-
vectorResults.forEach((result, rank) => {
|
|
119
|
-
const key = result.rid || result.content.substring(0, 100);
|
|
120
|
-
const rrfScore = 1 / (k + rank + 1);
|
|
121
|
-
const existing = scoreMap.get(key);
|
|
122
|
-
if (existing) {
|
|
123
|
-
// Combine scores if found in both
|
|
124
|
-
existing.score += rrfScore;
|
|
125
|
-
existing.type = 'both';
|
|
126
|
-
existing.vectorMatch = result;
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
scoreMap.set(key, {
|
|
130
|
-
type: 'vector',
|
|
131
|
-
content: result.content,
|
|
132
|
-
metadata: { ...result.metadata, source: 'vector' },
|
|
133
|
-
score: rrfScore,
|
|
134
|
-
vectorMatch: result
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
// Sort by combined score
|
|
139
|
-
return Array.from(scoreMap.values())
|
|
140
|
-
.sort((a, b) => b.score - a.score);
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Weighted score fusion
|
|
144
|
-
*/
|
|
145
|
-
weightedFusion(sparqlResults, vectorResults, sparqlWeight, vectorWeight) {
|
|
146
|
-
const results = [];
|
|
147
|
-
// Add SPARQL results with weight
|
|
148
|
-
sparqlResults.forEach(result => {
|
|
149
|
-
results.push({
|
|
150
|
-
type: 'sparql',
|
|
151
|
-
content: `${result.subject} ${result.predicate} ${result.object}`,
|
|
152
|
-
metadata: { source: 'sparql' },
|
|
153
|
-
score: (result.score || 1.0) * sparqlWeight,
|
|
154
|
-
sparqlTriple: result
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
// Add vector results with weight
|
|
158
|
-
vectorResults.forEach(result => {
|
|
159
|
-
results.push({
|
|
160
|
-
type: 'vector',
|
|
161
|
-
content: result.content,
|
|
162
|
-
metadata: { ...result.metadata, source: 'vector' },
|
|
163
|
-
score: result.score * vectorWeight,
|
|
164
|
-
vectorMatch: result
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
return results.sort((a, b) => b.score - a.score);
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Interleave results from both sources
|
|
171
|
-
*/
|
|
172
|
-
interleaveFusion(sparqlResults, vectorResults) {
|
|
173
|
-
const results = [];
|
|
174
|
-
const maxLen = Math.max(sparqlResults.length, vectorResults.length);
|
|
175
|
-
for (let i = 0; i < maxLen; i++) {
|
|
176
|
-
if (i < sparqlResults.length) {
|
|
177
|
-
const result = sparqlResults[i];
|
|
178
|
-
results.push({
|
|
179
|
-
type: 'sparql',
|
|
180
|
-
content: `${result.subject} ${result.predicate} ${result.object}`,
|
|
181
|
-
metadata: { source: 'sparql' },
|
|
182
|
-
score: 1.0 - (i / sparqlResults.length) * 0.5,
|
|
183
|
-
sparqlTriple: result
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
if (i < vectorResults.length) {
|
|
187
|
-
const result = vectorResults[i];
|
|
188
|
-
results.push({
|
|
189
|
-
type: 'vector',
|
|
190
|
-
content: result.content,
|
|
191
|
-
metadata: { ...result.metadata, source: 'vector' },
|
|
192
|
-
score: result.score,
|
|
193
|
-
vectorMatch: result
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
return results;
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Build SPARQL query from natural language
|
|
201
|
-
*/
|
|
202
|
-
async buildSPARQLQuery(nlQuery, options) {
|
|
203
|
-
// Use the refined graph structure
|
|
204
|
-
const queryLower = nlQuery.toLowerCase();
|
|
205
|
-
// Simple pattern matching for now
|
|
206
|
-
if (queryLower.includes('count') || queryLower.includes('how many')) {
|
|
207
|
-
return `
|
|
208
|
-
PREFIX regx: <https://regen.network/ontology/experimental#>
|
|
209
|
-
SELECT (COUNT(DISTINCT ?subject) as ?count)
|
|
210
|
-
WHERE {
|
|
211
|
-
?stmt a regx:Statement .
|
|
212
|
-
?stmt regx:subject ?subject .
|
|
213
|
-
?stmt regx:predicate ?predicate .
|
|
214
|
-
?stmt regx:object ?object .
|
|
215
|
-
}
|
|
216
|
-
`;
|
|
217
|
-
}
|
|
218
|
-
// Default: return triples matching keywords
|
|
219
|
-
const keywords = nlQuery.split(/\s+/)
|
|
220
|
-
.filter(w => w.length > 3)
|
|
221
|
-
.map(w => w.toLowerCase());
|
|
222
|
-
const dateFilter = options?.dateRange;
|
|
223
|
-
const includeUndated = !!options?.includeUndated;
|
|
224
|
-
const dateClause = dateFilter ? `
|
|
225
|
-
OPTIONAL { ?stmt regx:publishedAt ?publishedAt . }
|
|
226
|
-
FILTER(BOUND(?publishedAt) ${includeUndated ? '|| !BOUND(?publishedAt)' : ''}
|
|
227
|
-
${dateFilter.start ? `&& ?publishedAt >= \"${dateFilter.start}T00:00:00Z\"^^xsd:dateTime` : ''}
|
|
228
|
-
${dateFilter.end ? `&& ?publishedAt <= \"${dateFilter.end}T23:59:59Z\"^^xsd:dateTime` : ''}
|
|
229
|
-
)
|
|
230
|
-
` : '';
|
|
231
|
-
return `
|
|
232
|
-
PREFIX regx: <https://regen.network/ontology/experimental#>
|
|
233
|
-
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
|
|
234
|
-
SELECT ?subject ?predicate ?object
|
|
235
|
-
WHERE {
|
|
236
|
-
?stmt a regx:Statement .
|
|
237
|
-
?stmt regx:subject ?subject .
|
|
238
|
-
?stmt regx:predicate ?predicate .
|
|
239
|
-
?stmt regx:object ?object .
|
|
240
|
-
${dateClause}
|
|
241
|
-
FILTER(
|
|
242
|
-
${keywords.map(kw => `
|
|
243
|
-
regex(str(?subject), \"${kw}\", \"i\") ||
|
|
244
|
-
regex(str(?predicate), \"${kw}\", \"i\") ||
|
|
245
|
-
regex(str(?object), \"${kw}\", \"i\")
|
|
246
|
-
`).join(' || ')}
|
|
247
|
-
)
|
|
248
|
-
}
|
|
249
|
-
LIMIT 20
|
|
250
|
-
`;
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Format results for display
|
|
254
|
-
*/
|
|
255
|
-
formatResults(results) {
|
|
256
|
-
let output = '# Hybrid Search Results\n\n';
|
|
257
|
-
const grouped = {
|
|
258
|
-
both: results.filter(r => r.type === 'both'),
|
|
259
|
-
sparql: results.filter(r => r.type === 'sparql'),
|
|
260
|
-
vector: results.filter(r => r.type === 'vector')
|
|
261
|
-
};
|
|
262
|
-
// When nothing is returned from either branch, make it explicit
|
|
263
|
-
if (grouped.both.length === 0 &&
|
|
264
|
-
grouped.sparql.length === 0 &&
|
|
265
|
-
grouped.vector.length === 0) {
|
|
266
|
-
output += 'No results found. The KOI API or graph may be unreachable, or the knowledge base did not match this query.\n';
|
|
267
|
-
return output;
|
|
268
|
-
}
|
|
269
|
-
if (grouped.both.length > 0) {
|
|
270
|
-
output += '## 🔗 Found in Both Sources\n';
|
|
271
|
-
grouped.both.forEach((r, i) => {
|
|
272
|
-
output += `${i + 1}. **Score: ${r.score.toFixed(3)}**\n`;
|
|
273
|
-
output += ` ${r.content.substring(0, 200)}...\n\n`;
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
if (grouped.sparql.length > 0) {
|
|
277
|
-
output += '## 📊 Knowledge Graph Results\n';
|
|
278
|
-
grouped.sparql.slice(0, 5).forEach((r, i) => {
|
|
279
|
-
if (r.sparqlTriple) {
|
|
280
|
-
output += `${i + 1}. ${r.sparqlTriple.subject} → ${r.sparqlTriple.predicate} → ${r.sparqlTriple.object}\n`;
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
output += '\n';
|
|
284
|
-
}
|
|
285
|
-
if (grouped.vector.length > 0) {
|
|
286
|
-
output += '## 🔍 Vector Search Results\n';
|
|
287
|
-
grouped.vector.slice(0, 5).forEach((r, i) => {
|
|
288
|
-
output += `${i + 1}. ${r.content.substring(0, 150)}...\n`;
|
|
289
|
-
if (r.vectorMatch?.rid) {
|
|
290
|
-
output += ` RID: ${r.vectorMatch.rid}\n`;
|
|
291
|
-
}
|
|
292
|
-
const pub = r.vectorMatch?.metadata?.published_at;
|
|
293
|
-
if (pub) {
|
|
294
|
-
output += ` Published: ${pub}\n`;
|
|
295
|
-
}
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
return output;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
// Export for use in main index.ts
|
|
302
|
-
export default HybridSearchClient;
|
|
303
|
-
//# sourceMappingURL=hybrid-client.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hybrid-client.js","sourceRoot":"","sources":["../src/hybrid-client.ts"],"names":[],"mappings":"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"}
|
package/dist/query_router.d.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Query Router - Intelligent query classification using pg_trgm
|
|
3
|
-
*
|
|
4
|
-
* Routes queries to the appropriate search strategy:
|
|
5
|
-
* - Graph: Entity relationship queries (e.g., "What does Keeper handle?")
|
|
6
|
-
* - Vector: Conceptual/semantic queries (e.g., "How does consensus work?")
|
|
7
|
-
* - Unified: Hybrid queries combining entities and concepts
|
|
8
|
-
*
|
|
9
|
-
* Key Design Principles:
|
|
10
|
-
* 1. Entity detection via pg_trgm (NO JavaScript array scanning)
|
|
11
|
-
* 2. Database does the work - trigram similarity matching in SQL
|
|
12
|
-
* 3. Classification based on entities + keyword patterns
|
|
13
|
-
*/
|
|
14
|
-
export interface RouterConfig {
|
|
15
|
-
host: string;
|
|
16
|
-
port: number;
|
|
17
|
-
database: string;
|
|
18
|
-
user?: string;
|
|
19
|
-
password?: string;
|
|
20
|
-
entitySimilarityThreshold?: number;
|
|
21
|
-
}
|
|
22
|
-
export interface DetectedEntity {
|
|
23
|
-
name: string;
|
|
24
|
-
entity_type: 'Keeper' | 'Msg';
|
|
25
|
-
node_id: string;
|
|
26
|
-
score: number;
|
|
27
|
-
}
|
|
28
|
-
export interface QueryClassification {
|
|
29
|
-
intent: 'entity_lookup' | 'relationship' | 'conceptual' | 'hybrid';
|
|
30
|
-
detected_entities: DetectedEntity[];
|
|
31
|
-
recommended_route: 'graph' | 'vector' | 'unified';
|
|
32
|
-
confidence: number;
|
|
33
|
-
reasoning: string;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* QueryRouter - Classifies natural language queries for intelligent routing
|
|
37
|
-
*/
|
|
38
|
-
export declare class QueryRouter {
|
|
39
|
-
private pool;
|
|
40
|
-
private similarityThreshold;
|
|
41
|
-
constructor(config: RouterConfig);
|
|
42
|
-
/**
|
|
43
|
-
* Close the database connection pool
|
|
44
|
-
*/
|
|
45
|
-
close(): Promise<void>;
|
|
46
|
-
/**
|
|
47
|
-
* Detect entities in a query using pg_trgm trigram similarity
|
|
48
|
-
* This replaces JavaScript array scanning with efficient database queries
|
|
49
|
-
*/
|
|
50
|
-
detectEntities(queryText: string): Promise<DetectedEntity[]>;
|
|
51
|
-
/**
|
|
52
|
-
* Classify a query to determine routing strategy
|
|
53
|
-
*/
|
|
54
|
-
classifyQuery(queryText: string): Promise<QueryClassification>;
|
|
55
|
-
/**
|
|
56
|
-
* Analyze query patterns for relationship and conceptual indicators
|
|
57
|
-
* Uses regex patterns - lightweight and fast for keyword detection
|
|
58
|
-
*/
|
|
59
|
-
private analyzePatterns;
|
|
60
|
-
/**
|
|
61
|
-
* Calculate confidence score combining entity detection and pattern matching
|
|
62
|
-
*/
|
|
63
|
-
private calculateConfidence;
|
|
64
|
-
/**
|
|
65
|
-
* Get statistics about the entity lookup table
|
|
66
|
-
*/
|
|
67
|
-
getStats(): Promise<{
|
|
68
|
-
total: number;
|
|
69
|
-
by_type: Record<string, number>;
|
|
70
|
-
}>;
|
|
71
|
-
/**
|
|
72
|
-
* Test the similarity matching for a specific entity name
|
|
73
|
-
* Useful for debugging and tuning the similarity threshold
|
|
74
|
-
*/
|
|
75
|
-
testSimilarity(entityName: string, queryText: string): Promise<number>;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Create a default QueryRouter instance using environment variables
|
|
79
|
-
*/
|
|
80
|
-
export declare function createQueryRouter(): QueryRouter;
|
|
81
|
-
//# sourceMappingURL=query_router.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"query_router.d.ts","sourceRoot":"","sources":["../src/query_router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAGD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAGD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,eAAe,GAAG,cAAc,GAAG,YAAY,GAAG,QAAQ,CAAC;IACnE,iBAAiB,EAAE,cAAc,EAAE,CAAC;IACpC,iBAAiB,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IAClD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAAW;IACvB,OAAO,CAAC,mBAAmB,CAAS;gBAExB,MAAM,EAAE,YAAY;IAWhC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;;OAGG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAkBlE;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAiDpE;;;OAGG;IACH,OAAO,CAAC,eAAe;IAgDvB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAK3B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;IAsB7E;;;OAGG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAQ7E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,CAS/C"}
|
package/dist/query_router.js
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Query Router - Intelligent query classification using pg_trgm
|
|
3
|
-
*
|
|
4
|
-
* Routes queries to the appropriate search strategy:
|
|
5
|
-
* - Graph: Entity relationship queries (e.g., "What does Keeper handle?")
|
|
6
|
-
* - Vector: Conceptual/semantic queries (e.g., "How does consensus work?")
|
|
7
|
-
* - Unified: Hybrid queries combining entities and concepts
|
|
8
|
-
*
|
|
9
|
-
* Key Design Principles:
|
|
10
|
-
* 1. Entity detection via pg_trgm (NO JavaScript array scanning)
|
|
11
|
-
* 2. Database does the work - trigram similarity matching in SQL
|
|
12
|
-
* 3. Classification based on entities + keyword patterns
|
|
13
|
-
*/
|
|
14
|
-
import pkg from 'pg';
|
|
15
|
-
const { Pool } = pkg;
|
|
16
|
-
/**
|
|
17
|
-
* QueryRouter - Classifies natural language queries for intelligent routing
|
|
18
|
-
*/
|
|
19
|
-
export class QueryRouter {
|
|
20
|
-
pool;
|
|
21
|
-
similarityThreshold;
|
|
22
|
-
constructor(config) {
|
|
23
|
-
this.pool = new Pool({
|
|
24
|
-
host: config.host,
|
|
25
|
-
port: config.port,
|
|
26
|
-
database: config.database,
|
|
27
|
-
user: config.user,
|
|
28
|
-
password: config.password,
|
|
29
|
-
});
|
|
30
|
-
this.similarityThreshold = config.entitySimilarityThreshold || 0.15;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Close the database connection pool
|
|
34
|
-
*/
|
|
35
|
-
async close() {
|
|
36
|
-
await this.pool.end();
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Detect entities in a query using pg_trgm trigram similarity
|
|
40
|
-
* This replaces JavaScript array scanning with efficient database queries
|
|
41
|
-
*/
|
|
42
|
-
async detectEntities(queryText) {
|
|
43
|
-
const query = `
|
|
44
|
-
SELECT
|
|
45
|
-
name,
|
|
46
|
-
entity_type,
|
|
47
|
-
node_id,
|
|
48
|
-
similarity(name, $1) as score
|
|
49
|
-
FROM entity_lookup
|
|
50
|
-
WHERE name % $1
|
|
51
|
-
OR $1 ILIKE '%' || name || '%'
|
|
52
|
-
ORDER BY score DESC
|
|
53
|
-
LIMIT 10
|
|
54
|
-
`;
|
|
55
|
-
const result = await this.pool.query(query, [queryText]);
|
|
56
|
-
return result.rows.filter(row => row.score >= this.similarityThreshold);
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Classify a query to determine routing strategy
|
|
60
|
-
*/
|
|
61
|
-
async classifyQuery(queryText) {
|
|
62
|
-
// Step 1: Detect entities using pg_trgm (database does the work!)
|
|
63
|
-
const entities = await this.detectEntities(queryText);
|
|
64
|
-
const hasEntities = entities.length > 0;
|
|
65
|
-
const entityScore = hasEntities ? entities[0].score : 0;
|
|
66
|
-
// Step 2: Pattern detection for query intent
|
|
67
|
-
const patterns = this.analyzePatterns(queryText);
|
|
68
|
-
// Step 3: Classification logic
|
|
69
|
-
if (hasEntities && patterns.isRelationship) {
|
|
70
|
-
// Entity + relationship words → Graph search
|
|
71
|
-
return {
|
|
72
|
-
intent: 'relationship',
|
|
73
|
-
detected_entities: entities,
|
|
74
|
-
recommended_route: 'graph',
|
|
75
|
-
confidence: this.calculateConfidence(entityScore, patterns.relationshipScore),
|
|
76
|
-
reasoning: `Query mentions entities (${entities.map(e => e.name).join(', ')}) with relationship keywords. Best served by graph traversal.`
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
else if (hasEntities && patterns.isConceptual) {
|
|
80
|
-
// Entity + conceptual words → Hybrid search
|
|
81
|
-
return {
|
|
82
|
-
intent: 'hybrid',
|
|
83
|
-
detected_entities: entities,
|
|
84
|
-
recommended_route: 'unified',
|
|
85
|
-
confidence: this.calculateConfidence(entityScore, patterns.conceptualScore),
|
|
86
|
-
reasoning: `Query combines entities (${entities.map(e => e.name).join(', ')}) with conceptual questions. Hybrid search recommended.`
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
else if (hasEntities) {
|
|
90
|
-
// Entities only → Entity lookup via graph
|
|
91
|
-
return {
|
|
92
|
-
intent: 'entity_lookup',
|
|
93
|
-
detected_entities: entities,
|
|
94
|
-
recommended_route: 'graph',
|
|
95
|
-
confidence: entityScore,
|
|
96
|
-
reasoning: `Query focuses on specific entities (${entities.map(e => e.name).join(', ')}). Direct graph lookup.`
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
// No entities → Semantic/vector search
|
|
101
|
-
return {
|
|
102
|
-
intent: 'conceptual',
|
|
103
|
-
detected_entities: [],
|
|
104
|
-
recommended_route: 'vector',
|
|
105
|
-
confidence: patterns.conceptualScore,
|
|
106
|
-
reasoning: 'No specific entities detected. Conceptual query best served by semantic search.'
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Analyze query patterns for relationship and conceptual indicators
|
|
112
|
-
* Uses regex patterns - lightweight and fast for keyword detection
|
|
113
|
-
*/
|
|
114
|
-
analyzePatterns(queryText) {
|
|
115
|
-
const text = queryText.toLowerCase();
|
|
116
|
-
// Relationship patterns
|
|
117
|
-
const relationshipPatterns = [
|
|
118
|
-
/\bhandles?\b/,
|
|
119
|
-
/\bemits?\b/,
|
|
120
|
-
/\bmentions?\b/,
|
|
121
|
-
/\bkeeper\s+for\b/,
|
|
122
|
-
/\bwhat\s+(does|do|is)\s+\w+\s+handle/,
|
|
123
|
-
/\bwhich\s+keeper/,
|
|
124
|
-
/\bmessages?\s+(for|handled\s+by)/,
|
|
125
|
-
/\brelationship\s+between/,
|
|
126
|
-
/\bconnected\s+to/,
|
|
127
|
-
/\bdepend(s|ency|encies)\s+on/,
|
|
128
|
-
];
|
|
129
|
-
// Conceptual patterns
|
|
130
|
-
const conceptualPatterns = [
|
|
131
|
-
/\bhow\s+(does|do|to)\b/,
|
|
132
|
-
/\bwhy\s+(does|do|is)\b/,
|
|
133
|
-
/\bexplain\b/,
|
|
134
|
-
/\bguide\s+(to|for)\b/,
|
|
135
|
-
/\boverview\s+of\b/,
|
|
136
|
-
/\bgetting\s+started\b/,
|
|
137
|
-
/\bwhat\s+is\s+the\s+(purpose|concept|idea)/,
|
|
138
|
-
/\bunderstand(ing)?\b/,
|
|
139
|
-
/\blearn(ing)?\s+about/,
|
|
140
|
-
/\bintroduction\s+to/,
|
|
141
|
-
/\bbest\s+practice/,
|
|
142
|
-
];
|
|
143
|
-
const relationshipMatches = relationshipPatterns.filter(p => p.test(text)).length;
|
|
144
|
-
const conceptualMatches = conceptualPatterns.filter(p => p.test(text)).length;
|
|
145
|
-
return {
|
|
146
|
-
isRelationship: relationshipMatches > 0,
|
|
147
|
-
isConceptual: conceptualMatches > 0,
|
|
148
|
-
relationshipScore: Math.min(relationshipMatches / 3, 1.0),
|
|
149
|
-
conceptualScore: Math.min(conceptualMatches / 3, 1.0),
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Calculate confidence score combining entity detection and pattern matching
|
|
154
|
-
*/
|
|
155
|
-
calculateConfidence(entityScore, patternScore) {
|
|
156
|
-
// Weighted average: entity detection 60%, pattern matching 40%
|
|
157
|
-
return Math.min((entityScore * 0.6) + (patternScore * 0.4), 1.0);
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Get statistics about the entity lookup table
|
|
161
|
-
*/
|
|
162
|
-
async getStats() {
|
|
163
|
-
const query = `
|
|
164
|
-
SELECT
|
|
165
|
-
entity_type,
|
|
166
|
-
COUNT(*) as count
|
|
167
|
-
FROM entity_lookup
|
|
168
|
-
GROUP BY entity_type
|
|
169
|
-
ORDER BY entity_type
|
|
170
|
-
`;
|
|
171
|
-
const result = await this.pool.query(query);
|
|
172
|
-
const by_type = {};
|
|
173
|
-
let total = 0;
|
|
174
|
-
result.rows.forEach(row => {
|
|
175
|
-
by_type[row.entity_type] = parseInt(row.count);
|
|
176
|
-
total += parseInt(row.count);
|
|
177
|
-
});
|
|
178
|
-
return { total, by_type };
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Test the similarity matching for a specific entity name
|
|
182
|
-
* Useful for debugging and tuning the similarity threshold
|
|
183
|
-
*/
|
|
184
|
-
async testSimilarity(entityName, queryText) {
|
|
185
|
-
const query = `
|
|
186
|
-
SELECT similarity($1, $2) as score
|
|
187
|
-
`;
|
|
188
|
-
const result = await this.pool.query(query, [entityName, queryText]);
|
|
189
|
-
return result.rows[0]?.score || 0;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Create a default QueryRouter instance using environment variables
|
|
194
|
-
*/
|
|
195
|
-
export function createQueryRouter() {
|
|
196
|
-
return new QueryRouter({
|
|
197
|
-
host: process.env.GRAPH_DB_HOST || 'localhost',
|
|
198
|
-
port: parseInt(process.env.GRAPH_DB_PORT || '5432'),
|
|
199
|
-
database: process.env.GRAPH_DB_NAME || 'eliza',
|
|
200
|
-
user: process.env.GRAPH_DB_USER,
|
|
201
|
-
password: process.env.GRAPH_DB_PASSWORD,
|
|
202
|
-
entitySimilarityThreshold: parseFloat(process.env.ENTITY_SIMILARITY_THRESHOLD || '0.15'),
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
//# sourceMappingURL=query_router.js.map
|
package/dist/query_router.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"query_router.js","sourceRoot":"","sources":["../src/query_router.ts"],"names":[],"mappings":"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"}
|