@traqr/memory 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +135 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/auth.d.ts +18 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +31 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/auto-derive.d.ts +35 -0
- package/dist/lib/auto-derive.js +261 -0
- package/dist/lib/auto-derive.js.map +1 -0
- package/dist/lib/borderline.d.ts +26 -0
- package/dist/lib/borderline.js +121 -0
- package/dist/lib/borderline.js.map +1 -0
- package/dist/lib/client.d.ts +28 -0
- package/dist/lib/client.d.ts.map +1 -0
- package/dist/lib/client.js +60 -0
- package/dist/lib/client.js.map +1 -0
- package/dist/lib/context.d.ts +38 -0
- package/dist/lib/context.d.ts.map +1 -0
- package/dist/lib/context.js +334 -0
- package/dist/lib/context.js.map +1 -0
- package/dist/lib/embeddings.d.ts +60 -0
- package/dist/lib/embeddings.d.ts.map +1 -0
- package/dist/lib/embeddings.js +229 -0
- package/dist/lib/embeddings.js.map +1 -0
- package/dist/lib/entity-pipeline.d.ts +23 -0
- package/dist/lib/entity-pipeline.js +151 -0
- package/dist/lib/entity-pipeline.js.map +1 -0
- package/dist/lib/formatting.d.ts +13 -0
- package/dist/lib/formatting.d.ts.map +1 -0
- package/dist/lib/formatting.js +60 -0
- package/dist/lib/formatting.js.map +1 -0
- package/dist/lib/learning-extractor.d.ts +144 -0
- package/dist/lib/learning-extractor.d.ts.map +1 -0
- package/dist/lib/learning-extractor.js +921 -0
- package/dist/lib/learning-extractor.js.map +1 -0
- package/dist/lib/lifecycle.d.ts +45 -0
- package/dist/lib/lifecycle.js +84 -0
- package/dist/lib/lifecycle.js.map +1 -0
- package/dist/lib/memory.d.ts +128 -0
- package/dist/lib/memory.d.ts.map +1 -0
- package/dist/lib/memory.js +590 -0
- package/dist/lib/memory.js.map +1 -0
- package/dist/lib/quality-gate.d.ts +32 -0
- package/dist/lib/quality-gate.js +158 -0
- package/dist/lib/quality-gate.js.map +1 -0
- package/dist/lib/quality-gate.test.d.ts +7 -0
- package/dist/lib/quality-gate.test.js +75 -0
- package/dist/lib/quality-gate.test.js.map +1 -0
- package/dist/lib/rerank.d.ts +22 -0
- package/dist/lib/rerank.js +61 -0
- package/dist/lib/rerank.js.map +1 -0
- package/dist/lib/retrieval.d.ts +75 -0
- package/dist/lib/retrieval.js +380 -0
- package/dist/lib/retrieval.js.map +1 -0
- package/dist/migrate.d.ts +17 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +81 -0
- package/dist/migrate.js.map +1 -0
- package/dist/routes/analyze-codebase.d.ts +9 -0
- package/dist/routes/analyze-codebase.d.ts.map +1 -0
- package/dist/routes/analyze-codebase.js +70 -0
- package/dist/routes/analyze-codebase.js.map +1 -0
- package/dist/routes/analyze-voice.d.ts +9 -0
- package/dist/routes/analyze-voice.d.ts.map +1 -0
- package/dist/routes/analyze-voice.js +63 -0
- package/dist/routes/analyze-voice.js.map +1 -0
- package/dist/routes/assemble-context.d.ts +9 -0
- package/dist/routes/assemble-context.d.ts.map +1 -0
- package/dist/routes/assemble-context.js +68 -0
- package/dist/routes/assemble-context.js.map +1 -0
- package/dist/routes/bootstrap.d.ts +12 -0
- package/dist/routes/bootstrap.d.ts.map +1 -0
- package/dist/routes/bootstrap.js +102 -0
- package/dist/routes/bootstrap.js.map +1 -0
- package/dist/routes/browse.d.ts +11 -0
- package/dist/routes/browse.js +85 -0
- package/dist/routes/browse.js.map +1 -0
- package/dist/routes/capture-thought.d.ts +13 -0
- package/dist/routes/capture-thought.d.ts.map +1 -0
- package/dist/routes/capture-thought.js +178 -0
- package/dist/routes/capture-thought.js.map +1 -0
- package/dist/routes/capture.d.ts +13 -0
- package/dist/routes/capture.d.ts.map +1 -0
- package/dist/routes/capture.js +86 -0
- package/dist/routes/capture.js.map +1 -0
- package/dist/routes/cite.d.ts +9 -0
- package/dist/routes/cite.d.ts.map +1 -0
- package/dist/routes/cite.js +49 -0
- package/dist/routes/cite.js.map +1 -0
- package/dist/routes/crud.d.ts +11 -0
- package/dist/routes/crud.d.ts.map +1 -0
- package/dist/routes/crud.js +176 -0
- package/dist/routes/crud.js.map +1 -0
- package/dist/routes/dashboard.d.ts +9 -0
- package/dist/routes/dashboard.d.ts.map +1 -0
- package/dist/routes/dashboard.js +85 -0
- package/dist/routes/dashboard.js.map +1 -0
- package/dist/routes/entity-cron.d.ts +8 -0
- package/dist/routes/entity-cron.js +31 -0
- package/dist/routes/entity-cron.js.map +1 -0
- package/dist/routes/export.d.ts +8 -0
- package/dist/routes/export.d.ts.map +1 -0
- package/dist/routes/export.js +69 -0
- package/dist/routes/export.js.map +1 -0
- package/dist/routes/extract-pr-learnings.d.ts +12 -0
- package/dist/routes/extract-pr-learnings.d.ts.map +1 -0
- package/dist/routes/extract-pr-learnings.js +127 -0
- package/dist/routes/extract-pr-learnings.js.map +1 -0
- package/dist/routes/forget-cron.d.ts +9 -0
- package/dist/routes/forget-cron.js +30 -0
- package/dist/routes/forget-cron.js.map +1 -0
- package/dist/routes/learnings.d.ts +9 -0
- package/dist/routes/learnings.d.ts.map +1 -0
- package/dist/routes/learnings.js +237 -0
- package/dist/routes/learnings.js.map +1 -0
- package/dist/routes/pulse.d.ts +9 -0
- package/dist/routes/pulse.d.ts.map +1 -0
- package/dist/routes/pulse.js +133 -0
- package/dist/routes/pulse.js.map +1 -0
- package/dist/routes/search.d.ts +8 -0
- package/dist/routes/search.d.ts.map +1 -0
- package/dist/routes/search.js +107 -0
- package/dist/routes/search.js.map +1 -0
- package/dist/routes/store.d.ts +8 -0
- package/dist/routes/store.d.ts.map +1 -0
- package/dist/routes/store.js +89 -0
- package/dist/routes/store.js.map +1 -0
- package/dist/routes/sync.d.ts +12 -0
- package/dist/routes/sync.d.ts.map +1 -0
- package/dist/routes/sync.js +83 -0
- package/dist/routes/sync.js.map +1 -0
- package/dist/routes/voice-profile.d.ts +9 -0
- package/dist/routes/voice-profile.d.ts.map +1 -0
- package/dist/routes/voice-profile.js +124 -0
- package/dist/routes/voice-profile.js.map +1 -0
- package/dist/server.d.ts +37 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +99 -0
- package/dist/server.js.map +1 -0
- package/dist/vectordb/index.d.ts +17 -0
- package/dist/vectordb/index.d.ts.map +1 -0
- package/dist/vectordb/index.js +39 -0
- package/dist/vectordb/index.js.map +1 -0
- package/dist/vectordb/supabase.d.ts +62 -0
- package/dist/vectordb/supabase.d.ts.map +1 -0
- package/dist/vectordb/supabase.js +711 -0
- package/dist/vectordb/supabase.js.map +1 -0
- package/dist/vectordb/types.d.ts +217 -0
- package/dist/vectordb/types.d.ts.map +1 -0
- package/dist/vectordb/types.js +28 -0
- package/dist/vectordb/types.js.map +1 -0
- package/package.json +49 -0
- package/setup.sql +1037 -0
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Strategy Retrieval + RRF Fusion
|
|
3
|
+
*
|
|
4
|
+
* SearchOrchestrator for Memory Engine v2.
|
|
5
|
+
* Combines semantic, BM25, temporal, and graph search via
|
|
6
|
+
* Reciprocal Rank Fusion. Replaces single-strategy semantic search.
|
|
7
|
+
*/
|
|
8
|
+
import { getVectorDB } from '../vectordb/index.js';
|
|
9
|
+
import { SupabaseVectorProvider } from '../vectordb/supabase.js';
|
|
10
|
+
import { generateEmbedding, formatEmbeddingForPgVector } from './embeddings.js';
|
|
11
|
+
import { cohereRerank } from './rerank.js';
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Reciprocal Rank Fusion (TD-158)
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
/**
|
|
16
|
+
* Fuse ranked results from multiple search strategies via RRF.
|
|
17
|
+
*
|
|
18
|
+
* For each item across all strategies: score += 1/(k + rank)
|
|
19
|
+
* Items appearing in multiple strategies accumulate higher scores.
|
|
20
|
+
*
|
|
21
|
+
* @param strategyResults - Ranked results from each strategy
|
|
22
|
+
* @param k - RRF constant (default 60, standard in literature)
|
|
23
|
+
* @param topN - Max results to return
|
|
24
|
+
*/
|
|
25
|
+
export function reciprocalRankFusion(strategyResults, k = 60, topN = 20) {
|
|
26
|
+
const scoreMap = new Map();
|
|
27
|
+
for (const sr of strategyResults) {
|
|
28
|
+
for (const item of sr.items) {
|
|
29
|
+
const existing = scoreMap.get(item.id) || { rrfScore: 0, strategies: [] };
|
|
30
|
+
existing.rrfScore += 1 / (k + item.rank);
|
|
31
|
+
existing.strategies.push(sr.strategy);
|
|
32
|
+
scoreMap.set(item.id, existing);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const sorted = [...scoreMap.entries()]
|
|
36
|
+
.map(([id, { rrfScore, strategies }]) => ({
|
|
37
|
+
id,
|
|
38
|
+
rrfScore,
|
|
39
|
+
normalizedScore: 0,
|
|
40
|
+
strategies,
|
|
41
|
+
}))
|
|
42
|
+
.sort((a, b) => b.rrfScore - a.rrfScore)
|
|
43
|
+
.slice(0, topN);
|
|
44
|
+
// Normalize to 0-1 range
|
|
45
|
+
const maxScore = sorted.length > 0 ? sorted[0].rrfScore : 1;
|
|
46
|
+
for (const item of sorted) {
|
|
47
|
+
item.normalizedScore = maxScore > 0 ? item.rrfScore / maxScore : 0;
|
|
48
|
+
}
|
|
49
|
+
return sorted;
|
|
50
|
+
}
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// Strategy Detection (TD-159)
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
const DATE_PATTERNS = [
|
|
55
|
+
/\b(yesterday|today|last\s+(week|month|day|year))\b/i,
|
|
56
|
+
/\b(this\s+(week|month|year))\b/i,
|
|
57
|
+
/\b\d{4}-\d{2}(-\d{2})?\b/, // 2026-03-15 or 2026-03
|
|
58
|
+
/\b(january|february|march|april|may|june|july|august|september|october|november|december)\s+\d{4}\b/i,
|
|
59
|
+
/\b(in\s+\d{4})\b/i, // "in 2020"
|
|
60
|
+
/\b(\d+\s+(days?|weeks?|months?|years?)\s+ago)\b/i, // "3 months ago"
|
|
61
|
+
/\b(recent(ly)?|lately|earlier)\b/i,
|
|
62
|
+
];
|
|
63
|
+
/**
|
|
64
|
+
* Detect which search strategies should be activated for a query.
|
|
65
|
+
* Semantic + BM25 always run. Temporal activates on date patterns.
|
|
66
|
+
* Graph activates when entity seed IDs are provided.
|
|
67
|
+
*/
|
|
68
|
+
export function detectStrategies(query, entityIds) {
|
|
69
|
+
const strategies = ['semantic', 'bm25'];
|
|
70
|
+
const hasDatePattern = DATE_PATTERNS.some((p) => p.test(query));
|
|
71
|
+
let temporalRange;
|
|
72
|
+
if (hasDatePattern) {
|
|
73
|
+
strategies.push('temporal');
|
|
74
|
+
temporalRange = parseTemporalRange(query);
|
|
75
|
+
}
|
|
76
|
+
if (entityIds && entityIds.length > 0) {
|
|
77
|
+
strategies.push('graph');
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
strategies,
|
|
81
|
+
temporalRange,
|
|
82
|
+
graphSeedIds: entityIds,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Parse temporal references in a query to a date range.
|
|
87
|
+
* Falls back to 30-day lookback for ambiguous patterns.
|
|
88
|
+
*/
|
|
89
|
+
export function parseTemporalRange(query) {
|
|
90
|
+
const now = new Date();
|
|
91
|
+
const end = now;
|
|
92
|
+
// "yesterday"
|
|
93
|
+
if (/\byesterday\b/i.test(query)) {
|
|
94
|
+
const start = new Date(now);
|
|
95
|
+
start.setDate(start.getDate() - 1);
|
|
96
|
+
start.setHours(0, 0, 0, 0);
|
|
97
|
+
return { start, end };
|
|
98
|
+
}
|
|
99
|
+
// "last week/month/year"
|
|
100
|
+
const lastMatch = query.match(/\blast\s+(week|month|year|day)\b/i);
|
|
101
|
+
if (lastMatch) {
|
|
102
|
+
const start = new Date(now);
|
|
103
|
+
switch (lastMatch[1].toLowerCase()) {
|
|
104
|
+
case 'day':
|
|
105
|
+
start.setDate(start.getDate() - 1);
|
|
106
|
+
break;
|
|
107
|
+
case 'week':
|
|
108
|
+
start.setDate(start.getDate() - 7);
|
|
109
|
+
break;
|
|
110
|
+
case 'month':
|
|
111
|
+
start.setMonth(start.getMonth() - 1);
|
|
112
|
+
break;
|
|
113
|
+
case 'year':
|
|
114
|
+
start.setFullYear(start.getFullYear() - 1);
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
return { start, end };
|
|
118
|
+
}
|
|
119
|
+
// "N days/weeks/months/years ago"
|
|
120
|
+
const agoMatch = query.match(/\b(\d+)\s+(days?|weeks?|months?|years?)\s+ago\b/i);
|
|
121
|
+
if (agoMatch) {
|
|
122
|
+
const n = parseInt(agoMatch[1], 10);
|
|
123
|
+
const unit = agoMatch[2].toLowerCase().replace(/s$/, '');
|
|
124
|
+
const start = new Date(now);
|
|
125
|
+
switch (unit) {
|
|
126
|
+
case 'day':
|
|
127
|
+
start.setDate(start.getDate() - n);
|
|
128
|
+
break;
|
|
129
|
+
case 'week':
|
|
130
|
+
start.setDate(start.getDate() - n * 7);
|
|
131
|
+
break;
|
|
132
|
+
case 'month':
|
|
133
|
+
start.setMonth(start.getMonth() - n);
|
|
134
|
+
break;
|
|
135
|
+
case 'year':
|
|
136
|
+
start.setFullYear(start.getFullYear() - n);
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
return { start, end };
|
|
140
|
+
}
|
|
141
|
+
// "March 2026" or "in 2026"
|
|
142
|
+
const monthYearMatch = query.match(/\b(january|february|march|april|may|june|july|august|september|october|november|december)\s+(\d{4})\b/i);
|
|
143
|
+
if (monthYearMatch) {
|
|
144
|
+
const months = {
|
|
145
|
+
january: 0, february: 1, march: 2, april: 3, may: 4, june: 5,
|
|
146
|
+
july: 6, august: 7, september: 8, october: 9, november: 10, december: 11,
|
|
147
|
+
};
|
|
148
|
+
const month = months[monthYearMatch[1].toLowerCase()];
|
|
149
|
+
const year = parseInt(monthYearMatch[2], 10);
|
|
150
|
+
const start = new Date(year, month, 1);
|
|
151
|
+
const monthEnd = new Date(year, month + 1, 0, 23, 59, 59, 999);
|
|
152
|
+
return { start, end: monthEnd };
|
|
153
|
+
}
|
|
154
|
+
// "2026-03-15" or "2026-03"
|
|
155
|
+
const isoMatch = query.match(/\b(\d{4})-(\d{2})(?:-(\d{2}))?\b/);
|
|
156
|
+
if (isoMatch) {
|
|
157
|
+
const year = parseInt(isoMatch[1], 10);
|
|
158
|
+
const month = parseInt(isoMatch[2], 10) - 1;
|
|
159
|
+
if (isoMatch[3]) {
|
|
160
|
+
const day = parseInt(isoMatch[3], 10);
|
|
161
|
+
const start = new Date(year, month, day, 0, 0, 0, 0);
|
|
162
|
+
const dayEnd = new Date(year, month, day, 23, 59, 59, 999);
|
|
163
|
+
return { start, end: dayEnd };
|
|
164
|
+
}
|
|
165
|
+
const start = new Date(year, month, 1);
|
|
166
|
+
const monthEnd = new Date(year, month + 1, 0, 23, 59, 59, 999);
|
|
167
|
+
return { start, end: monthEnd };
|
|
168
|
+
}
|
|
169
|
+
// "in 2020"
|
|
170
|
+
const yearMatch = query.match(/\bin\s+(\d{4})\b/i);
|
|
171
|
+
if (yearMatch) {
|
|
172
|
+
const year = parseInt(yearMatch[1], 10);
|
|
173
|
+
return { start: new Date(year, 0, 1), end: new Date(year, 11, 31, 23, 59, 59, 999) };
|
|
174
|
+
}
|
|
175
|
+
// Default: 30-day lookback
|
|
176
|
+
const start = new Date(now);
|
|
177
|
+
start.setDate(start.getDate() - 30);
|
|
178
|
+
return { start, end };
|
|
179
|
+
}
|
|
180
|
+
// ---------------------------------------------------------------------------
|
|
181
|
+
// Entity Resolution from Query (TD-180)
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
const STOPWORDS = new Set([
|
|
184
|
+
'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
|
|
185
|
+
'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
|
|
186
|
+
'should', 'may', 'might', 'shall', 'can', 'need', 'must',
|
|
187
|
+
'how', 'what', 'when', 'where', 'why', 'who', 'which', 'that', 'this',
|
|
188
|
+
'about', 'with', 'from', 'into', 'for', 'and', 'or', 'but', 'not',
|
|
189
|
+
'of', 'in', 'on', 'at', 'to', 'by', 'up', 'if', 'so', 'no', 'my',
|
|
190
|
+
'i', 'me', 'we', 'you', 'he', 'she', 'it', 'they', 'them', 'our',
|
|
191
|
+
'your', 'his', 'her', 'its', 'their', 'all', 'each', 'any', 'some',
|
|
192
|
+
'say', 'said', 'tell', 'think', 'know', 'use', 'work', 'like',
|
|
193
|
+
]);
|
|
194
|
+
/**
|
|
195
|
+
* Find known entities mentioned in a search query.
|
|
196
|
+
* Tokenizes the query, filters stopwords, looks up against memory_entities.
|
|
197
|
+
* Returns entity IDs for graph search activation.
|
|
198
|
+
*/
|
|
199
|
+
export async function findEntitiesInQuery(query, provider) {
|
|
200
|
+
// Tokenize: split on spaces + punctuation, filter stopwords
|
|
201
|
+
const words = query
|
|
202
|
+
.split(/[\s,.!?;:'"()\[\]{}]+/)
|
|
203
|
+
.map((w) => w.trim())
|
|
204
|
+
.filter((w) => w.length > 1 && !STOPWORDS.has(w.toLowerCase()));
|
|
205
|
+
// Also extract bigrams for multi-word entity names
|
|
206
|
+
const rawWords = query.split(/\s+/);
|
|
207
|
+
const bigrams = [];
|
|
208
|
+
for (let i = 0; i < rawWords.length - 1; i++) {
|
|
209
|
+
bigrams.push(`${rawWords[i]} ${rawWords[i + 1]}`);
|
|
210
|
+
}
|
|
211
|
+
const allTokens = [...new Set([...words, ...bigrams])];
|
|
212
|
+
if (allTokens.length === 0)
|
|
213
|
+
return [];
|
|
214
|
+
try {
|
|
215
|
+
const entities = await provider.findEntitiesByNames(allTokens);
|
|
216
|
+
return entities.map((e) => e.id);
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
return [];
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// ---------------------------------------------------------------------------
|
|
223
|
+
// Search Orchestrator (TD-160)
|
|
224
|
+
// ---------------------------------------------------------------------------
|
|
225
|
+
/**
|
|
226
|
+
* Multi-strategy search with RRF fusion.
|
|
227
|
+
*
|
|
228
|
+
* Runs semantic + BM25 in parallel (always), plus temporal and graph
|
|
229
|
+
* when detected. Fuses results via Reciprocal Rank Fusion.
|
|
230
|
+
* Returns MemorySearchResult[] for backward compatibility.
|
|
231
|
+
*/
|
|
232
|
+
export async function searchMemoriesV2(query, options = {}) {
|
|
233
|
+
const db = getVectorDB();
|
|
234
|
+
// Gate: provider must support v2 methods
|
|
235
|
+
if (!(db instanceof SupabaseVectorProvider)) {
|
|
236
|
+
return db.search(query, options);
|
|
237
|
+
}
|
|
238
|
+
const provider = db;
|
|
239
|
+
const topN = options.limit || 10;
|
|
240
|
+
const k = options.rrfK || 60;
|
|
241
|
+
const overFetchLimit = topN * 2;
|
|
242
|
+
// 0.5 Auto-resolve entities from query (if no explicit entityIds)
|
|
243
|
+
let resolvedEntityIds = options.entityIds || [];
|
|
244
|
+
if (resolvedEntityIds.length === 0) {
|
|
245
|
+
resolvedEntityIds = await findEntitiesInQuery(query, provider);
|
|
246
|
+
}
|
|
247
|
+
// 1. Detect strategies (with resolved entity IDs)
|
|
248
|
+
const detected = options.strategies
|
|
249
|
+
? { strategies: options.strategies, temporalRange: undefined, graphSeedIds: resolvedEntityIds }
|
|
250
|
+
: detectStrategies(query, resolvedEntityIds);
|
|
251
|
+
// 2. Generate embedding ONCE
|
|
252
|
+
const embeddingResult = await generateEmbedding(query);
|
|
253
|
+
const embeddingStr = formatEmbeddingForPgVector(embeddingResult.embedding);
|
|
254
|
+
// 3. Run active strategies in parallel
|
|
255
|
+
// Keep full semantic results for hydration + BM25 content for reranking
|
|
256
|
+
let semanticFullResults = [];
|
|
257
|
+
let bm25ContentMap = new Map();
|
|
258
|
+
const strategyPromises = [];
|
|
259
|
+
if (detected.strategies.includes('semantic')) {
|
|
260
|
+
strategyPromises.push(provider
|
|
261
|
+
.search(query, {
|
|
262
|
+
...options,
|
|
263
|
+
limit: overFetchLimit,
|
|
264
|
+
precomputedEmbedding: embeddingStr,
|
|
265
|
+
})
|
|
266
|
+
.then((results) => {
|
|
267
|
+
semanticFullResults = results;
|
|
268
|
+
return {
|
|
269
|
+
strategy: 'semantic',
|
|
270
|
+
items: results.map((r, i) => ({ id: r.id, rank: i + 1 })),
|
|
271
|
+
};
|
|
272
|
+
})
|
|
273
|
+
.catch((err) => {
|
|
274
|
+
console.warn('[retrieval] Semantic search failed:', err);
|
|
275
|
+
return { strategy: 'semantic', items: [] };
|
|
276
|
+
}));
|
|
277
|
+
}
|
|
278
|
+
if (detected.strategies.includes('bm25')) {
|
|
279
|
+
strategyPromises.push(provider
|
|
280
|
+
.bm25Search(query, {
|
|
281
|
+
category: options.category,
|
|
282
|
+
limit: overFetchLimit,
|
|
283
|
+
})
|
|
284
|
+
.then((results) => {
|
|
285
|
+
bm25ContentMap = new Map(results.map((r) => [r.id, r.content]));
|
|
286
|
+
return {
|
|
287
|
+
strategy: 'bm25',
|
|
288
|
+
items: results.map((r, i) => ({ id: r.id, rank: i + 1 })),
|
|
289
|
+
};
|
|
290
|
+
})
|
|
291
|
+
.catch(() => ({ strategy: 'bm25', items: [] })));
|
|
292
|
+
}
|
|
293
|
+
if (detected.strategies.includes('temporal') && detected.temporalRange) {
|
|
294
|
+
strategyPromises.push(provider
|
|
295
|
+
.temporalSearch(query, detected.temporalRange.start, detected.temporalRange.end, {
|
|
296
|
+
limit: overFetchLimit,
|
|
297
|
+
precomputedEmbedding: embeddingStr,
|
|
298
|
+
})
|
|
299
|
+
.then((results) => ({
|
|
300
|
+
strategy: 'temporal',
|
|
301
|
+
items: results.map((r, i) => ({ id: r.id, rank: i + 1 })),
|
|
302
|
+
}))
|
|
303
|
+
.catch(() => ({ strategy: 'temporal', items: [] })));
|
|
304
|
+
}
|
|
305
|
+
if (detected.strategies.includes('graph') && detected.graphSeedIds?.length) {
|
|
306
|
+
strategyPromises.push(provider
|
|
307
|
+
.graphSearch(detected.graphSeedIds, {
|
|
308
|
+
limit: overFetchLimit,
|
|
309
|
+
})
|
|
310
|
+
.then((results) => ({
|
|
311
|
+
strategy: 'graph',
|
|
312
|
+
items: results.map((r, i) => ({ id: r.id, rank: i + 1 })),
|
|
313
|
+
}))
|
|
314
|
+
.catch(() => ({ strategy: 'graph', items: [] })));
|
|
315
|
+
}
|
|
316
|
+
// 4. Fuse via RRF
|
|
317
|
+
const strategyResults = await Promise.all(strategyPromises);
|
|
318
|
+
// Observability: log when entities activate graph search
|
|
319
|
+
if (resolvedEntityIds.length > 0) {
|
|
320
|
+
const strategyLog = strategyResults.map((sr) => `${sr.strategy}:${sr.items.length}`).join(', ');
|
|
321
|
+
console.log(`[retrieval] q="${query.slice(0, 50)}" strategies=[${strategyLog}] entities=${resolvedEntityIds.length}`);
|
|
322
|
+
}
|
|
323
|
+
const fused = reciprocalRankFusion(strategyResults, k, topN);
|
|
324
|
+
if (fused.length === 0) {
|
|
325
|
+
return [];
|
|
326
|
+
}
|
|
327
|
+
// 4.5 Optional: Cohere rerank (graceful — skips if no API key)
|
|
328
|
+
const rerankDocs = fused.map((f) => ({
|
|
329
|
+
id: f.id,
|
|
330
|
+
content: semanticFullResults.find((r) => r.id === f.id)?.content || bm25ContentMap.get(f.id) || '',
|
|
331
|
+
})).filter((d) => d.content.length > 0);
|
|
332
|
+
if (rerankDocs.length > 0) {
|
|
333
|
+
const reranked = await cohereRerank(query, rerankDocs, topN);
|
|
334
|
+
if (reranked) {
|
|
335
|
+
const rerankMap = new Map(reranked.map((r) => [r.id, r.relevanceScore]));
|
|
336
|
+
for (const item of fused) {
|
|
337
|
+
const cohereScore = rerankMap.get(item.id);
|
|
338
|
+
if (cohereScore !== undefined) {
|
|
339
|
+
item.normalizedScore = cohereScore;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
fused.sort((a, b) => b.normalizedScore - a.normalizedScore);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
// 5. Hydrate: map fused items to full MemorySearchResult
|
|
346
|
+
const semanticMap = new Map(semanticFullResults.map((r) => [r.id, r]));
|
|
347
|
+
const hydratedResults = [];
|
|
348
|
+
const idsToFetch = [];
|
|
349
|
+
for (const item of fused) {
|
|
350
|
+
const semantic = semanticMap.get(item.id);
|
|
351
|
+
if (semantic) {
|
|
352
|
+
hydratedResults.push({
|
|
353
|
+
...semantic,
|
|
354
|
+
relevanceScore: item.normalizedScore,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
idsToFetch.push({ id: item.id, normalizedScore: item.normalizedScore });
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
// Fetch non-semantic results by ID (BM25/graph-only hits)
|
|
362
|
+
if (idsToFetch.length > 0) {
|
|
363
|
+
const fetched = await Promise.all(idsToFetch.map(({ id }) => provider.getById(id).catch(() => null)));
|
|
364
|
+
for (let i = 0; i < fetched.length; i++) {
|
|
365
|
+
const memory = fetched[i];
|
|
366
|
+
if (!memory)
|
|
367
|
+
continue;
|
|
368
|
+
hydratedResults.push({
|
|
369
|
+
...memory,
|
|
370
|
+
currentConfidence: memory.originalConfidence,
|
|
371
|
+
similarity: 0,
|
|
372
|
+
relevanceScore: idsToFetch[i].normalizedScore,
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
// 6. Final sort by RRF score
|
|
377
|
+
hydratedResults.sort((a, b) => b.relevanceScore - a.relevanceScore);
|
|
378
|
+
return hydratedResults.slice(0, topN);
|
|
379
|
+
}
|
|
380
|
+
//# sourceMappingURL=retrieval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retrieval.js","sourceRoot":"","sources":["../../src/lib/retrieval.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration Runner for @traqr/memory
|
|
3
|
+
*
|
|
4
|
+
* Reads SQL migration files from packages/memory/migrations/ and executes
|
|
5
|
+
* them in order against a Supabase database. Tracks applied migrations
|
|
6
|
+
* in a _traqr_migrations table to avoid re-running.
|
|
7
|
+
*
|
|
8
|
+
* Standalone usage:
|
|
9
|
+
* SUPABASE_URL=https://xxx.supabase.co \
|
|
10
|
+
* SUPABASE_SERVICE_ROLE_KEY=eyJ... \
|
|
11
|
+
* npx ts-node packages/memory/src/migrate.ts
|
|
12
|
+
*
|
|
13
|
+
* Requires the `exec_sql` RPC function in your Supabase project.
|
|
14
|
+
* If not available, paste the SQL from .traqr/schema.sql directly
|
|
15
|
+
* into Supabase SQL Editor instead.
|
|
16
|
+
*/
|
|
17
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
|
package/dist/migrate.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration Runner for @traqr/memory
|
|
3
|
+
*
|
|
4
|
+
* Reads SQL migration files from packages/memory/migrations/ and executes
|
|
5
|
+
* them in order against a Supabase database. Tracks applied migrations
|
|
6
|
+
* in a _traqr_migrations table to avoid re-running.
|
|
7
|
+
*
|
|
8
|
+
* Standalone usage:
|
|
9
|
+
* SUPABASE_URL=https://xxx.supabase.co \
|
|
10
|
+
* SUPABASE_SERVICE_ROLE_KEY=eyJ... \
|
|
11
|
+
* npx ts-node packages/memory/src/migrate.ts
|
|
12
|
+
*
|
|
13
|
+
* Requires the `exec_sql` RPC function in your Supabase project.
|
|
14
|
+
* If not available, paste the SQL from .traqr/schema.sql directly
|
|
15
|
+
* into Supabase SQL Editor instead.
|
|
16
|
+
*/
|
|
17
|
+
import { createClient } from '@supabase/supabase-js';
|
|
18
|
+
import { readFileSync, readdirSync } from 'fs';
|
|
19
|
+
import { join, dirname } from 'path';
|
|
20
|
+
import { fileURLToPath } from 'url';
|
|
21
|
+
const MIGRATIONS_TABLE = '_traqr_migrations';
|
|
22
|
+
async function migrate() {
|
|
23
|
+
const supabaseUrl = process.env.SUPABASE_URL || process.env.NEXT_PUBLIC_SUPABASE_URL;
|
|
24
|
+
const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
|
25
|
+
if (!supabaseUrl || !supabaseKey) {
|
|
26
|
+
console.error('Missing required env vars: SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const client = createClient(supabaseUrl, supabaseKey);
|
|
30
|
+
// Ensure migrations tracking table exists
|
|
31
|
+
await client.rpc('exec_sql', {
|
|
32
|
+
sql: `
|
|
33
|
+
CREATE TABLE IF NOT EXISTS ${MIGRATIONS_TABLE} (
|
|
34
|
+
name TEXT PRIMARY KEY,
|
|
35
|
+
applied_at TIMESTAMPTZ DEFAULT NOW()
|
|
36
|
+
);
|
|
37
|
+
`,
|
|
38
|
+
}).then(({ error }) => {
|
|
39
|
+
if (error) {
|
|
40
|
+
// If RPC doesn't exist, try raw query via REST
|
|
41
|
+
console.warn('exec_sql RPC not available, attempting direct execution...');
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
// Find migration files
|
|
45
|
+
const migrationsDir = join(dirname(fileURLToPath(import.meta.url)), '..', 'migrations');
|
|
46
|
+
const files = readdirSync(migrationsDir)
|
|
47
|
+
.filter(f => f.endsWith('.sql'))
|
|
48
|
+
.sort();
|
|
49
|
+
console.log(`Found ${files.length} migration files`);
|
|
50
|
+
// Check which have been applied
|
|
51
|
+
const { data: applied } = await client
|
|
52
|
+
.from(MIGRATIONS_TABLE)
|
|
53
|
+
.select('name');
|
|
54
|
+
const appliedSet = new Set((applied || []).map(r => r.name));
|
|
55
|
+
let appliedCount = 0;
|
|
56
|
+
let skippedCount = 0;
|
|
57
|
+
for (const file of files) {
|
|
58
|
+
if (appliedSet.has(file)) {
|
|
59
|
+
console.log(` SKIP ${file} (already applied)`);
|
|
60
|
+
skippedCount++;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const sql = readFileSync(join(migrationsDir, file), 'utf-8');
|
|
64
|
+
console.log(` RUN ${file}...`);
|
|
65
|
+
const { error } = await client.rpc('exec_sql', { sql });
|
|
66
|
+
if (error) {
|
|
67
|
+
console.error(` FAIL ${file}: ${error.message}`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
// Record migration
|
|
71
|
+
await client.from(MIGRATIONS_TABLE).insert({ name: file });
|
|
72
|
+
appliedCount++;
|
|
73
|
+
console.log(` OK ${file}`);
|
|
74
|
+
}
|
|
75
|
+
console.log(`\nDone: ${appliedCount} applied, ${skippedCount} skipped`);
|
|
76
|
+
}
|
|
77
|
+
migrate().catch(err => {
|
|
78
|
+
console.error('Migration failed:', err);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
});
|
|
81
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codebase Analysis Route (Portable)
|
|
3
|
+
*
|
|
4
|
+
* POST /analyze-codebase — Accepts file samples, extracts design preferences
|
|
5
|
+
* and coding conventions via LLM, stores in memory.
|
|
6
|
+
*/
|
|
7
|
+
import { Hono } from 'hono';
|
|
8
|
+
declare const app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
9
|
+
export default app;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze-codebase.d.ts","sourceRoot":"","sources":["../../src/routes/analyze-codebase.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAW3B,QAAA,MAAM,GAAG,4EAAa,CAAA;AA2EtB,eAAe,GAAG,CAAA"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codebase Analysis Route (Portable)
|
|
3
|
+
*
|
|
4
|
+
* POST /analyze-codebase — Accepts file samples, extracts design preferences
|
|
5
|
+
* and coding conventions via LLM, stores in memory.
|
|
6
|
+
*/
|
|
7
|
+
import { Hono } from 'hono';
|
|
8
|
+
import { extractFromCodebaseAnalysis } from '../lib/learning-extractor.js';
|
|
9
|
+
const VALID_ANALYSIS_TYPES = [
|
|
10
|
+
'component-patterns', 'design-system', 'state-management',
|
|
11
|
+
'error-handling', 'api-patterns', 'naming-conventions',
|
|
12
|
+
'typescript-patterns', 'animation-patterns', 'layout-patterns',
|
|
13
|
+
'performance-patterns', 'full',
|
|
14
|
+
];
|
|
15
|
+
const app = new Hono();
|
|
16
|
+
app.post('/', async (c) => {
|
|
17
|
+
try {
|
|
18
|
+
const body = await c.req.json();
|
|
19
|
+
if (!body.analyses || !Array.isArray(body.analyses) || body.analyses.length === 0) {
|
|
20
|
+
return c.json({ success: false, error: 'analyses array is required and must not be empty' }, 400);
|
|
21
|
+
}
|
|
22
|
+
for (const analysis of body.analyses) {
|
|
23
|
+
if (!analysis.analysisType || !VALID_ANALYSIS_TYPES.includes(analysis.analysisType)) {
|
|
24
|
+
return c.json({ success: false, error: `Invalid analysisType: ${analysis.analysisType}. Must be one of: ${VALID_ANALYSIS_TYPES.join(', ')}` }, 400);
|
|
25
|
+
}
|
|
26
|
+
if (!analysis.fileSamples || !Array.isArray(analysis.fileSamples) || analysis.fileSamples.length === 0) {
|
|
27
|
+
return c.json({ success: false, error: `fileSamples required for analysisType: ${analysis.analysisType}` }, 400);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
let totalStored = 0;
|
|
31
|
+
let totalDeduplicated = 0;
|
|
32
|
+
const allErrors = [];
|
|
33
|
+
const byType = {};
|
|
34
|
+
for (const analysis of body.analyses) {
|
|
35
|
+
const context = {
|
|
36
|
+
analysisType: analysis.analysisType,
|
|
37
|
+
fileSamples: analysis.fileSamples.map((f) => ({
|
|
38
|
+
path: f.path,
|
|
39
|
+
content: String(f.content).slice(0, 4500),
|
|
40
|
+
})),
|
|
41
|
+
configFiles: analysis.configFiles?.map((f) => ({
|
|
42
|
+
path: f.path,
|
|
43
|
+
content: String(f.content).slice(0, 3000),
|
|
44
|
+
})),
|
|
45
|
+
};
|
|
46
|
+
const result = await extractFromCodebaseAnalysis(context);
|
|
47
|
+
totalStored += result.memoriesStored;
|
|
48
|
+
totalDeduplicated += result.memoriesDeduplicated;
|
|
49
|
+
allErrors.push(...result.errors);
|
|
50
|
+
byType[analysis.analysisType] = {
|
|
51
|
+
stored: result.memoriesStored,
|
|
52
|
+
deduplicated: result.memoriesDeduplicated,
|
|
53
|
+
learnings: result.learnings.length,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return c.json({
|
|
57
|
+
success: true,
|
|
58
|
+
totalStored,
|
|
59
|
+
totalDeduplicated,
|
|
60
|
+
byType,
|
|
61
|
+
errors: allErrors,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.error('[Memory Analyze Codebase] Error:', error);
|
|
66
|
+
return c.json({ success: false, error: error instanceof Error ? error.message : 'Unknown error analyzing codebase' }, 500);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
export default app;
|
|
70
|
+
//# sourceMappingURL=analyze-codebase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze-codebase.js","sourceRoot":"","sources":["../../src/routes/analyze-codebase.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Voice Analysis Route (Portable)
|
|
3
|
+
*
|
|
4
|
+
* POST /analyze-voice — Accepts writing samples, extracts voice traits
|
|
5
|
+
* via LLM, and stores them as preference memories with voice tags.
|
|
6
|
+
*/
|
|
7
|
+
import { Hono } from 'hono';
|
|
8
|
+
declare const app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
9
|
+
export default app;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze-voice.d.ts","sourceRoot":"","sources":["../../src/routes/analyze-voice.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAQ3B,QAAA,MAAM,GAAG,4EAAa,CAAA;AAuEtB,eAAe,GAAG,CAAA"}
|