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.
@@ -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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"}
@@ -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"}
@@ -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
@@ -1 +0,0 @@
1
- {"version":3,"file":"query_router.js","sourceRoot":"","sources":["../src/query_router.ts"],"names":[],"mappings":"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"}