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.
Files changed (206) hide show
  1. package/.env.example +28 -0
  2. package/CHANGELOG.md +137 -0
  3. package/LICENSE +21 -0
  4. package/README.md +665 -0
  5. package/config/sqlite-schema.sql +413 -0
  6. package/dist/benchmark/index.d.ts +18 -0
  7. package/dist/benchmark/index.d.ts.map +1 -0
  8. package/dist/benchmark/index.js +19 -0
  9. package/dist/benchmark/index.js.map +1 -0
  10. package/dist/benchmark/metrics-collector.d.ts +90 -0
  11. package/dist/benchmark/metrics-collector.d.ts.map +1 -0
  12. package/dist/benchmark/metrics-collector.js +196 -0
  13. package/dist/benchmark/metrics-collector.js.map +1 -0
  14. package/dist/benchmark/report-generator.d.ts +35 -0
  15. package/dist/benchmark/report-generator.d.ts.map +1 -0
  16. package/dist/benchmark/report-generator.js +221 -0
  17. package/dist/benchmark/report-generator.js.map +1 -0
  18. package/dist/benchmark/runner.d.ts +30 -0
  19. package/dist/benchmark/runner.d.ts.map +1 -0
  20. package/dist/benchmark/runner.js +308 -0
  21. package/dist/benchmark/runner.js.map +1 -0
  22. package/dist/benchmark/scenarios/context-recall.d.ts +65 -0
  23. package/dist/benchmark/scenarios/context-recall.d.ts.map +1 -0
  24. package/dist/benchmark/scenarios/context-recall.js +180 -0
  25. package/dist/benchmark/scenarios/context-recall.js.map +1 -0
  26. package/dist/benchmark/scenarios/index.d.ts +34 -0
  27. package/dist/benchmark/scenarios/index.d.ts.map +1 -0
  28. package/dist/benchmark/scenarios/index.js +230 -0
  29. package/dist/benchmark/scenarios/index.js.map +1 -0
  30. package/dist/benchmark/statistics.d.ts +125 -0
  31. package/dist/benchmark/statistics.d.ts.map +1 -0
  32. package/dist/benchmark/statistics.js +520 -0
  33. package/dist/benchmark/statistics.js.map +1 -0
  34. package/dist/benchmark/types.d.ts +458 -0
  35. package/dist/benchmark/types.d.ts.map +1 -0
  36. package/dist/benchmark/types.js +297 -0
  37. package/dist/benchmark/types.js.map +1 -0
  38. package/dist/cli 2.js +583 -0
  39. package/dist/cli.d 2.ts +8 -0
  40. package/dist/cli.d.ts +8 -0
  41. package/dist/cli.d.ts 2.map +1 -0
  42. package/dist/cli.d.ts.map +1 -0
  43. package/dist/cli.js +583 -0
  44. package/dist/cli.js 2.map +1 -0
  45. package/dist/cli.js.map +1 -0
  46. package/dist/config/rate-limits.d.ts +76 -0
  47. package/dist/config/rate-limits.d.ts.map +1 -0
  48. package/dist/config/rate-limits.js +161 -0
  49. package/dist/config/rate-limits.js.map +1 -0
  50. package/dist/config 2/rate-limits.d.ts +76 -0
  51. package/dist/config 2/rate-limits.d.ts.map +1 -0
  52. package/dist/config 2/rate-limits.js +161 -0
  53. package/dist/config 2/rate-limits.js.map +1 -0
  54. package/dist/consolidation/pipeline.d.ts +52 -0
  55. package/dist/consolidation/pipeline.d.ts.map +1 -0
  56. package/dist/consolidation/pipeline.js +193 -0
  57. package/dist/consolidation/pipeline.js.map +1 -0
  58. package/dist/consolidation 2/pipeline.d.ts +52 -0
  59. package/dist/consolidation 2/pipeline.d.ts.map +1 -0
  60. package/dist/consolidation 2/pipeline.js +193 -0
  61. package/dist/consolidation 2/pipeline.js.map +1 -0
  62. package/dist/embeddings/client.d.ts +95 -0
  63. package/dist/embeddings/client.d.ts.map +1 -0
  64. package/dist/embeddings/client.js +162 -0
  65. package/dist/embeddings/client.js.map +1 -0
  66. package/dist/embeddings 2/client.d.ts +94 -0
  67. package/dist/embeddings 2/client.d.ts.map +1 -0
  68. package/dist/embeddings 2/client.js +144 -0
  69. package/dist/embeddings 2/client.js.map +1 -0
  70. package/dist/memory-layers/semantic-memory.d.ts +76 -0
  71. package/dist/memory-layers/semantic-memory.d.ts.map +1 -0
  72. package/dist/memory-layers/semantic-memory.js +231 -0
  73. package/dist/memory-layers/semantic-memory.js.map +1 -0
  74. package/dist/memory-layers/skill-library.d.ts +25 -0
  75. package/dist/memory-layers/skill-library.d.ts.map +1 -0
  76. package/dist/memory-layers/skill-library.js +54 -0
  77. package/dist/memory-layers/skill-library.js.map +1 -0
  78. package/dist/memory-layers/working-memory.d.ts +57 -0
  79. package/dist/memory-layers/working-memory.d.ts.map +1 -0
  80. package/dist/memory-layers/working-memory.js +153 -0
  81. package/dist/memory-layers/working-memory.js.map +1 -0
  82. package/dist/memory-layers 2/semantic-memory.d.ts +33 -0
  83. package/dist/memory-layers 2/semantic-memory.d.ts.map +1 -0
  84. package/dist/memory-layers 2/semantic-memory.js +114 -0
  85. package/dist/memory-layers 2/semantic-memory.js.map +1 -0
  86. package/dist/memory-layers 2/skill-library.d.ts +25 -0
  87. package/dist/memory-layers 2/skill-library.d.ts.map +1 -0
  88. package/dist/memory-layers 2/skill-library.js +54 -0
  89. package/dist/memory-layers 2/skill-library.js.map +1 -0
  90. package/dist/memory-layers 2/working-memory.d.ts +57 -0
  91. package/dist/memory-layers 2/working-memory.d.ts.map +1 -0
  92. package/dist/memory-layers 2/working-memory.js +153 -0
  93. package/dist/memory-layers 2/working-memory.js.map +1 -0
  94. package/dist/middleware/auth.d.ts +287 -0
  95. package/dist/middleware/auth.d.ts.map +1 -0
  96. package/dist/middleware/auth.js +610 -0
  97. package/dist/middleware/auth.js.map +1 -0
  98. package/dist/middleware 2/auth.d.ts +287 -0
  99. package/dist/middleware 2/auth.d.ts.map +1 -0
  100. package/dist/middleware 2/auth.js +610 -0
  101. package/dist/middleware 2/auth.js.map +1 -0
  102. package/dist/monitoring/health.d.ts +241 -0
  103. package/dist/monitoring/health.d.ts.map +1 -0
  104. package/dist/monitoring/health.js +649 -0
  105. package/dist/monitoring/health.js.map +1 -0
  106. package/dist/monitoring/metrics.d.ts +153 -0
  107. package/dist/monitoring/metrics.d.ts.map +1 -0
  108. package/dist/monitoring/metrics.js +349 -0
  109. package/dist/monitoring/metrics.js.map +1 -0
  110. package/dist/monitoring 2/health.d.ts +241 -0
  111. package/dist/monitoring 2/health.d.ts.map +1 -0
  112. package/dist/monitoring 2/health.js +649 -0
  113. package/dist/monitoring 2/health.js.map +1 -0
  114. package/dist/monitoring 2/metrics.d.ts +153 -0
  115. package/dist/monitoring 2/metrics.d.ts.map +1 -0
  116. package/dist/monitoring 2/metrics.js +349 -0
  117. package/dist/monitoring 2/metrics.js.map +1 -0
  118. package/dist/retrieval/hybrid-search.d.ts +186 -0
  119. package/dist/retrieval/hybrid-search.d.ts.map +1 -0
  120. package/dist/retrieval/hybrid-search.js +330 -0
  121. package/dist/retrieval/hybrid-search.js.map +1 -0
  122. package/dist/retrieval 2/hybrid-search.d.ts +186 -0
  123. package/dist/retrieval 2/hybrid-search.d.ts.map +1 -0
  124. package/dist/retrieval 2/hybrid-search.js +327 -0
  125. package/dist/retrieval 2/hybrid-search.js.map +1 -0
  126. package/dist/router/smart-router.d.ts +157 -0
  127. package/dist/router/smart-router.d.ts.map +1 -0
  128. package/dist/router/smart-router.js +524 -0
  129. package/dist/router/smart-router.js.map +1 -0
  130. package/dist/router 2/smart-router.d.ts +111 -0
  131. package/dist/router 2/smart-router.d.ts.map +1 -0
  132. package/dist/router 2/smart-router.js +383 -0
  133. package/dist/router 2/smart-router.js.map +1 -0
  134. package/dist/security/rate-limit-middleware.d.ts +119 -0
  135. package/dist/security/rate-limit-middleware.d.ts.map +1 -0
  136. package/dist/security/rate-limit-middleware.js +193 -0
  137. package/dist/security/rate-limit-middleware.js.map +1 -0
  138. package/dist/security 2/rate-limit-middleware.d.ts +119 -0
  139. package/dist/security 2/rate-limit-middleware.d.ts.map +1 -0
  140. package/dist/security 2/rate-limit-middleware.js +193 -0
  141. package/dist/security 2/rate-limit-middleware.js.map +1 -0
  142. package/dist/server 2.js +861 -0
  143. package/dist/server-wrapper 2.js +170 -0
  144. package/dist/server-wrapper.d 2.ts +12 -0
  145. package/dist/server-wrapper.d.ts +12 -0
  146. package/dist/server-wrapper.d.ts 2.map +1 -0
  147. package/dist/server-wrapper.d.ts.map +1 -0
  148. package/dist/server-wrapper.js +170 -0
  149. package/dist/server-wrapper.js 2.map +1 -0
  150. package/dist/server-wrapper.js.map +1 -0
  151. package/dist/server.d 2.ts +14 -0
  152. package/dist/server.d.ts +14 -0
  153. package/dist/server.d.ts 2.map +1 -0
  154. package/dist/server.d.ts.map +1 -0
  155. package/dist/server.js +656 -0
  156. package/dist/server.js 2.map +1 -0
  157. package/dist/server.js.map +1 -0
  158. package/dist/synthesis/conflict-detector.d.ts +43 -0
  159. package/dist/synthesis/conflict-detector.d.ts.map +1 -0
  160. package/dist/synthesis/conflict-detector.js +125 -0
  161. package/dist/synthesis/conflict-detector.js.map +1 -0
  162. package/dist/synthesis 2/conflict-detector.d.ts +43 -0
  163. package/dist/synthesis 2/conflict-detector.d.ts.map +1 -0
  164. package/dist/synthesis 2/conflict-detector.js +125 -0
  165. package/dist/synthesis 2/conflict-detector.js.map +1 -0
  166. package/dist/utils/monitoring.d.ts +25 -0
  167. package/dist/utils/monitoring.d.ts.map +1 -0
  168. package/dist/utils/monitoring.js +41 -0
  169. package/dist/utils/monitoring.js.map +1 -0
  170. package/dist/utils/rate-limiter.d.ts +97 -0
  171. package/dist/utils/rate-limiter.d.ts.map +1 -0
  172. package/dist/utils/rate-limiter.js +166 -0
  173. package/dist/utils/rate-limiter.js.map +1 -0
  174. package/dist/utils/validation.d.ts +139 -0
  175. package/dist/utils/validation.d.ts.map +1 -0
  176. package/dist/utils/validation.js +195 -0
  177. package/dist/utils/validation.js.map +1 -0
  178. package/dist/utils 2/monitoring.d.ts +25 -0
  179. package/dist/utils 2/monitoring.d.ts.map +1 -0
  180. package/dist/utils 2/monitoring.js +41 -0
  181. package/dist/utils 2/monitoring.js.map +1 -0
  182. package/dist/utils 2/rate-limiter.d.ts +97 -0
  183. package/dist/utils 2/rate-limiter.d.ts.map +1 -0
  184. package/dist/utils 2/rate-limiter.js +166 -0
  185. package/dist/utils 2/rate-limiter.js.map +1 -0
  186. package/dist/utils 2/validation.d.ts +139 -0
  187. package/dist/utils 2/validation.d.ts.map +1 -0
  188. package/dist/utils 2/validation.js +195 -0
  189. package/dist/utils 2/validation.js.map +1 -0
  190. package/docker-compose.yml +65 -0
  191. package/embedding-service/Dockerfile +29 -0
  192. package/embedding-service/README.md +68 -0
  193. package/embedding-service/requirements.txt +6 -0
  194. package/embedding-service/server.py +110 -0
  195. package/package.json +92 -0
  196. package/scripts/FRESH_INSTALL.md +280 -0
  197. package/scripts/README.md +101 -0
  198. package/scripts/ensure-infrastructure.sh +38 -0
  199. package/scripts/fresh-install-auto.sh +96 -0
  200. package/scripts/fresh-install.sh +167 -0
  201. package/scripts/health-check.sh +72 -0
  202. package/scripts/init-qdrant.ts +201 -0
  203. package/scripts/postinstall.js +94 -0
  204. package/scripts/run-accuracy-benchmark.ts +1237 -0
  205. package/scripts/run-real-benchmark.ts +581 -0
  206. 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"}