vesper-memory 0.3.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/.env.example +28 -0
- package/CHANGELOG.md +137 -0
- package/LICENSE +21 -0
- package/README.md +665 -0
- package/config/sqlite-schema.sql +413 -0
- package/dist/benchmark/index.d.ts +18 -0
- package/dist/benchmark/index.d.ts.map +1 -0
- package/dist/benchmark/index.js +19 -0
- package/dist/benchmark/index.js.map +1 -0
- package/dist/benchmark/metrics-collector.d.ts +90 -0
- package/dist/benchmark/metrics-collector.d.ts.map +1 -0
- package/dist/benchmark/metrics-collector.js +196 -0
- package/dist/benchmark/metrics-collector.js.map +1 -0
- package/dist/benchmark/report-generator.d.ts +35 -0
- package/dist/benchmark/report-generator.d.ts.map +1 -0
- package/dist/benchmark/report-generator.js +221 -0
- package/dist/benchmark/report-generator.js.map +1 -0
- package/dist/benchmark/runner.d.ts +30 -0
- package/dist/benchmark/runner.d.ts.map +1 -0
- package/dist/benchmark/runner.js +308 -0
- package/dist/benchmark/runner.js.map +1 -0
- package/dist/benchmark/scenarios/context-recall.d.ts +65 -0
- package/dist/benchmark/scenarios/context-recall.d.ts.map +1 -0
- package/dist/benchmark/scenarios/context-recall.js +180 -0
- package/dist/benchmark/scenarios/context-recall.js.map +1 -0
- package/dist/benchmark/scenarios/index.d.ts +34 -0
- package/dist/benchmark/scenarios/index.d.ts.map +1 -0
- package/dist/benchmark/scenarios/index.js +230 -0
- package/dist/benchmark/scenarios/index.js.map +1 -0
- package/dist/benchmark/statistics.d.ts +125 -0
- package/dist/benchmark/statistics.d.ts.map +1 -0
- package/dist/benchmark/statistics.js +520 -0
- package/dist/benchmark/statistics.js.map +1 -0
- package/dist/benchmark/types.d.ts +458 -0
- package/dist/benchmark/types.d.ts.map +1 -0
- package/dist/benchmark/types.js +297 -0
- package/dist/benchmark/types.js.map +1 -0
- package/dist/cli 2.js +583 -0
- package/dist/cli.d 2.ts +8 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts 2.map +1 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +583 -0
- package/dist/cli.js 2.map +1 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/rate-limits.d.ts +76 -0
- package/dist/config/rate-limits.d.ts.map +1 -0
- package/dist/config/rate-limits.js +161 -0
- package/dist/config/rate-limits.js.map +1 -0
- package/dist/config 2/rate-limits.d.ts +76 -0
- package/dist/config 2/rate-limits.d.ts.map +1 -0
- package/dist/config 2/rate-limits.js +161 -0
- package/dist/config 2/rate-limits.js.map +1 -0
- package/dist/consolidation/pipeline.d.ts +52 -0
- package/dist/consolidation/pipeline.d.ts.map +1 -0
- package/dist/consolidation/pipeline.js +193 -0
- package/dist/consolidation/pipeline.js.map +1 -0
- package/dist/consolidation 2/pipeline.d.ts +52 -0
- package/dist/consolidation 2/pipeline.d.ts.map +1 -0
- package/dist/consolidation 2/pipeline.js +193 -0
- package/dist/consolidation 2/pipeline.js.map +1 -0
- package/dist/embeddings/client.d.ts +95 -0
- package/dist/embeddings/client.d.ts.map +1 -0
- package/dist/embeddings/client.js +162 -0
- package/dist/embeddings/client.js.map +1 -0
- package/dist/embeddings 2/client.d.ts +94 -0
- package/dist/embeddings 2/client.d.ts.map +1 -0
- package/dist/embeddings 2/client.js +144 -0
- package/dist/embeddings 2/client.js.map +1 -0
- package/dist/memory-layers/semantic-memory.d.ts +76 -0
- package/dist/memory-layers/semantic-memory.d.ts.map +1 -0
- package/dist/memory-layers/semantic-memory.js +231 -0
- package/dist/memory-layers/semantic-memory.js.map +1 -0
- package/dist/memory-layers/skill-library.d.ts +25 -0
- package/dist/memory-layers/skill-library.d.ts.map +1 -0
- package/dist/memory-layers/skill-library.js +54 -0
- package/dist/memory-layers/skill-library.js.map +1 -0
- package/dist/memory-layers/working-memory.d.ts +57 -0
- package/dist/memory-layers/working-memory.d.ts.map +1 -0
- package/dist/memory-layers/working-memory.js +153 -0
- package/dist/memory-layers/working-memory.js.map +1 -0
- package/dist/memory-layers 2/semantic-memory.d.ts +33 -0
- package/dist/memory-layers 2/semantic-memory.d.ts.map +1 -0
- package/dist/memory-layers 2/semantic-memory.js +114 -0
- package/dist/memory-layers 2/semantic-memory.js.map +1 -0
- package/dist/memory-layers 2/skill-library.d.ts +25 -0
- package/dist/memory-layers 2/skill-library.d.ts.map +1 -0
- package/dist/memory-layers 2/skill-library.js +54 -0
- package/dist/memory-layers 2/skill-library.js.map +1 -0
- package/dist/memory-layers 2/working-memory.d.ts +57 -0
- package/dist/memory-layers 2/working-memory.d.ts.map +1 -0
- package/dist/memory-layers 2/working-memory.js +153 -0
- package/dist/memory-layers 2/working-memory.js.map +1 -0
- package/dist/middleware/auth.d.ts +287 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +610 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware 2/auth.d.ts +287 -0
- package/dist/middleware 2/auth.d.ts.map +1 -0
- package/dist/middleware 2/auth.js +610 -0
- package/dist/middleware 2/auth.js.map +1 -0
- package/dist/monitoring/health.d.ts +241 -0
- package/dist/monitoring/health.d.ts.map +1 -0
- package/dist/monitoring/health.js +649 -0
- package/dist/monitoring/health.js.map +1 -0
- package/dist/monitoring/metrics.d.ts +153 -0
- package/dist/monitoring/metrics.d.ts.map +1 -0
- package/dist/monitoring/metrics.js +349 -0
- package/dist/monitoring/metrics.js.map +1 -0
- package/dist/monitoring 2/health.d.ts +241 -0
- package/dist/monitoring 2/health.d.ts.map +1 -0
- package/dist/monitoring 2/health.js +649 -0
- package/dist/monitoring 2/health.js.map +1 -0
- package/dist/monitoring 2/metrics.d.ts +153 -0
- package/dist/monitoring 2/metrics.d.ts.map +1 -0
- package/dist/monitoring 2/metrics.js +349 -0
- package/dist/monitoring 2/metrics.js.map +1 -0
- package/dist/retrieval/hybrid-search.d.ts +186 -0
- package/dist/retrieval/hybrid-search.d.ts.map +1 -0
- package/dist/retrieval/hybrid-search.js +330 -0
- package/dist/retrieval/hybrid-search.js.map +1 -0
- package/dist/retrieval 2/hybrid-search.d.ts +186 -0
- package/dist/retrieval 2/hybrid-search.d.ts.map +1 -0
- package/dist/retrieval 2/hybrid-search.js +327 -0
- package/dist/retrieval 2/hybrid-search.js.map +1 -0
- package/dist/router/smart-router.d.ts +157 -0
- package/dist/router/smart-router.d.ts.map +1 -0
- package/dist/router/smart-router.js +524 -0
- package/dist/router/smart-router.js.map +1 -0
- package/dist/router 2/smart-router.d.ts +111 -0
- package/dist/router 2/smart-router.d.ts.map +1 -0
- package/dist/router 2/smart-router.js +383 -0
- package/dist/router 2/smart-router.js.map +1 -0
- package/dist/security/rate-limit-middleware.d.ts +119 -0
- package/dist/security/rate-limit-middleware.d.ts.map +1 -0
- package/dist/security/rate-limit-middleware.js +193 -0
- package/dist/security/rate-limit-middleware.js.map +1 -0
- package/dist/security 2/rate-limit-middleware.d.ts +119 -0
- package/dist/security 2/rate-limit-middleware.d.ts.map +1 -0
- package/dist/security 2/rate-limit-middleware.js +193 -0
- package/dist/security 2/rate-limit-middleware.js.map +1 -0
- package/dist/server 2.js +861 -0
- package/dist/server-wrapper 2.js +170 -0
- package/dist/server-wrapper.d 2.ts +12 -0
- package/dist/server-wrapper.d.ts +12 -0
- package/dist/server-wrapper.d.ts 2.map +1 -0
- package/dist/server-wrapper.d.ts.map +1 -0
- package/dist/server-wrapper.js +170 -0
- package/dist/server-wrapper.js 2.map +1 -0
- package/dist/server-wrapper.js.map +1 -0
- package/dist/server.d 2.ts +14 -0
- package/dist/server.d.ts +14 -0
- package/dist/server.d.ts 2.map +1 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +656 -0
- package/dist/server.js 2.map +1 -0
- package/dist/server.js.map +1 -0
- package/dist/synthesis/conflict-detector.d.ts +43 -0
- package/dist/synthesis/conflict-detector.d.ts.map +1 -0
- package/dist/synthesis/conflict-detector.js +125 -0
- package/dist/synthesis/conflict-detector.js.map +1 -0
- package/dist/synthesis 2/conflict-detector.d.ts +43 -0
- package/dist/synthesis 2/conflict-detector.d.ts.map +1 -0
- package/dist/synthesis 2/conflict-detector.js +125 -0
- package/dist/synthesis 2/conflict-detector.js.map +1 -0
- package/dist/utils/monitoring.d.ts +25 -0
- package/dist/utils/monitoring.d.ts.map +1 -0
- package/dist/utils/monitoring.js +41 -0
- package/dist/utils/monitoring.js.map +1 -0
- package/dist/utils/rate-limiter.d.ts +97 -0
- package/dist/utils/rate-limiter.d.ts.map +1 -0
- package/dist/utils/rate-limiter.js +166 -0
- package/dist/utils/rate-limiter.js.map +1 -0
- package/dist/utils/validation.d.ts +139 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +195 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/utils 2/monitoring.d.ts +25 -0
- package/dist/utils 2/monitoring.d.ts.map +1 -0
- package/dist/utils 2/monitoring.js +41 -0
- package/dist/utils 2/monitoring.js.map +1 -0
- package/dist/utils 2/rate-limiter.d.ts +97 -0
- package/dist/utils 2/rate-limiter.d.ts.map +1 -0
- package/dist/utils 2/rate-limiter.js +166 -0
- package/dist/utils 2/rate-limiter.js.map +1 -0
- package/dist/utils 2/validation.d.ts +139 -0
- package/dist/utils 2/validation.d.ts.map +1 -0
- package/dist/utils 2/validation.js +195 -0
- package/dist/utils 2/validation.js.map +1 -0
- package/docker-compose.yml +65 -0
- package/embedding-service/Dockerfile +29 -0
- package/embedding-service/README.md +68 -0
- package/embedding-service/requirements.txt +6 -0
- package/embedding-service/server.py +110 -0
- package/package.json +92 -0
- package/scripts/FRESH_INSTALL.md +280 -0
- package/scripts/README.md +101 -0
- package/scripts/ensure-infrastructure.sh +38 -0
- package/scripts/fresh-install-auto.sh +96 -0
- package/scripts/fresh-install.sh +167 -0
- package/scripts/health-check.sh +72 -0
- package/scripts/init-qdrant.ts +201 -0
- package/scripts/postinstall.js +94 -0
- package/scripts/run-accuracy-benchmark.ts +1237 -0
- package/scripts/run-real-benchmark.ts +581 -0
- package/scripts/test-mcp-server.sh +38 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-router.d.ts","sourceRoot":"","sources":["../../src/router/smart-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAY1E;;GAEG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE;IAAE,aAAa,CAAC,EAAE,kBAAkB,CAAA;CAAE,GAAG,IAAI,CAEvE;AAED;;;GAGG;AACH,oBAAY,SAAS;IACnB,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,YAAY,GAAG,QAAQ,CAAC;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CA0FjE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,YAAY,EAAE,CAAC,CAyDzB;AA2ND;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE1D;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;CACf;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAI/D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA+BpE;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,EAAE,mBAAmB,GAAG,IAAI,CAE/E;AAuBD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,YAAY,EAAE,CAAC,CAwCzB"}
|
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart Query Router
|
|
3
|
+
*
|
|
4
|
+
* Implements intelligent routing logic from v3.0 plan:
|
|
5
|
+
* 1. Always check working memory first (fast path)
|
|
6
|
+
* 2. Classify query type using regex patterns
|
|
7
|
+
* 3. Route to appropriate handler based on classification
|
|
8
|
+
* 4. Fall back to hybrid search for complex queries
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Module-level dependency - set via init()
|
|
12
|
+
*/
|
|
13
|
+
let workingMemoryLayer = null;
|
|
14
|
+
/**
|
|
15
|
+
* Module-level semantic memory dependency for preference queries
|
|
16
|
+
*/
|
|
17
|
+
let semanticMemoryLayer = null;
|
|
18
|
+
/**
|
|
19
|
+
* Initialize the router with dependencies
|
|
20
|
+
*/
|
|
21
|
+
export function init(deps) {
|
|
22
|
+
workingMemoryLayer = deps.workingMemory || null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Query type enumeration
|
|
26
|
+
* Used to classify queries and route to appropriate handlers
|
|
27
|
+
*/
|
|
28
|
+
export var QueryType;
|
|
29
|
+
(function (QueryType) {
|
|
30
|
+
QueryType["FACTUAL"] = "factual";
|
|
31
|
+
QueryType["PREFERENCE"] = "preference";
|
|
32
|
+
QueryType["PROJECT"] = "project";
|
|
33
|
+
QueryType["TEMPORAL"] = "temporal";
|
|
34
|
+
QueryType["SKILL"] = "skill";
|
|
35
|
+
QueryType["COMPLEX"] = "complex";
|
|
36
|
+
})(QueryType || (QueryType = {}));
|
|
37
|
+
/**
|
|
38
|
+
* Classify a query into one of the six query types
|
|
39
|
+
*
|
|
40
|
+
* Uses simple regex patterns to identify query intent without LLM calls.
|
|
41
|
+
* Falls back to 'complex' for ambiguous queries.
|
|
42
|
+
*
|
|
43
|
+
* Patterns (in order of specificity):
|
|
44
|
+
* - skill: "like before", "same as", "same way", "how you", "analyze"
|
|
45
|
+
* - factual: "what is", "who is", "where is"
|
|
46
|
+
* - temporal: "last week", "yesterday", "recently", etc.
|
|
47
|
+
* - preference: "prefer", "want", "style", "favorite"
|
|
48
|
+
* - project: "project", "working on", "decided", "building", "creating", "developing"
|
|
49
|
+
* - complex: fallback for anything else
|
|
50
|
+
*/
|
|
51
|
+
export function classifyQuery(query) {
|
|
52
|
+
const normalizedQuery = query.toLowerCase().trim();
|
|
53
|
+
// Pattern definitions with confidence scores
|
|
54
|
+
// NOTE: More specific patterns should be checked first to avoid ambiguity
|
|
55
|
+
const patterns = [
|
|
56
|
+
// Skill patterns are most specific - check before preference and temporal
|
|
57
|
+
{
|
|
58
|
+
type: QueryType.SKILL,
|
|
59
|
+
regex: /\b(like before|same as|same way|how you)\b/i,
|
|
60
|
+
confidence: 0.85,
|
|
61
|
+
label: "skill"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
type: QueryType.SKILL,
|
|
65
|
+
regex: /\banalyze\b/i,
|
|
66
|
+
confidence: 0.75,
|
|
67
|
+
label: "skill_analyze"
|
|
68
|
+
},
|
|
69
|
+
// Temporal patterns - check before factual WH questions since temporal is more specific
|
|
70
|
+
{
|
|
71
|
+
type: QueryType.TEMPORAL,
|
|
72
|
+
regex: /\b(last week|last month|last year|last time)\b/i,
|
|
73
|
+
confidence: 0.95,
|
|
74
|
+
label: "temporal_specific"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
type: QueryType.TEMPORAL,
|
|
78
|
+
regex: /\b(yesterday|recently|earlier)\b/i,
|
|
79
|
+
confidence: 0.9,
|
|
80
|
+
label: "temporal"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
type: QueryType.TEMPORAL,
|
|
84
|
+
regex: /\bbefore\b/i,
|
|
85
|
+
confidence: 0.7,
|
|
86
|
+
label: "temporal_before"
|
|
87
|
+
},
|
|
88
|
+
// Factual patterns (WH questions) - after temporal to avoid misclassifying temporal queries
|
|
89
|
+
{
|
|
90
|
+
type: QueryType.FACTUAL,
|
|
91
|
+
regex: /\b(what|who|where)\s+(is|was|are|were)\b/i,
|
|
92
|
+
confidence: 0.95,
|
|
93
|
+
label: "factual_wh"
|
|
94
|
+
},
|
|
95
|
+
// Preference patterns
|
|
96
|
+
{
|
|
97
|
+
type: QueryType.PREFERENCE,
|
|
98
|
+
regex: /\b(prefer|want|style|favorite)\b/i,
|
|
99
|
+
confidence: 0.9,
|
|
100
|
+
label: "preference"
|
|
101
|
+
},
|
|
102
|
+
// Note: 'like' as preference is checked but has lower confidence due to ambiguity
|
|
103
|
+
{
|
|
104
|
+
type: QueryType.PREFERENCE,
|
|
105
|
+
regex: /\bhow do i like\b/i,
|
|
106
|
+
confidence: 0.85,
|
|
107
|
+
label: "preference_like"
|
|
108
|
+
},
|
|
109
|
+
// Project patterns
|
|
110
|
+
{
|
|
111
|
+
type: QueryType.PROJECT,
|
|
112
|
+
regex: /\b(working on|decided|decide|decision)\b/i,
|
|
113
|
+
confidence: 0.9,
|
|
114
|
+
label: "project_specific"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
type: QueryType.PROJECT,
|
|
118
|
+
regex: /\b(project|building|creating|developing)\b/i,
|
|
119
|
+
confidence: 0.85,
|
|
120
|
+
label: "project"
|
|
121
|
+
}
|
|
122
|
+
];
|
|
123
|
+
// Check each pattern in order
|
|
124
|
+
for (const pattern of patterns) {
|
|
125
|
+
if (pattern.regex.test(normalizedQuery)) {
|
|
126
|
+
return {
|
|
127
|
+
type: pattern.type,
|
|
128
|
+
confidence: pattern.confidence,
|
|
129
|
+
matchedPattern: pattern.label
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Default to complex query
|
|
134
|
+
return {
|
|
135
|
+
type: QueryType.COMPLEX,
|
|
136
|
+
confidence: 0.5
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Smart query router following v3.0 plan retrieval strategy
|
|
141
|
+
*
|
|
142
|
+
* Routing decision tree:
|
|
143
|
+
* 1. Check working memory first (5ms, high confidence threshold)
|
|
144
|
+
* 2. Classify query type with regex
|
|
145
|
+
* 3. Route to appropriate handler:
|
|
146
|
+
* - factual: direct entity lookup
|
|
147
|
+
* - preference: preference retrieval
|
|
148
|
+
* - project: graph traversal with HippoRAG
|
|
149
|
+
* - temporal: time-based filtering
|
|
150
|
+
* - skill: skill library search
|
|
151
|
+
* - complex: hybrid search (dense + sparse + BM25)
|
|
152
|
+
*
|
|
153
|
+
* @param query - The user's query string
|
|
154
|
+
* @param context - Routing context (user, conversation, etc.)
|
|
155
|
+
* @returns Promise resolving to array of memory results
|
|
156
|
+
*
|
|
157
|
+
* @throws Error if query is empty or context is invalid
|
|
158
|
+
*/
|
|
159
|
+
export async function retrieve(query, context) {
|
|
160
|
+
// Input validation
|
|
161
|
+
if (!query || query.trim().length === 0) {
|
|
162
|
+
throw new Error("Query cannot be empty");
|
|
163
|
+
}
|
|
164
|
+
if (!context || !context.userId) {
|
|
165
|
+
throw new Error("Valid routing context with userId is required");
|
|
166
|
+
}
|
|
167
|
+
// Step 1: ALWAYS check working memory first (5ms fast path)
|
|
168
|
+
const recentMemories = await checkWorkingMemory(query, context);
|
|
169
|
+
// High similarity threshold suggests cache hit - return immediately
|
|
170
|
+
if (recentMemories.length > 0 && recentMemories[0].similarity > 0.85) {
|
|
171
|
+
console.debug(`[Router] Cache hit in working memory for query: "${query}"`);
|
|
172
|
+
return recentMemories;
|
|
173
|
+
}
|
|
174
|
+
// Step 2: Classify query type using regex patterns
|
|
175
|
+
const classification = classifyQuery(query);
|
|
176
|
+
console.debug(`[Router] Query classified as ${classification.type} ` +
|
|
177
|
+
`(confidence: ${classification.confidence}, pattern: ${classification.matchedPattern})`);
|
|
178
|
+
// Step 3: Route to appropriate handler based on classification
|
|
179
|
+
let results = [];
|
|
180
|
+
switch (classification.type) {
|
|
181
|
+
case QueryType.FACTUAL:
|
|
182
|
+
results = await handleFactualQuery(query, context);
|
|
183
|
+
break;
|
|
184
|
+
case QueryType.PREFERENCE:
|
|
185
|
+
results = await handlePreferenceQuery(query, context);
|
|
186
|
+
break;
|
|
187
|
+
case QueryType.PROJECT:
|
|
188
|
+
results = await handleProjectQuery(query, context);
|
|
189
|
+
break;
|
|
190
|
+
case QueryType.TEMPORAL:
|
|
191
|
+
results = await handleTemporalQuery(query, context);
|
|
192
|
+
break;
|
|
193
|
+
case QueryType.SKILL:
|
|
194
|
+
results = await handleSkillQuery(query, context);
|
|
195
|
+
break;
|
|
196
|
+
case QueryType.COMPLEX:
|
|
197
|
+
default:
|
|
198
|
+
results = await handleComplexQuery(query, context);
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
return results;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Check working memory for recent relevant memories
|
|
205
|
+
*
|
|
206
|
+
* Implementation stub - will integrate with Redis/Hopfield layer
|
|
207
|
+
* Current behavior: returns empty array (no working memory yet)
|
|
208
|
+
*
|
|
209
|
+
* @param query - Search query
|
|
210
|
+
* @param context - Routing context
|
|
211
|
+
* @returns Recent memory results matching query
|
|
212
|
+
*/
|
|
213
|
+
async function checkWorkingMemory(query, _context) {
|
|
214
|
+
console.debug(`[Router] Checking working memory for: "${query}"`);
|
|
215
|
+
// Early return if working memory not available
|
|
216
|
+
if (!workingMemoryLayer) {
|
|
217
|
+
console.debug(`[Router] Working memory layer not initialized`);
|
|
218
|
+
return [];
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
// Search working memory using keyword matching (5ms fast path)
|
|
222
|
+
const results = await workingMemoryLayer.search(query, 3);
|
|
223
|
+
// Transform to MemoryResult format
|
|
224
|
+
return results.map(r => ({
|
|
225
|
+
id: r.memory.conversationId,
|
|
226
|
+
source: "working",
|
|
227
|
+
content: r.memory.fullText,
|
|
228
|
+
similarity: r.similarity,
|
|
229
|
+
timestamp: r.memory.timestamp,
|
|
230
|
+
}));
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
console.error(`[Router] Working memory search error:`, err);
|
|
234
|
+
return [];
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Handle factual queries
|
|
239
|
+
*
|
|
240
|
+
* Pattern: "What is X?", "Who is Y?", "Where is Z?"
|
|
241
|
+
* Handler: Direct entity lookup in semantic memory
|
|
242
|
+
*
|
|
243
|
+
* Implementation stub
|
|
244
|
+
*
|
|
245
|
+
* @param query - The factual query
|
|
246
|
+
* @param context - Routing context
|
|
247
|
+
* @returns Entity information
|
|
248
|
+
*/
|
|
249
|
+
async function handleFactualQuery(query, _context) {
|
|
250
|
+
console.debug(`[Router] Handling factual query: "${query}"`);
|
|
251
|
+
// TODO: Implement factual query handler
|
|
252
|
+
// 1. Extract entity name from query (using NER or simple heuristics)
|
|
253
|
+
// 2. Lookup entity in semantic memory
|
|
254
|
+
// 3. Retrieve related facts and properties
|
|
255
|
+
// 4. Return with confidence scores
|
|
256
|
+
return [];
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Handle preference queries
|
|
260
|
+
*
|
|
261
|
+
* Pattern: "How do I prefer X?", "What style do I like?"
|
|
262
|
+
* Handler: Optimized direct SQLite lookup with temporal decay
|
|
263
|
+
*
|
|
264
|
+
* This function uses direct database queries instead of embedding generation
|
|
265
|
+
* for improved latency (~50ms vs ~200ms).
|
|
266
|
+
*
|
|
267
|
+
* @param query - The preference query
|
|
268
|
+
* @param context - Routing context
|
|
269
|
+
* @returns User preference information
|
|
270
|
+
*/
|
|
271
|
+
async function handlePreferenceQuery(query, context) {
|
|
272
|
+
return handlePreferenceQueryDirect(query, context);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Handle project queries
|
|
276
|
+
*
|
|
277
|
+
* Pattern: "What did we decide about X?", "What's the status on Y?"
|
|
278
|
+
* Handler: Graph traversal with HippoRAG personalized PageRank
|
|
279
|
+
*
|
|
280
|
+
* Implementation stub
|
|
281
|
+
*
|
|
282
|
+
* @param query - The project query
|
|
283
|
+
* @param context - Routing context
|
|
284
|
+
* @returns Project-related information via graph traversal
|
|
285
|
+
*/
|
|
286
|
+
async function handleProjectQuery(query, _context) {
|
|
287
|
+
console.debug(`[Router] Handling project query: "${query}"`);
|
|
288
|
+
// TODO: Implement project query handler
|
|
289
|
+
// 1. Extract project entity name from query
|
|
290
|
+
// 2. Lookup project entity in semantic memory
|
|
291
|
+
// 3. Run HippoRAG personalized PageRank from project node (depth=2)
|
|
292
|
+
// 4. Return connected entities and relationships
|
|
293
|
+
return [];
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Handle temporal queries
|
|
297
|
+
*
|
|
298
|
+
* Pattern: "What were we working on last week?", "What was discussed yesterday?"
|
|
299
|
+
* Handler: Time-based filtering from semantic memory
|
|
300
|
+
*
|
|
301
|
+
* Implementation stub
|
|
302
|
+
*
|
|
303
|
+
* @param query - The temporal query
|
|
304
|
+
* @param context - Routing context
|
|
305
|
+
* @returns Memories from specified time range
|
|
306
|
+
*/
|
|
307
|
+
async function handleTemporalQuery(query, _context) {
|
|
308
|
+
console.debug(`[Router] Handling temporal query: "${query}"`);
|
|
309
|
+
// TODO: Implement temporal query handler
|
|
310
|
+
// 1. Parse temporal references from query
|
|
311
|
+
// 2. Convert to time range (start_date, end_date)
|
|
312
|
+
// 3. Query semantic memory for memories in that range
|
|
313
|
+
// 4. Apply temporal decay based on specificity
|
|
314
|
+
return [];
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Handle skill queries
|
|
318
|
+
*
|
|
319
|
+
* Pattern: "Analyze this like before", "Same way as last time"
|
|
320
|
+
* Handler: Skill library semantic search
|
|
321
|
+
*
|
|
322
|
+
* Implementation stub
|
|
323
|
+
*
|
|
324
|
+
* @param query - The skill query
|
|
325
|
+
* @param context - Routing context
|
|
326
|
+
* @returns Matching skills from skill library
|
|
327
|
+
*/
|
|
328
|
+
async function handleSkillQuery(query, _context) {
|
|
329
|
+
console.debug(`[Router] Handling skill query: "${query}"`);
|
|
330
|
+
// TODO: Implement skill query handler
|
|
331
|
+
// 1. Embed query using BGE-large
|
|
332
|
+
// 2. Search skill library for matching triggers
|
|
333
|
+
// 3. Filter by prerequisites being met in context
|
|
334
|
+
// 4. Return skills ranked by success rate
|
|
335
|
+
return [];
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Handle complex queries
|
|
339
|
+
*
|
|
340
|
+
* Pattern: Ambiguous queries that don't match specific patterns
|
|
341
|
+
* Handler: Hybrid search across all representations
|
|
342
|
+
*
|
|
343
|
+
* Hybrid search pipeline:
|
|
344
|
+
* 1. Parallel search: dense embeddings + sparse vectors + BM25
|
|
345
|
+
* 2. Reciprocal Rank Fusion (k=60) to combine results
|
|
346
|
+
* 3. Light reranking with cross-encoder on top-10
|
|
347
|
+
* 4. Return top-5 fused results
|
|
348
|
+
*
|
|
349
|
+
* Implementation stub
|
|
350
|
+
*
|
|
351
|
+
* @param query - The complex query
|
|
352
|
+
* @param context - Routing context
|
|
353
|
+
* @returns Hybrid search results
|
|
354
|
+
*/
|
|
355
|
+
async function handleComplexQuery(query, _context) {
|
|
356
|
+
console.debug(`[Router] Handling complex query with hybrid search: "${query}"`);
|
|
357
|
+
// TODO: Implement hybrid search
|
|
358
|
+
// 1. Embed query in multiple representations:
|
|
359
|
+
// - Dense: BGE-large embeddings
|
|
360
|
+
// - Sparse: SPLADE++ sparse vectors
|
|
361
|
+
// - Keyword: BM25 tokenization
|
|
362
|
+
//
|
|
363
|
+
// 2. Parallel search in Qdrant:
|
|
364
|
+
// - Dense similarity search (limit: 20)
|
|
365
|
+
// - Sparse similarity search (limit: 20)
|
|
366
|
+
// - BM25 full-text search (limit: 20)
|
|
367
|
+
//
|
|
368
|
+
// 3. Reciprocal Rank Fusion:
|
|
369
|
+
// - Combine ranked lists from three searches
|
|
370
|
+
// - Weight scores using RRF formula with k=60
|
|
371
|
+
//
|
|
372
|
+
// 4. Light reranking:
|
|
373
|
+
// - Use cross-encoder (not ColBERT for speed)
|
|
374
|
+
// - Rerank only top-10 results
|
|
375
|
+
// - Adds ~20ms but significant accuracy gain
|
|
376
|
+
//
|
|
377
|
+
// 5. Return top-5 after reranking
|
|
378
|
+
return [];
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Extract entity name from a query
|
|
382
|
+
*
|
|
383
|
+
* Implementation stub for entity extraction
|
|
384
|
+
* Will later integrate with NER or simple heuristics
|
|
385
|
+
*/
|
|
386
|
+
export function extractEntityName(_query) {
|
|
387
|
+
// TODO: Implement entity extraction
|
|
388
|
+
// Current: just return null
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Extract domain/category from a query
|
|
393
|
+
*
|
|
394
|
+
* Delegates to extractPreferenceDomain for preference queries.
|
|
395
|
+
* Used for preference and skill queries.
|
|
396
|
+
*
|
|
397
|
+
* @param query - The query string
|
|
398
|
+
* @returns Extracted domain (lowercase) or null if not extractable
|
|
399
|
+
*/
|
|
400
|
+
export function extractDomain(query) {
|
|
401
|
+
return extractPreferenceDomain(query);
|
|
402
|
+
}
|
|
403
|
+
export function parseTimeRange(_query) {
|
|
404
|
+
// TODO: Implement temporal reference parsing
|
|
405
|
+
// Current: just return null
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Extract preference domain from a query using regex patterns
|
|
410
|
+
*
|
|
411
|
+
* Patterns recognized:
|
|
412
|
+
* - "my X style" -> X (coding, writing, etc.)
|
|
413
|
+
* - "favorite X" -> X (language, framework, etc.)
|
|
414
|
+
* - "prefer X" -> X (TypeScript, tabs, etc.)
|
|
415
|
+
* - "like my X" -> X (coffee, code, etc.)
|
|
416
|
+
*
|
|
417
|
+
* @param query - The preference query
|
|
418
|
+
* @returns Extracted domain (lowercase) or null if not extractable
|
|
419
|
+
*/
|
|
420
|
+
export function extractPreferenceDomain(query) {
|
|
421
|
+
const normalizedQuery = query.toLowerCase().trim();
|
|
422
|
+
// Pattern definitions for domain extraction
|
|
423
|
+
// Each pattern has a capture group for the domain noun
|
|
424
|
+
// NOTE: Order matters - more specific patterns should come before generic ones
|
|
425
|
+
const patterns = [
|
|
426
|
+
// "my X style" pattern - captures word before "style"
|
|
427
|
+
/\bmy\s+(\w+)\s+style\b/i,
|
|
428
|
+
// "favorite X" pattern - captures word after "favorite"
|
|
429
|
+
/\bfavorite\s+(\w+)\b/i,
|
|
430
|
+
// "prefer my X" pattern - captures word after "my" (more specific than "prefer X")
|
|
431
|
+
/\bprefer\s+my\s+(\w+)\b/i,
|
|
432
|
+
// "prefer X" or "prefer X or Y" pattern - captures first word after "prefer"
|
|
433
|
+
/\bprefer\s+(\w+)\b/i,
|
|
434
|
+
// "like my X" pattern - captures word after "my"
|
|
435
|
+
/\blike\s+my\s+(\w+)\b/i,
|
|
436
|
+
// "my X formatted" or "my X preferences" pattern
|
|
437
|
+
/\bmy\s+(\w+)\s+(formatted|preference|preferences)\b/i,
|
|
438
|
+
// "X preference" pattern - captures word before "preference"
|
|
439
|
+
/\b(\w+)\s+preference\b/i,
|
|
440
|
+
];
|
|
441
|
+
for (const pattern of patterns) {
|
|
442
|
+
const match = normalizedQuery.match(pattern);
|
|
443
|
+
if (match && match[1]) {
|
|
444
|
+
return match[1].toLowerCase();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
return null;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Initialize the preference handler with semantic memory dependency
|
|
451
|
+
*
|
|
452
|
+
* @param semanticMemory - SemanticMemoryLayer instance for preference lookups
|
|
453
|
+
*/
|
|
454
|
+
export function initPreferenceHandler(semanticMemory) {
|
|
455
|
+
semanticMemoryLayer = semanticMemory;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Calculate temporal decay weight using exponential formula
|
|
459
|
+
*
|
|
460
|
+
* Decay formula: weight = e^(-days/30)
|
|
461
|
+
* - Decays to 50% in ~21 days
|
|
462
|
+
* - Decays to 10% in ~69 days
|
|
463
|
+
*
|
|
464
|
+
* @param lastAccessed - Date when the preference was last accessed
|
|
465
|
+
* @returns Weight between 0 and 1
|
|
466
|
+
*/
|
|
467
|
+
function calculateTemporalDecay(lastAccessed) {
|
|
468
|
+
const lastAccessedDate = typeof lastAccessed === 'string'
|
|
469
|
+
? new Date(lastAccessed)
|
|
470
|
+
: lastAccessed;
|
|
471
|
+
const now = new Date();
|
|
472
|
+
const daysSinceAccess = (now.getTime() - lastAccessedDate.getTime()) / (1000 * 60 * 60 * 24);
|
|
473
|
+
// Exponential decay with 30-day half-life
|
|
474
|
+
return Math.exp(-daysSinceAccess / 30);
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Direct preference query handler - optimized for low latency
|
|
478
|
+
*
|
|
479
|
+
* This handler bypasses embedding generation by using direct SQLite lookup:
|
|
480
|
+
* 1. Extract preference domain from query using regex
|
|
481
|
+
* 2. Query semantic memory with domain filter (or get all preferences)
|
|
482
|
+
* 3. Apply temporal decay weighting to prioritize recent preferences
|
|
483
|
+
* 4. Return results sorted by weighted score
|
|
484
|
+
*
|
|
485
|
+
* Performance target: <50ms (vs ~200ms for embedding-based search)
|
|
486
|
+
*
|
|
487
|
+
* @param query - The preference query
|
|
488
|
+
* @param _context - Routing context (userId, etc.)
|
|
489
|
+
* @returns Array of MemoryResult objects
|
|
490
|
+
*/
|
|
491
|
+
export async function handlePreferenceQueryDirect(query, _context) {
|
|
492
|
+
console.debug(`[Router] Handling preference query (optimized): "${query}"`);
|
|
493
|
+
if (!semanticMemoryLayer) {
|
|
494
|
+
console.debug(`[Router] Semantic memory layer not initialized for preference queries`);
|
|
495
|
+
return [];
|
|
496
|
+
}
|
|
497
|
+
// Step 1: Extract domain from query
|
|
498
|
+
const domain = extractPreferenceDomain(query);
|
|
499
|
+
console.debug(`[Router] Extracted preference domain: ${domain || 'none'}`);
|
|
500
|
+
// Step 2: Get preferences from semantic memory (filtered by domain if available)
|
|
501
|
+
const preferences = semanticMemoryLayer.getPreferences(domain || undefined);
|
|
502
|
+
if (preferences.length === 0) {
|
|
503
|
+
console.debug(`[Router] No preferences found for domain: ${domain || 'all'}`);
|
|
504
|
+
return [];
|
|
505
|
+
}
|
|
506
|
+
// Step 3: Apply temporal decay weighting and transform to MemoryResult
|
|
507
|
+
const weightedResults = preferences.map((pref) => {
|
|
508
|
+
const decayWeight = calculateTemporalDecay(pref.last_accessed || pref.created_at);
|
|
509
|
+
const confidenceWeight = pref.confidence || 1.0;
|
|
510
|
+
// Combined score: temporal decay * confidence
|
|
511
|
+
const similarity = decayWeight * confidenceWeight;
|
|
512
|
+
return {
|
|
513
|
+
id: pref.id,
|
|
514
|
+
source: "semantic",
|
|
515
|
+
content: pref.description || pref.name,
|
|
516
|
+
similarity,
|
|
517
|
+
timestamp: new Date(pref.last_accessed || pref.created_at),
|
|
518
|
+
confidence: pref.confidence
|
|
519
|
+
};
|
|
520
|
+
});
|
|
521
|
+
// Step 4: Sort by similarity (descending) and return
|
|
522
|
+
return weightedResults.sort((a, b) => b.similarity - a.similarity);
|
|
523
|
+
}
|
|
524
|
+
//# sourceMappingURL=smart-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-router.js","sourceRoot":"","sources":["../../src/router/smart-router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart Query Router
|
|
3
|
+
*
|
|
4
|
+
* Implements intelligent routing logic from v3.0 plan:
|
|
5
|
+
* 1. Always check working memory first (fast path)
|
|
6
|
+
* 2. Classify query type using regex patterns
|
|
7
|
+
* 3. Route to appropriate handler based on classification
|
|
8
|
+
* 4. Fall back to hybrid search for complex queries
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Query type enumeration
|
|
12
|
+
* Used to classify queries and route to appropriate handlers
|
|
13
|
+
*/
|
|
14
|
+
export declare enum QueryType {
|
|
15
|
+
FACTUAL = "factual",
|
|
16
|
+
PREFERENCE = "preference",
|
|
17
|
+
PROJECT = "project",
|
|
18
|
+
TEMPORAL = "temporal",
|
|
19
|
+
SKILL = "skill",
|
|
20
|
+
COMPLEX = "complex"
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Query classification result
|
|
24
|
+
*/
|
|
25
|
+
export interface ClassificationResult {
|
|
26
|
+
type: QueryType;
|
|
27
|
+
confidence: number;
|
|
28
|
+
matchedPattern?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Context for routing decisions
|
|
32
|
+
*/
|
|
33
|
+
export interface RoutingContext {
|
|
34
|
+
userId: string;
|
|
35
|
+
conversationId: string;
|
|
36
|
+
timestamp: Date;
|
|
37
|
+
metadata?: Record<string, unknown>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Memory result from any layer
|
|
41
|
+
*/
|
|
42
|
+
export interface MemoryResult {
|
|
43
|
+
id: string;
|
|
44
|
+
source: "working" | "semantic" | "procedural" | "hybrid";
|
|
45
|
+
content: string;
|
|
46
|
+
similarity: number;
|
|
47
|
+
timestamp: Date;
|
|
48
|
+
confidence?: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Classify a query into one of the six query types
|
|
52
|
+
*
|
|
53
|
+
* Uses simple regex patterns to identify query intent without LLM calls.
|
|
54
|
+
* Falls back to 'complex' for ambiguous queries.
|
|
55
|
+
*
|
|
56
|
+
* Patterns (in order of specificity):
|
|
57
|
+
* - skill: "like before", "same as", "same way", "how you", "analyze"
|
|
58
|
+
* - factual: "what is", "who is", "where is"
|
|
59
|
+
* - temporal: "last week", "yesterday", "recently", etc.
|
|
60
|
+
* - preference: "prefer", "want", "style", "favorite"
|
|
61
|
+
* - project: "project", "working on", "decided", "building", "creating", "developing"
|
|
62
|
+
* - complex: fallback for anything else
|
|
63
|
+
*/
|
|
64
|
+
export declare function classifyQuery(query: string): ClassificationResult;
|
|
65
|
+
/**
|
|
66
|
+
* Smart query router following v3.0 plan retrieval strategy
|
|
67
|
+
*
|
|
68
|
+
* Routing decision tree:
|
|
69
|
+
* 1. Check working memory first (5ms, high confidence threshold)
|
|
70
|
+
* 2. Classify query type with regex
|
|
71
|
+
* 3. Route to appropriate handler:
|
|
72
|
+
* - factual: direct entity lookup
|
|
73
|
+
* - preference: preference retrieval
|
|
74
|
+
* - project: graph traversal with HippoRAG
|
|
75
|
+
* - temporal: time-based filtering
|
|
76
|
+
* - skill: skill library search
|
|
77
|
+
* - complex: hybrid search (dense + sparse + BM25)
|
|
78
|
+
*
|
|
79
|
+
* @param query - The user's query string
|
|
80
|
+
* @param context - Routing context (user, conversation, etc.)
|
|
81
|
+
* @returns Promise resolving to array of memory results
|
|
82
|
+
*
|
|
83
|
+
* @throws Error if query is empty or context is invalid
|
|
84
|
+
*/
|
|
85
|
+
export declare function retrieve(query: string, context: RoutingContext): Promise<MemoryResult[]>;
|
|
86
|
+
/**
|
|
87
|
+
* Extract entity name from a query
|
|
88
|
+
*
|
|
89
|
+
* Implementation stub for entity extraction
|
|
90
|
+
* Will later integrate with NER or simple heuristics
|
|
91
|
+
*/
|
|
92
|
+
export declare function extractEntityName(query: string): string | null;
|
|
93
|
+
/**
|
|
94
|
+
* Extract domain/category from a query
|
|
95
|
+
*
|
|
96
|
+
* Implementation stub for domain extraction
|
|
97
|
+
* Used for preference and skill queries
|
|
98
|
+
*/
|
|
99
|
+
export declare function extractDomain(query: string): string | null;
|
|
100
|
+
/**
|
|
101
|
+
* Parse temporal references from query
|
|
102
|
+
*
|
|
103
|
+
* Implementation stub for temporal parsing
|
|
104
|
+
* Will extract time ranges like "last week", "yesterday", etc.
|
|
105
|
+
*/
|
|
106
|
+
export interface TimeRange {
|
|
107
|
+
startDate: Date;
|
|
108
|
+
endDate: Date;
|
|
109
|
+
}
|
|
110
|
+
export declare function parseTimeRange(query: string): TimeRange | null;
|
|
111
|
+
//# sourceMappingURL=smart-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-router.d.ts","sourceRoot":"","sources":["../../src/router/smart-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;GAGG;AACH,oBAAY,SAAS;IACnB,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,YAAY,GAAG,QAAQ,CAAC;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CA0FjE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,YAAY,EAAE,CAAC,CAyDzB;AAmND;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI9D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI1D;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;CACf;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAI9D"}
|