pmem-ai 0.7.6 → 0.8.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/CHANGELOG.md +14 -0
- package/README.md +6 -4
- package/dist/commands/ask.d.ts +5 -1
- package/dist/commands/ask.d.ts.map +1 -1
- package/dist/commands/ask.js +48 -240
- package/dist/commands/ask.js.map +1 -1
- package/dist/commands/rebuild.d.ts.map +1 -1
- package/dist/commands/rebuild.js +74 -10
- package/dist/commands/rebuild.js.map +1 -1
- package/dist/commands/recall.d.ts +1 -0
- package/dist/commands/recall.d.ts.map +1 -1
- package/dist/commands/recall.js +1 -1
- package/dist/commands/recall.js.map +1 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +30 -1
- package/dist/commands/verify.js.map +1 -1
- package/dist/core/db.d.ts +13 -0
- package/dist/core/db.d.ts.map +1 -1
- package/dist/core/db.js +36 -0
- package/dist/core/db.js.map +1 -1
- package/dist/core/format.d.ts.map +1 -1
- package/dist/core/format.js +37 -0
- package/dist/core/format.js.map +1 -1
- package/dist/core/query/ask.d.ts +14 -3
- package/dist/core/query/ask.d.ts.map +1 -1
- package/dist/core/query/ask.js +60 -200
- package/dist/core/query/ask.js.map +1 -1
- package/dist/core/query/context.d.ts.map +1 -1
- package/dist/core/query/context.js +8 -2
- package/dist/core/query/context.js.map +1 -1
- package/dist/core/query/engine/candidates.d.ts +11 -0
- package/dist/core/query/engine/candidates.d.ts.map +1 -0
- package/dist/core/query/engine/candidates.js +207 -0
- package/dist/core/query/engine/candidates.js.map +1 -0
- package/dist/core/query/engine/intent.d.ts +14 -0
- package/dist/core/query/engine/intent.d.ts.map +1 -0
- package/dist/core/query/engine/intent.js +53 -0
- package/dist/core/query/engine/intent.js.map +1 -0
- package/dist/core/query/engine/pack.d.ts +33 -0
- package/dist/core/query/engine/pack.d.ts.map +1 -0
- package/dist/core/query/engine/pack.js +92 -0
- package/dist/core/query/engine/pack.js.map +1 -0
- package/dist/core/query/engine/scoring.d.ts +50 -0
- package/dist/core/query/engine/scoring.d.ts.map +1 -0
- package/dist/core/query/engine/scoring.js +132 -0
- package/dist/core/query/engine/scoring.js.map +1 -0
- package/dist/index.js +15 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +2 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/v0.8 pre-design.md +203 -0
- package/package.json +2 -2
- package/skills/pmem/SKILL.md +4 -2
package/dist/core/query/ask.js
CHANGED
|
@@ -38,219 +38,79 @@ const path = __importStar(require("path"));
|
|
|
38
38
|
const fs_1 = require("../fs");
|
|
39
39
|
const db_1 = require("../db");
|
|
40
40
|
const manifest_1 = require("../manifest");
|
|
41
|
-
|
|
41
|
+
const intent_1 = require("./engine/intent");
|
|
42
|
+
const candidates_1 = require("./engine/candidates");
|
|
43
|
+
const scoring_1 = require("./engine/scoring");
|
|
44
|
+
const CHANNEL_TO_MATCH_TYPE = {
|
|
45
|
+
exact_id: 'exact_id',
|
|
46
|
+
id_substring: 'exact_title',
|
|
47
|
+
exact_title: 'exact_title',
|
|
48
|
+
title_phrase: 'exact_title',
|
|
49
|
+
title_token: 'exact_title',
|
|
50
|
+
alias: 'alias',
|
|
51
|
+
tag: 'tag',
|
|
52
|
+
tag_token: 'tag',
|
|
53
|
+
source_file: 'source_file',
|
|
54
|
+
source_file_prefix: 'source_file',
|
|
55
|
+
fts: 'keyword_fallback',
|
|
56
|
+
like: 'keyword_fallback',
|
|
57
|
+
graph: 'graph_expansion',
|
|
58
|
+
};
|
|
59
|
+
function askQuery(pmemPath, query, options = {}) {
|
|
42
60
|
const dbPath = path.join(pmemPath, 'pmem.db');
|
|
43
61
|
if (!(0, fs_1.fileExists)(dbPath)) {
|
|
44
62
|
throw new Error('No SQLite database found. Run `pmem rebuild` first.');
|
|
45
63
|
}
|
|
46
64
|
const db = (0, db_1.openDatabase)(pmemPath);
|
|
47
65
|
(0, db_1.createSchema)(db);
|
|
48
|
-
const normalizedQuery = query.toLowerCase().trim();
|
|
49
|
-
const queryTokens = tokenize(normalizedQuery);
|
|
50
|
-
const matches = [];
|
|
51
|
-
const seenIds = new Set();
|
|
52
|
-
// Step 1: Exact match — card ID
|
|
53
|
-
const idMatches = db.prepare("SELECT * FROM cards WHERE (id = ? OR id LIKE ?) AND is_deleted = 0").all(normalizedQuery, `%${normalizedQuery}%`);
|
|
54
|
-
for (const card of idMatches) {
|
|
55
|
-
if (seenIds.has(card.id))
|
|
56
|
-
continue;
|
|
57
|
-
seenIds.add(card.id);
|
|
58
|
-
matches.push({
|
|
59
|
-
id: card.id,
|
|
60
|
-
title: card.title,
|
|
61
|
-
match_type: card.id === normalizedQuery ? 'exact_id' : 'exact_title',
|
|
62
|
-
confidence: card.id === normalizedQuery ? 0.95 : 0.85,
|
|
63
|
-
graph_distance: 0,
|
|
64
|
-
file: card.file_path,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
// Step 2: Exact match — aliases
|
|
68
|
-
const aliasMatches = db.prepare(`SELECT c.* FROM cards c
|
|
69
|
-
JOIN aliases a ON c.id = a.card_id
|
|
70
|
-
WHERE (a.normalized_alias = ? OR a.normalized_alias LIKE ?)
|
|
71
|
-
AND c.is_deleted = 0`).all(normalizedQuery, `%${normalizedQuery}%`);
|
|
72
|
-
for (const card of aliasMatches) {
|
|
73
|
-
if (seenIds.has(card.id))
|
|
74
|
-
continue;
|
|
75
|
-
seenIds.add(card.id);
|
|
76
|
-
matches.push({
|
|
77
|
-
id: card.id,
|
|
78
|
-
title: card.title,
|
|
79
|
-
match_type: 'alias',
|
|
80
|
-
confidence: 0.9,
|
|
81
|
-
graph_distance: 0,
|
|
82
|
-
file: card.file_path,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
// Step 3: Exact match — tags
|
|
86
|
-
const tagMatches = db.prepare(`SELECT c.* FROM cards c
|
|
87
|
-
JOIN tags t ON c.id = t.card_id
|
|
88
|
-
WHERE t.normalized_tag = ?
|
|
89
|
-
AND c.is_deleted = 0`).all(normalizedQuery);
|
|
90
|
-
for (const card of tagMatches) {
|
|
91
|
-
if (seenIds.has(card.id))
|
|
92
|
-
continue;
|
|
93
|
-
seenIds.add(card.id);
|
|
94
|
-
matches.push({
|
|
95
|
-
id: card.id,
|
|
96
|
-
title: card.title,
|
|
97
|
-
match_type: 'tag',
|
|
98
|
-
confidence: 0.7,
|
|
99
|
-
graph_distance: 0,
|
|
100
|
-
file: card.file_path,
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
// Token-based tag matching
|
|
104
|
-
for (const token of queryTokens) {
|
|
105
|
-
const tokenTagMatches = db.prepare(`SELECT c.* FROM cards c
|
|
106
|
-
JOIN tags t ON c.id = t.card_id
|
|
107
|
-
WHERE t.normalized_tag LIKE ?
|
|
108
|
-
AND c.is_deleted = 0`).all(`%${token}%`);
|
|
109
|
-
for (const card of tokenTagMatches) {
|
|
110
|
-
if (seenIds.has(card.id))
|
|
111
|
-
continue;
|
|
112
|
-
seenIds.add(card.id);
|
|
113
|
-
matches.push({
|
|
114
|
-
id: card.id,
|
|
115
|
-
title: card.title,
|
|
116
|
-
match_type: 'tag',
|
|
117
|
-
confidence: 0.6,
|
|
118
|
-
graph_distance: 0,
|
|
119
|
-
file: card.file_path,
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
// Step 4: Graph expansion — 1-hop neighbors
|
|
124
|
-
const matchedIdsAtThisPoint = new Set(matches.map(m => m.id));
|
|
125
|
-
for (const match of matches) {
|
|
126
|
-
const edges = db.prepare("SELECT * FROM edges WHERE from_id = ? OR to_id = ?").all(match.id, match.id);
|
|
127
|
-
for (const edge of edges) {
|
|
128
|
-
const neighborId = edge.from_id === match.id ? edge.to_id : edge.from_id;
|
|
129
|
-
if (matchedIdsAtThisPoint.has(neighborId) || seenIds.has(neighborId))
|
|
130
|
-
continue;
|
|
131
|
-
seenIds.add(neighborId);
|
|
132
|
-
const neighborCard = db.prepare("SELECT * FROM cards WHERE id = ? AND is_deleted = 0").get(neighborId);
|
|
133
|
-
if (neighborCard) {
|
|
134
|
-
matches.push({
|
|
135
|
-
id: neighborCard.id,
|
|
136
|
-
title: neighborCard.title,
|
|
137
|
-
match_type: 'graph_expansion',
|
|
138
|
-
confidence: 0.6,
|
|
139
|
-
graph_distance: 1,
|
|
140
|
-
file: neighborCard.file_path,
|
|
141
|
-
edge_type: edge.type,
|
|
142
|
-
from_card: match.id,
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
// Step 5: Keyword fallback — FTS5 if available, else LIKE
|
|
148
|
-
const directMatchesBeforeFallback = matches.filter(m => m.match_type !== 'graph_expansion');
|
|
149
|
-
if (directMatchesBeforeFallback.length === 0) {
|
|
150
|
-
if ((0, db_1.hasFTS5)(db)) {
|
|
151
|
-
try {
|
|
152
|
-
const ftsResults = db.prepare("SELECT c.*, rank FROM card_fts JOIN cards c ON card_fts.card_id = c.id WHERE card_fts MATCH ? AND c.is_deleted = 0 ORDER BY rank").all(normalizedQuery);
|
|
153
|
-
for (const row of ftsResults) {
|
|
154
|
-
if (seenIds.has(row.id))
|
|
155
|
-
continue;
|
|
156
|
-
seenIds.add(row.id);
|
|
157
|
-
matches.push({
|
|
158
|
-
id: row.id,
|
|
159
|
-
title: row.title,
|
|
160
|
-
match_type: 'keyword_fallback',
|
|
161
|
-
confidence: Math.min(0.5, 1 / (1 + (row.rank || 1))),
|
|
162
|
-
graph_distance: 0,
|
|
163
|
-
file: row.file_path,
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
catch {
|
|
168
|
-
// FTS5 query failed, fall through to LIKE fallback
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
// LIKE fallback
|
|
172
|
-
if (matches.filter(m => m.match_type === 'keyword_fallback').length === 0) {
|
|
173
|
-
const likePattern = `%${normalizedQuery}%`;
|
|
174
|
-
const likeResults = db.prepare("SELECT * FROM cards WHERE (title LIKE ? OR summary LIKE ?) AND is_deleted = 0").all(likePattern, likePattern);
|
|
175
|
-
for (const card of likeResults) {
|
|
176
|
-
if (seenIds.has(card.id))
|
|
177
|
-
continue;
|
|
178
|
-
seenIds.add(card.id);
|
|
179
|
-
const titleLower = card.title.toLowerCase();
|
|
180
|
-
const tokenOverlap = queryTokens.filter(t => titleLower.includes(t)).length;
|
|
181
|
-
matches.push({
|
|
182
|
-
id: card.id,
|
|
183
|
-
title: card.title,
|
|
184
|
-
match_type: 'keyword_fallback',
|
|
185
|
-
confidence: Math.min(0.5, tokenOverlap / Math.max(1, queryTokens.length)),
|
|
186
|
-
graph_distance: 0,
|
|
187
|
-
file: card.file_path,
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
// Step 6: Rerank
|
|
193
|
-
const typeOrder = {
|
|
194
|
-
exact_id: 5,
|
|
195
|
-
exact_title: 4,
|
|
196
|
-
alias: 3,
|
|
197
|
-
tag: 2,
|
|
198
|
-
graph_expansion: 1,
|
|
199
|
-
keyword_fallback: 0,
|
|
200
|
-
};
|
|
201
|
-
matches.sort((a, b) => {
|
|
202
|
-
return ((typeOrder[b.match_type] - typeOrder[a.match_type]) ||
|
|
203
|
-
(b.confidence - a.confidence) ||
|
|
204
|
-
(a.graph_distance - b.graph_distance));
|
|
205
|
-
});
|
|
206
|
-
// Step 7: Deduplicate
|
|
207
|
-
const dedupedIds = new Set();
|
|
208
|
-
const deduped = [];
|
|
209
|
-
for (const m of matches) {
|
|
210
|
-
if (dedupedIds.has(m.id))
|
|
211
|
-
continue;
|
|
212
|
-
dedupedIds.add(m.id);
|
|
213
|
-
deduped.push(m);
|
|
214
|
-
}
|
|
215
|
-
// Build recommended_files and evidence_paths
|
|
216
|
-
const recommendedFiles = [];
|
|
217
|
-
for (const m of deduped.slice(0, 8)) {
|
|
218
|
-
recommendedFiles.push(m.file);
|
|
219
|
-
}
|
|
220
66
|
const manifest = (0, manifest_1.loadManifest)(pmemPath);
|
|
221
|
-
const config = manifest
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
67
|
+
const config = manifest
|
|
68
|
+
? (0, manifest_1.resolveConfig)(manifest)
|
|
69
|
+
: { evidence_types: ['decision', 'trace'], card_types: ['module', 'decision', 'trace', 'task', 'feature', 'risk'] };
|
|
70
|
+
const knownTypes = config.card_types ?? ['module', 'decision', 'trace', 'task', 'feature', 'risk'];
|
|
71
|
+
const intent = (0, intent_1.parseIntent)(query, knownTypes);
|
|
72
|
+
const candidates = (0, candidates_1.generateCandidates)(db, intent);
|
|
73
|
+
const dirtyRows = db.prepare("SELECT target FROM dirty_flags WHERE resolved_at IS NULL AND scope = 'card'").all();
|
|
74
|
+
const dirtyCardIds = new Set(dirtyRows.map(r => r.target));
|
|
75
|
+
const scored = (0, scoring_1.fuseAndScore)(candidates, {
|
|
76
|
+
now: options.now ?? Date.now(),
|
|
77
|
+
dirtyCardIds,
|
|
78
|
+
});
|
|
79
|
+
const limit = options.limit ?? 20;
|
|
80
|
+
const top = scored.slice(0, limit);
|
|
81
|
+
const matched = top.map(r => toMatch(r, options.explain ?? false));
|
|
82
|
+
const recommendedFiles = top.slice(0, 8).map(r => r.card.file_path);
|
|
83
|
+
const evidenceTypes = config.evidence_types ?? ['decision', 'trace'];
|
|
84
|
+
const evidencePaths = scored
|
|
85
|
+
.filter(r => evidenceTypes.includes(r.card.type))
|
|
86
|
+
.map(r => r.card.file_path);
|
|
230
87
|
return {
|
|
231
88
|
query,
|
|
232
|
-
matched
|
|
89
|
+
matched,
|
|
233
90
|
recommended_files: recommendedFiles,
|
|
234
91
|
evidence_paths: evidencePaths,
|
|
235
92
|
};
|
|
236
93
|
}
|
|
237
|
-
function
|
|
238
|
-
const
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
94
|
+
function toMatch(r, explain) {
|
|
95
|
+
const primary = [...r.reasons].sort((a, b) => b.base - a.base)[0];
|
|
96
|
+
const match = {
|
|
97
|
+
id: r.card.id,
|
|
98
|
+
title: r.card.title,
|
|
99
|
+
match_type: CHANNEL_TO_MATCH_TYPE[primary?.channel ?? 'like'] ?? 'keyword_fallback',
|
|
100
|
+
confidence: r.score,
|
|
101
|
+
graph_distance: r.graph_distance,
|
|
102
|
+
file: r.card.file_path,
|
|
103
|
+
score: r.score,
|
|
104
|
+
stale: r.stale,
|
|
105
|
+
};
|
|
106
|
+
if (r.edge_type)
|
|
107
|
+
match.edge_type = r.edge_type;
|
|
108
|
+
if (r.from_card)
|
|
109
|
+
match.from_card = r.from_card;
|
|
110
|
+
if (explain) {
|
|
111
|
+
match.reasons = r.reasons;
|
|
112
|
+
match.factors = r.factors;
|
|
253
113
|
}
|
|
254
|
-
return
|
|
114
|
+
return match;
|
|
255
115
|
}
|
|
256
116
|
//# sourceMappingURL=ask.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../../../src/core/query/ask.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../../../src/core/query/ask.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,4BA+CC;AAxGD,2CAA6B;AAC7B,8BAAmC;AACnC,8BAAmD;AACnD,0CAA0D;AAC1D,4CAA8C;AAC9C,oDAAyD;AACzD,8CAAmG;AAmCnG,MAAM,qBAAqB,GAA8B;IACvD,QAAQ,EAAE,UAAU;IACpB,YAAY,EAAE,aAAa;IAC3B,WAAW,EAAE,aAAa;IAC1B,YAAY,EAAE,aAAa;IAC3B,WAAW,EAAE,aAAa;IAC1B,KAAK,EAAE,OAAO;IACd,GAAG,EAAE,KAAK;IACV,SAAS,EAAE,KAAK;IAChB,WAAW,EAAE,aAAa;IAC1B,kBAAkB,EAAE,aAAa;IACjC,GAAG,EAAE,kBAAkB;IACvB,IAAI,EAAE,kBAAkB;IACxB,KAAK,EAAE,iBAAiB;CACzB,CAAC;AAEF,SAAgB,QAAQ,CAAC,QAAgB,EAAE,KAAa,EAAE,UAAsB,EAAE;IAChF,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAE9C,IAAI,CAAC,IAAA,eAAU,EAAC,MAAM,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,EAAE,GAAG,IAAA,iBAAY,EAAC,QAAQ,CAAC,CAAC;IAClC,IAAA,iBAAY,EAAC,EAAE,CAAC,CAAC;IAEjB,MAAM,QAAQ,GAAG,IAAA,uBAAY,EAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,QAAQ;QACrB,CAAC,CAAC,IAAA,wBAAa,EAAC,QAAQ,CAAC;QACzB,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;IACtH,MAAM,UAAU,GAAc,MAAc,CAAC,UAAU,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IAEtH,MAAM,MAAM,GAAG,IAAA,oBAAW,EAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,IAAA,+BAAkB,EAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAElD,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAC1B,6EAA6E,CAC9E,CAAC,GAAG,EAA+B,CAAC;IACrC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAE3D,MAAM,MAAM,GAAG,IAAA,sBAAY,EAAC,UAAU,EAAE;QACtC,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE;QAC9B,YAAY;KACb,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;IAClC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAEnC,MAAM,OAAO,GAAkB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC;IAElF,MAAM,gBAAgB,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEpE,MAAM,aAAa,GAAc,MAAc,CAAC,cAAc,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACxF,MAAM,aAAa,GAAG,MAAM;SACzB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAChD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAE9B,OAAO;QACL,KAAK;QACL,OAAO;QACP,iBAAiB,EAAE,gBAAgB;QACnC,cAAc,EAAE,aAAa;KAC9B,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,CAAe,EAAE,OAAgB;IAChD,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,KAAK,GAAgB;QACzB,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE;QACb,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK;QACnB,UAAU,EAAE,qBAAqB,CAAC,OAAO,EAAE,OAAO,IAAI,MAAM,CAAC,IAAI,kBAAkB;QACnF,UAAU,EAAE,CAAC,CAAC,KAAK;QACnB,cAAc,EAAE,CAAC,CAAC,cAAc;QAChC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS;QACtB,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAC;IACF,IAAI,CAAC,CAAC,SAAS;QAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;IAC/C,IAAI,CAAC,CAAC,SAAS;QAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;IAC/C,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;QAC1B,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;IAC5B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/core/query/context.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,aAAa,CAAC;AAEvE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,SAAO,GAAG,kBAAkB,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/core/query/context.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,aAAa,CAAC;AAEvE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,SAAO,GAAG,kBAAkB,CA6K9F"}
|
|
@@ -109,7 +109,7 @@ function contextQuery(pmemPath, task, budget = 4000) {
|
|
|
109
109
|
let askMatched = [];
|
|
110
110
|
if ((0, fs_1.fileExists)(dbPath)) {
|
|
111
111
|
try {
|
|
112
|
-
const ask = (0, ask_1.askQuery)(pmemPath, task);
|
|
112
|
+
const ask = (0, ask_1.askQuery)(pmemPath, task, { explain: true, limit: 12 });
|
|
113
113
|
askMatched = ask.matched || [];
|
|
114
114
|
}
|
|
115
115
|
catch (err) {
|
|
@@ -139,12 +139,18 @@ function contextQuery(pmemPath, task, budget = 4000) {
|
|
|
139
139
|
for (const m of askMatched.slice(0, 10)) {
|
|
140
140
|
const card = db.prepare("SELECT type, title, summary, file_path FROM cards WHERE id = ? AND is_deleted = 0").get(m.id);
|
|
141
141
|
if (card) {
|
|
142
|
+
const reasons = Array.isArray(m.reasons)
|
|
143
|
+
? m.reasons.map((r) => r.channel).filter(Boolean).join(', ')
|
|
144
|
+
: m.match_type;
|
|
142
145
|
result.relevant_memory.push({
|
|
143
146
|
id: m.id,
|
|
144
147
|
title: card.title,
|
|
145
148
|
file_path: card.file_path,
|
|
146
149
|
summary: card.summary || undefined,
|
|
147
|
-
type: card.type
|
|
150
|
+
type: card.type,
|
|
151
|
+
score: m.score,
|
|
152
|
+
reason: reasons || undefined,
|
|
153
|
+
stale: m.stale === true
|
|
148
154
|
});
|
|
149
155
|
}
|
|
150
156
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/core/query/context.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/core/query/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
import type { ParsedIntent } from './intent';
|
|
3
|
+
import { type ScoredCandidate } from './scoring';
|
|
4
|
+
export interface CandidateOptions {
|
|
5
|
+
/** Max hops for graph expansion (default 1) */
|
|
6
|
+
maxHops?: number;
|
|
7
|
+
/** How many top seeds to expand (default 8) */
|
|
8
|
+
expandTopN?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function generateCandidates(db: Database.Database, intent: ParsedIntent, opts?: CandidateOptions): ScoredCandidate[];
|
|
11
|
+
//# sourceMappingURL=candidates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"candidates.d.ts","sourceRoot":"","sources":["../../../../src/core/query/engine/candidates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAG3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAoC,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAEnF,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE,gBAAqB,GAC1B,eAAe,EAAE,CAgBnB"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateCandidates = generateCandidates;
|
|
4
|
+
const db_1 = require("../../db");
|
|
5
|
+
const scoring_1 = require("./scoring");
|
|
6
|
+
function generateCandidates(db, intent, opts = {}) {
|
|
7
|
+
const out = [];
|
|
8
|
+
collectIdMatches(db, intent, out);
|
|
9
|
+
collectTitleMatches(db, intent, out);
|
|
10
|
+
collectAliasMatches(db, intent, out);
|
|
11
|
+
collectTagMatches(db, intent, out);
|
|
12
|
+
collectSourceFileMatches(db, intent, out);
|
|
13
|
+
collectFtsMatches(db, intent, out);
|
|
14
|
+
if (out.length === 0) {
|
|
15
|
+
collectLikeMatches(db, intent, out);
|
|
16
|
+
}
|
|
17
|
+
expandGraph(db, out, opts);
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
function push(out, card, channel, detail, base, extra) {
|
|
21
|
+
out.push({
|
|
22
|
+
card,
|
|
23
|
+
base: base ?? scoring_1.CHANNEL_BASE[channel],
|
|
24
|
+
reasons: [{ channel, detail, base: base ?? scoring_1.CHANNEL_BASE[channel] }],
|
|
25
|
+
graph_distance: 0,
|
|
26
|
+
...extra,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/** Title-based matching: exact title, phrase, and per-token matching.
|
|
30
|
+
* Provides strong signals that rank above pure FTS body hits — critical
|
|
31
|
+
* for queries like "hybrid recall" where the user intends to find cards
|
|
32
|
+
* whose title contains those terms. */
|
|
33
|
+
function collectTitleMatches(db, intent, out) {
|
|
34
|
+
const q = intent.normalized;
|
|
35
|
+
// 1. Exact title match (case-insensitive)
|
|
36
|
+
const exactRows = db.prepare('SELECT * FROM cards WHERE LOWER(title) = ? AND is_deleted = 0').all(q);
|
|
37
|
+
for (const card of exactRows) {
|
|
38
|
+
push(out, card, 'exact_title', `title = "${q}"`);
|
|
39
|
+
}
|
|
40
|
+
// 2. Title phrase match: full normalized query as substring of title
|
|
41
|
+
if (q.length >= 2) {
|
|
42
|
+
const phraseRows = db.prepare('SELECT * FROM cards WHERE LOWER(title) LIKE ? AND is_deleted = 0').all(`%${q}%`);
|
|
43
|
+
for (const card of phraseRows) {
|
|
44
|
+
// Don't double-count exact title matches
|
|
45
|
+
if (card.title.toLowerCase() === q)
|
|
46
|
+
continue;
|
|
47
|
+
push(out, card, 'title_phrase', `title ~ "${q}"`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// 3. Per-token title hits: each query token found in the title
|
|
51
|
+
const titleTokens = intent.tokens.filter(t => t.length >= 2 || /[一-鿿]/.test(t));
|
|
52
|
+
for (const token of titleTokens) {
|
|
53
|
+
// Skip the full query token to avoid redundant LIKE matches
|
|
54
|
+
if (token === q)
|
|
55
|
+
continue;
|
|
56
|
+
const rows = db.prepare('SELECT * FROM cards WHERE LOWER(title) LIKE ? AND is_deleted = 0').all(`%${token}%`);
|
|
57
|
+
for (const card of rows) {
|
|
58
|
+
push(out, card, 'title_token', `title contains "${token}"`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function collectIdMatches(db, intent, out) {
|
|
63
|
+
const q = intent.normalized;
|
|
64
|
+
const rows = db.prepare('SELECT * FROM cards WHERE (id = ? OR id LIKE ?) AND is_deleted = 0').all(q, `%${q}%`);
|
|
65
|
+
for (const card of rows) {
|
|
66
|
+
if (card.id === q)
|
|
67
|
+
push(out, card, 'exact_id', `id = ${q}`);
|
|
68
|
+
else
|
|
69
|
+
push(out, card, 'id_substring', `id contains "${q}"`);
|
|
70
|
+
}
|
|
71
|
+
for (const idCand of intent.cardIdCandidates) {
|
|
72
|
+
if (idCand === q)
|
|
73
|
+
continue;
|
|
74
|
+
const row = db.prepare('SELECT * FROM cards WHERE id = ? AND is_deleted = 0').get(idCand);
|
|
75
|
+
if (row)
|
|
76
|
+
push(out, row, 'exact_id', `id token = ${idCand}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function collectAliasMatches(db, intent, out) {
|
|
80
|
+
const q = intent.normalized;
|
|
81
|
+
const rows = db.prepare(`SELECT c.*, a.normalized_alias AS matched_alias FROM cards c
|
|
82
|
+
JOIN aliases a ON c.id = a.card_id
|
|
83
|
+
WHERE (a.normalized_alias = ? OR a.normalized_alias LIKE ?) AND c.is_deleted = 0`).all(q, `%${q}%`);
|
|
84
|
+
for (const row of rows) {
|
|
85
|
+
push(out, row, 'alias', `alias: ${row.matched_alias}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function collectTagMatches(db, intent, out) {
|
|
89
|
+
const q = intent.normalized;
|
|
90
|
+
const exact = db.prepare(`SELECT c.*, t.normalized_tag AS matched_tag FROM cards c
|
|
91
|
+
JOIN tags t ON c.id = t.card_id
|
|
92
|
+
WHERE t.normalized_tag = ? AND c.is_deleted = 0`).all(q);
|
|
93
|
+
for (const row of exact)
|
|
94
|
+
push(out, row, 'tag', `tag: ${row.matched_tag}`);
|
|
95
|
+
for (const token of intent.tokens) {
|
|
96
|
+
if (token.length < 2 && !/[一-鿿]/.test(token))
|
|
97
|
+
continue;
|
|
98
|
+
const rows = db.prepare(`SELECT c.*, t.normalized_tag AS matched_tag FROM cards c
|
|
99
|
+
JOIN tags t ON c.id = t.card_id
|
|
100
|
+
WHERE t.normalized_tag LIKE ? AND c.is_deleted = 0`).all(`%${token}%`);
|
|
101
|
+
for (const row of rows)
|
|
102
|
+
push(out, row, 'tag_token', `tag ~ ${token} (${row.matched_tag})`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function collectSourceFileMatches(db, intent, out) {
|
|
106
|
+
const candidates = intent.pathCandidates.length > 0
|
|
107
|
+
? intent.pathCandidates
|
|
108
|
+
: (looksLikePath(intent.normalized) ? [intent.normalized] : []);
|
|
109
|
+
for (const p of candidates) {
|
|
110
|
+
const exact = db.prepare(`SELECT c.*, p.path AS matched_path FROM cards c
|
|
111
|
+
JOIN paths p ON c.id = p.card_id
|
|
112
|
+
WHERE p.path = ? AND c.is_deleted = 0`).all(p);
|
|
113
|
+
for (const row of exact)
|
|
114
|
+
push(out, row, 'source_file', `source file: ${row.matched_path}`);
|
|
115
|
+
if (exact.length === 0) {
|
|
116
|
+
const partial = db.prepare(`SELECT c.*, p.path AS matched_path FROM cards c
|
|
117
|
+
JOIN paths p ON c.id = p.card_id
|
|
118
|
+
WHERE p.path LIKE ? AND c.is_deleted = 0`).all(`%${p}%`);
|
|
119
|
+
for (const row of partial)
|
|
120
|
+
push(out, row, 'source_file_prefix', `source file ~ ${p} (${row.matched_path})`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function looksLikePath(s) {
|
|
125
|
+
return !s.includes(' ') && (s.includes('/') || /\.[a-z]{1,4}$/.test(s));
|
|
126
|
+
}
|
|
127
|
+
function collectFtsMatches(db, intent, out) {
|
|
128
|
+
if (!(0, db_1.ftsTableExists)(db))
|
|
129
|
+
return;
|
|
130
|
+
const ftsQuery = buildFtsQuery(intent);
|
|
131
|
+
if (!ftsQuery)
|
|
132
|
+
return;
|
|
133
|
+
try {
|
|
134
|
+
const rows = db.prepare(`SELECT c.*, bm25(card_fts, 0.0, 4.0, 2.0, 1.0, 3.0, 2.5) AS rank
|
|
135
|
+
FROM card_fts JOIN cards c ON card_fts.card_id = c.id
|
|
136
|
+
WHERE card_fts MATCH ? AND c.is_deleted = 0
|
|
137
|
+
ORDER BY rank LIMIT 20`).all(ftsQuery);
|
|
138
|
+
if (rows.length === 0)
|
|
139
|
+
return;
|
|
140
|
+
const best = rows[0].rank;
|
|
141
|
+
const worst = rows[rows.length - 1].rank;
|
|
142
|
+
for (const row of rows) {
|
|
143
|
+
push(out, row, 'fts', `bm25 rank ${row.rank.toFixed(2)}`, (0, scoring_1.ftsBase)(row.rank, best, worst));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// Malformed FTS query (special chars) — skip channel silently
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function buildFtsQuery(intent) {
|
|
151
|
+
const terms = intent.tokens
|
|
152
|
+
.filter(t => t.length >= 2 && /^[\w一-鿿-]+$/.test(t))
|
|
153
|
+
.map(t => `"${t}"`);
|
|
154
|
+
if (terms.length === 0)
|
|
155
|
+
return null;
|
|
156
|
+
return terms.join(' OR ');
|
|
157
|
+
}
|
|
158
|
+
function collectLikeMatches(db, intent, out) {
|
|
159
|
+
const pattern = `%${intent.normalized}%`;
|
|
160
|
+
const rows = db.prepare('SELECT * FROM cards WHERE (title LIKE ? OR summary LIKE ?) AND is_deleted = 0').all(pattern, pattern);
|
|
161
|
+
for (const card of rows) {
|
|
162
|
+
const titleLower = card.title.toLowerCase();
|
|
163
|
+
const overlap = intent.tokens.filter(t => titleLower.includes(t)).length;
|
|
164
|
+
const base = Math.min(scoring_1.CHANNEL_BASE.like, overlap / Math.max(1, intent.tokens.length));
|
|
165
|
+
push(out, card, 'like', `title/summary contains "${intent.normalized}"`, Math.max(0.2, base));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function expandGraph(db, out, opts) {
|
|
169
|
+
const maxHops = opts.maxHops ?? 1;
|
|
170
|
+
const expandTopN = opts.expandTopN ?? 8;
|
|
171
|
+
if (maxHops < 1 || out.length === 0)
|
|
172
|
+
return;
|
|
173
|
+
const seen = new Set(out.map(c => c.card.id));
|
|
174
|
+
const seeds = [...out]
|
|
175
|
+
.sort((a, b) => (b.base - a.base) || a.card.id.localeCompare(b.card.id))
|
|
176
|
+
.slice(0, expandTopN);
|
|
177
|
+
let frontier = seeds.map(s => ({ id: s.card.id, score: s.base }));
|
|
178
|
+
for (let hop = 1; hop <= maxHops; hop++) {
|
|
179
|
+
const nextFrontier = [];
|
|
180
|
+
for (const node of frontier) {
|
|
181
|
+
const edges = db.prepare('SELECT * FROM edges WHERE from_id = ? OR to_id = ?').all(node.id, node.id);
|
|
182
|
+
for (const edge of edges) {
|
|
183
|
+
const neighborId = edge.from_id === node.id ? edge.to_id : edge.from_id;
|
|
184
|
+
if (seen.has(neighborId))
|
|
185
|
+
continue;
|
|
186
|
+
const neighbor = db.prepare('SELECT * FROM cards WHERE id = ? AND is_deleted = 0').get(neighborId);
|
|
187
|
+
if (!neighbor)
|
|
188
|
+
continue;
|
|
189
|
+
seen.add(neighborId);
|
|
190
|
+
const base = (0, scoring_1.graphBase)(node.score, edge.confidence ?? 1.0, hop);
|
|
191
|
+
out.push({
|
|
192
|
+
card: neighbor,
|
|
193
|
+
base,
|
|
194
|
+
reasons: [{ channel: 'graph', detail: `${edge.type} ← ${node.id} (hop ${hop})`, base }],
|
|
195
|
+
graph_distance: hop,
|
|
196
|
+
edge_type: edge.type,
|
|
197
|
+
from_card: node.id,
|
|
198
|
+
});
|
|
199
|
+
nextFrontier.push({ id: neighborId, score: base });
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
frontier = nextFrontier;
|
|
203
|
+
if (frontier.length === 0)
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=candidates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"candidates.js","sourceRoot":"","sources":["../../../../src/core/query/engine/candidates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ParsedIntent {
|
|
2
|
+
raw: string;
|
|
3
|
+
normalized: string;
|
|
4
|
+
tokens: string[];
|
|
5
|
+
/** Tokens that look like card ids, e.g. decision.foo_bar_20260101 */
|
|
6
|
+
cardIdCandidates: string[];
|
|
7
|
+
/** Tokens that look like file paths, e.g. src/core/db.ts */
|
|
8
|
+
pathCandidates: string[];
|
|
9
|
+
/** Card type names mentioned in the query (decision, module, ...) */
|
|
10
|
+
typeHints: string[];
|
|
11
|
+
}
|
|
12
|
+
export declare function parseIntent(query: string, knownTypes: string[]): ParsedIntent;
|
|
13
|
+
export declare function tokenize(text: string): string[];
|
|
14
|
+
//# sourceMappingURL=intent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent.d.ts","sourceRoot":"","sources":["../../../../src/core/query/engine/intent.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,qEAAqE;IACrE,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,4DAA4D;IAC5D,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,qEAAqE;IACrE,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAKD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,YAAY,CA2B7E;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAe/C"}
|