@djolex999/vir-cli 0.14.1 → 0.16.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 +281 -264
- package/dist/cli/embedSetup.js +62 -0
- package/dist/cli/embedSetup.js.map +1 -0
- package/dist/cli/queries.js +44 -0
- package/dist/cli/queries.js.map +1 -0
- package/dist/cli.js +143 -20
- package/dist/cli.js.map +1 -1
- package/dist/config.js +10 -0
- package/dist/config.js.map +1 -1
- package/dist/diagnostics/doctor.js +79 -0
- package/dist/diagnostics/doctor.js.map +1 -1
- package/dist/mcp/server.js +19 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/pipeline/embeddingSweep.js +17 -11
- package/dist/pipeline/embeddingSweep.js.map +1 -1
- package/dist/pipeline/run.js +19 -7
- package/dist/pipeline/run.js.map +1 -1
- package/dist/pipeline/writer.js +43 -23
- package/dist/pipeline/writer.js.map +1 -1
- package/dist/search/embedder.js +75 -15
- package/dist/search/embedder.js.map +1 -1
- package/dist/search/localProvider.js +99 -0
- package/dist/search/localProvider.js.map +1 -0
- package/dist/search/provider.js +72 -0
- package/dist/search/provider.js.map +1 -0
- package/dist/search/queryLog.js +123 -0
- package/dist/search/queryLog.js.map +1 -0
- package/dist/search/retriever.js +61 -17
- package/dist/search/retriever.js.map +1 -1
- package/dist/search/thresholds.js +18 -0
- package/dist/search/thresholds.js.map +1 -0
- package/dist/state/db.js +65 -17
- package/dist/state/db.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, writeFileSync, } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { isVerified } from "./retriever.js";
|
|
5
|
+
export const QUERY_LOG_PATH = join(homedir(), ".vir", "queries.jsonl");
|
|
6
|
+
// One rotated generation only: at the cap the live file becomes .1 (replacing
|
|
7
|
+
// any previous .1) and a fresh live file starts. Two generations bound the log
|
|
8
|
+
// at ~2×cap while keeping enough history for `vir queries` to be meaningful.
|
|
9
|
+
export const QUERY_LOG_MAX_BYTES = 5 * 1024 * 1024;
|
|
10
|
+
// Written (best-effort) whenever a log append fails, so doctor can surface
|
|
11
|
+
// "queries are happening but the log isn't being written" — the stderr line
|
|
12
|
+
// alone scrolls away, and a silent best-effort is a blind spot.
|
|
13
|
+
export const QUERY_LOG_FAIL_MARKER_PATH = join(homedir(), ".vir", "queries.failed");
|
|
14
|
+
export function formatQueryRecord(input) {
|
|
15
|
+
return {
|
|
16
|
+
ts: input.now.toISOString(),
|
|
17
|
+
source: input.source,
|
|
18
|
+
query: input.query,
|
|
19
|
+
type: input.type,
|
|
20
|
+
method: input.search.method,
|
|
21
|
+
degraded: input.search.degraded,
|
|
22
|
+
degradedReason: input.search.degraded ? input.search.embedError : null,
|
|
23
|
+
provider: input.search.provider,
|
|
24
|
+
candidates: input.search.candidates,
|
|
25
|
+
excludedModel: input.search.excludedMismatched,
|
|
26
|
+
latencyMs: input.latencyMs,
|
|
27
|
+
hits: input.hits.map((h, i) => ({
|
|
28
|
+
slug: h.title,
|
|
29
|
+
rank: i + 1,
|
|
30
|
+
score: h.score,
|
|
31
|
+
verified: isVerified(h.content),
|
|
32
|
+
})),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// The one chokepoint both call sites (CLI query, MCP vir_query) wire through:
|
|
36
|
+
// gate on cfg.logQueries, stamp the time, format, append. `append` is
|
|
37
|
+
// injectable for tests only — production callers pass nothing.
|
|
38
|
+
export function recordQueryEvent(event, append = appendQueryLog) {
|
|
39
|
+
if (!event.logQueries)
|
|
40
|
+
return;
|
|
41
|
+
// Outer guard on the WHOLE logging path (format + append): logging must
|
|
42
|
+
// never throw into a query, no matter what fails. appendQueryLog already
|
|
43
|
+
// reports its own failures on stderr; anything else dies silently here
|
|
44
|
+
// rather than failing the query.
|
|
45
|
+
try {
|
|
46
|
+
append(formatQueryRecord({
|
|
47
|
+
source: event.source,
|
|
48
|
+
query: event.query,
|
|
49
|
+
type: event.type,
|
|
50
|
+
hits: event.hits,
|
|
51
|
+
search: event.search,
|
|
52
|
+
latencyMs: event.latencyMs,
|
|
53
|
+
now: new Date(),
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// best-effort by contract
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Best-effort by contract: a log write failure must never fail a query. But
|
|
61
|
+
// never SILENT — on failure it emits one stderr line (stderr only: on the MCP
|
|
62
|
+
// path stdout is the JSON-RPC channel) and stamps the failure marker for
|
|
63
|
+
// doctor. It never touches stdout.
|
|
64
|
+
export function appendQueryLog(rec, opts = {}) {
|
|
65
|
+
const logPath = opts.logPath ?? QUERY_LOG_PATH;
|
|
66
|
+
const maxBytes = opts.maxBytes ?? QUERY_LOG_MAX_BYTES;
|
|
67
|
+
const stderr = opts.stderr ?? ((line) => process.stderr.write(line));
|
|
68
|
+
try {
|
|
69
|
+
mkdirSync(dirname(logPath), { recursive: true });
|
|
70
|
+
rotateIfNeeded(logPath, maxBytes);
|
|
71
|
+
appendFileSync(logPath, JSON.stringify(rec) + "\n", "utf8");
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
stderr(`vir: query log write failed: ${err.message}\n`);
|
|
75
|
+
try {
|
|
76
|
+
writeFileSync(opts.failMarkerPath ?? QUERY_LOG_FAIL_MARKER_PATH, `${rec.ts} ${err.message}\n`, "utf8");
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// marker is itself best-effort — the stderr line already fired
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function rotateIfNeeded(logPath, maxBytes) {
|
|
84
|
+
let size;
|
|
85
|
+
try {
|
|
86
|
+
size = statSync(logPath).size;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return; // no live file yet — nothing to rotate
|
|
90
|
+
}
|
|
91
|
+
// rename replaces any existing .1, so exactly one generation survives.
|
|
92
|
+
if (size >= maxBytes)
|
|
93
|
+
renameSync(logPath, logPath + ".1");
|
|
94
|
+
}
|
|
95
|
+
// Reads the rotated generation first, then the live file, so records come back
|
|
96
|
+
// in chronological order. Malformed lines and missing files are skipped.
|
|
97
|
+
export function readQueryLog(logPath = QUERY_LOG_PATH) {
|
|
98
|
+
const records = [];
|
|
99
|
+
for (const p of [logPath + ".1", logPath]) {
|
|
100
|
+
if (!existsSync(p))
|
|
101
|
+
continue;
|
|
102
|
+
let raw;
|
|
103
|
+
try {
|
|
104
|
+
raw = readFileSync(p, "utf8");
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
for (const line of raw.split("\n")) {
|
|
110
|
+
const trimmed = line.trim();
|
|
111
|
+
if (!trimmed)
|
|
112
|
+
continue;
|
|
113
|
+
try {
|
|
114
|
+
records.push(JSON.parse(trimmed));
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// skip malformed lines
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return records;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=queryLog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryLog.js","sourceRoot":"","sources":["../../src/search/queryLog.ts"],"names":[],"mappings":"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"}
|
package/dist/search/retriever.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
2
2
|
import { join, relative } from "node:path";
|
|
3
|
-
import { cosineSimilarity
|
|
3
|
+
import { cosineSimilarity } from "./embedder.js";
|
|
4
|
+
import { resolveEmbeddingProvider, } from "./provider.js";
|
|
5
|
+
import { thresholdsFor } from "./thresholds.js";
|
|
4
6
|
const SKIP_FILES = new Set(["index.md", "log.md"]);
|
|
5
7
|
// Directories the TF-IDF walk must never index: derived period summaries
|
|
6
8
|
// (files-only, never in SQLite), human-rejected notes (`vir review` moves
|
|
@@ -8,14 +10,16 @@ const SKIP_FILES = new Set(["index.md", "log.md"]);
|
|
|
8
10
|
// covered separately — rejected notes' recorded paths no longer exist (the
|
|
9
11
|
// content read skips them) and getEmbeddings gates on `archived`.
|
|
10
12
|
const SKIP_DIRS = new Set(["summaries", ".rejected", "archived"]);
|
|
11
|
-
|
|
13
|
+
// Resolved per-model from thresholds.ts — see MODEL_THRESHOLDS.
|
|
12
14
|
// Notes a user has approved via `vir review` carry `verified: true` in their
|
|
13
15
|
// frontmatter. They get a flat ranking boost so human-verified knowledge floats
|
|
14
16
|
// above unverified auto-distillations of comparable relevance. Applied before
|
|
15
17
|
// the topK slice in both the embedding and TF-IDF paths.
|
|
16
18
|
const VERIFIED_BOOST = 0.2;
|
|
17
19
|
// Cheap frontmatter check — true only when the YAML block has `verified: true`.
|
|
18
|
-
|
|
20
|
+
// Exported so the query log records per-hit verified status without a second
|
|
21
|
+
// drift-prone reimplementation (the kebabLite lesson).
|
|
22
|
+
export function isVerified(raw) {
|
|
19
23
|
const m = raw.match(/^---\n([\s\S]*?)\n---/);
|
|
20
24
|
if (!m?.[1])
|
|
21
25
|
return false;
|
|
@@ -27,8 +31,9 @@ export async function search(cfg, db, query, topK = 8) {
|
|
|
27
31
|
return (await searchWithOutcome(cfg, db, query, topK)).hits;
|
|
28
32
|
}
|
|
29
33
|
export async function searchWithOutcome(cfg, db, query, topK = 8) {
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
const provider = await resolveEmbeddingProvider(cfg.embeddingProvider);
|
|
35
|
+
if (provider) {
|
|
36
|
+
const attempt = await searchByEmbedding(cfg, db, query, topK, provider);
|
|
32
37
|
// If embeddings produced at least one match above the floor, take it.
|
|
33
38
|
// Otherwise fall through to TF-IDF: low cosine on every doc means the
|
|
34
39
|
// query is semantically off; lexical overlap might still find a match.
|
|
@@ -38,50 +43,82 @@ export async function searchWithOutcome(cfg, db, query, topK = 8) {
|
|
|
38
43
|
method: "embedding",
|
|
39
44
|
degraded: false,
|
|
40
45
|
embedError: null,
|
|
46
|
+
excludedMismatched: attempt.excluded,
|
|
47
|
+
noProvider: false,
|
|
48
|
+
candidates: attempt.candidates,
|
|
49
|
+
provider: {
|
|
50
|
+
name: provider.name,
|
|
51
|
+
model: provider.modelName,
|
|
52
|
+
dim: provider.dimensions,
|
|
53
|
+
},
|
|
41
54
|
};
|
|
42
55
|
}
|
|
56
|
+
const fallback = searchByTfIdf(cfg, query, topK);
|
|
43
57
|
return {
|
|
44
|
-
hits:
|
|
58
|
+
hits: fallback.hits,
|
|
45
59
|
method: "tfidf",
|
|
46
60
|
degraded: attempt.error !== null,
|
|
47
61
|
embedError: attempt.error,
|
|
62
|
+
excludedMismatched: attempt.excluded,
|
|
63
|
+
noProvider: false,
|
|
64
|
+
candidates: fallback.candidates,
|
|
65
|
+
provider: null,
|
|
48
66
|
};
|
|
49
67
|
}
|
|
68
|
+
// TF-IDF is the supported floor, not a degraded state — but the caller must
|
|
69
|
+
// be able to say "no provider" rather than "embeddings failed".
|
|
70
|
+
const floor = searchByTfIdf(cfg, query, topK);
|
|
50
71
|
return {
|
|
51
|
-
hits:
|
|
72
|
+
hits: floor.hits,
|
|
52
73
|
method: "tfidf",
|
|
53
74
|
degraded: false,
|
|
54
75
|
embedError: null,
|
|
76
|
+
excludedMismatched: 0,
|
|
77
|
+
noProvider: true,
|
|
78
|
+
candidates: floor.candidates,
|
|
79
|
+
provider: null,
|
|
55
80
|
};
|
|
56
81
|
}
|
|
57
|
-
|
|
82
|
+
// Splits an embedding pool into rows comparable with the active model and a
|
|
83
|
+
// count of refusals. Cosine between vectors from different models (or different
|
|
84
|
+
// dimensionalities) is meaningless, so those rows must never enter the ranking.
|
|
85
|
+
export function partitionByEmbeddingModel(rows, activeModel) {
|
|
86
|
+
const compatible = rows.filter((r) => r.embeddingModel === activeModel);
|
|
87
|
+
return { compatible, excluded: rows.length - compatible.length };
|
|
88
|
+
}
|
|
89
|
+
async function searchByEmbedding(cfg, db, query, topK, provider) {
|
|
58
90
|
let queryVec;
|
|
59
91
|
try {
|
|
60
|
-
queryVec = await
|
|
92
|
+
queryVec = await provider.embedQuery(query);
|
|
61
93
|
}
|
|
62
94
|
catch (err) {
|
|
63
|
-
return { hits: [], error: err.message };
|
|
95
|
+
return { hits: [], error: err.message, excluded: 0, candidates: 0 };
|
|
64
96
|
}
|
|
65
97
|
const root = vaultRoot(cfg);
|
|
66
98
|
// Sessions, articles, topics, and PDFs are embedded into the same vector
|
|
67
99
|
// space; concat all four so semantic search covers every layer. No layer gets
|
|
68
100
|
// a ranking boost — they compete on cosine like everything else.
|
|
69
|
-
const
|
|
101
|
+
const allRows = [
|
|
70
102
|
...db.getEmbeddings(root),
|
|
71
103
|
...db.getArticleEmbeddings(),
|
|
72
104
|
...db.getTopicEmbeddings(root, cfg.topicsDir),
|
|
73
105
|
...db.getPdfEmbeddings(),
|
|
74
106
|
];
|
|
107
|
+
// Vectors from another model are geometric nonsense against this query —
|
|
108
|
+
// refuse to compare them. Excluded rows are counted, never silently dropped;
|
|
109
|
+
// they re-enter search once re-embedded under the active model.
|
|
110
|
+
const { compatible: rows, excluded } = partitionByEmbeddingModel(allRows, provider.modelName);
|
|
75
111
|
if (rows.length === 0)
|
|
76
|
-
return { hits: [], error: null };
|
|
112
|
+
return { hits: [], error: null, excluded, candidates: 0 };
|
|
77
113
|
// Read each candidate's content once, here, so the verified boost can be
|
|
78
114
|
// applied BEFORE the topK slice — a verified note must be able to outrank an
|
|
79
115
|
// unverified one just outside the window. Reads are bounded to docs above the
|
|
80
116
|
// cosine floor (a personal-scale vault), and the content is reused for hits.
|
|
117
|
+
const minScore = thresholdsFor(provider.modelName).minEmbeddingScore;
|
|
81
118
|
const enriched = [];
|
|
82
119
|
for (const r of rows) {
|
|
83
120
|
const s = cosineSimilarity(queryVec, r.embedding);
|
|
84
|
-
if (s <
|
|
121
|
+
if (s < minScore)
|
|
85
122
|
continue;
|
|
86
123
|
let content = "";
|
|
87
124
|
try {
|
|
@@ -120,7 +157,7 @@ async function searchByEmbedding(cfg, db, query, topK) {
|
|
|
120
157
|
method: "embedding",
|
|
121
158
|
};
|
|
122
159
|
});
|
|
123
|
-
return { hits, error: null };
|
|
160
|
+
return { hits, error: null, excluded, candidates: enriched.length };
|
|
124
161
|
}
|
|
125
162
|
// Maximal Marginal Relevance: greedily reranks a candidate pool to trade off
|
|
126
163
|
// relevance against diversity. lambda is the relevance weight — 1.0 is pure
|
|
@@ -160,15 +197,18 @@ export function mmrRerank(candidates, topK, lambda = 0.7) {
|
|
|
160
197
|
}
|
|
161
198
|
function searchByTfIdf(cfg, query, topK) {
|
|
162
199
|
const docs = loadIndex(cfg);
|
|
163
|
-
|
|
200
|
+
// Score everything, slice here: the full match count is the `candidates`
|
|
201
|
+
// telemetry for the query log. Same sort, same slice — ranking unchanged.
|
|
202
|
+
const scored = searchTfIdf(docs, query, docs.length);
|
|
164
203
|
const root = vaultRoot(cfg);
|
|
165
|
-
|
|
204
|
+
const hits = scored.slice(0, topK).map((d) => ({
|
|
166
205
|
filePath: join(root, d.relPath),
|
|
167
206
|
title: d.title,
|
|
168
207
|
content: d.raw,
|
|
169
208
|
score: d.score,
|
|
170
209
|
method: "tfidf",
|
|
171
210
|
}));
|
|
211
|
+
return { hits, candidates: scored.length };
|
|
172
212
|
}
|
|
173
213
|
export function vaultRoot(cfg) {
|
|
174
214
|
return join(cfg.vaultPath, cfg.outputDir);
|
|
@@ -229,7 +269,11 @@ export function searchTfIdf(docs, query, topK = 8) {
|
|
|
229
269
|
const df = dfMap.get(term) ?? 0;
|
|
230
270
|
if (df === 0)
|
|
231
271
|
continue;
|
|
232
|
-
|
|
272
|
+
// Smoothed: log(1 + N/df), never zero. Bare log(N/df) is 0 whenever
|
|
273
|
+
// df === N — which is EVERY term in a single-note vault, making the
|
|
274
|
+
// first note a new user creates unfindable. log(1+x) → log(x) for
|
|
275
|
+
// large x, so established-vault rankings are essentially unchanged.
|
|
276
|
+
const idf = Math.log(1 + totalDocs / df);
|
|
233
277
|
// Normalize TF by doc length so long docs don't dominate.
|
|
234
278
|
const tfNorm = tf / Math.max(1, d.tokens.length);
|
|
235
279
|
score += tfNorm * idf;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retriever.js","sourceRoot":"","sources":["../../src/search/retriever.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"retriever.js","sourceRoot":"","sources":["../../src/search/retriever.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const MODEL_THRESHOLDS = {
|
|
2
|
+
"nomic-embed-text": { minEmbeddingScore: 0.3, relatedMinSim: 0.6 },
|
|
3
|
+
// Calibrated 2026-07-31 by quantile-matching nomic's floors on a real
|
|
4
|
+
// 389-note vault (20 queries; 75,466 doc-doc pairs). The two models'
|
|
5
|
+
// DOC-DOC cosine distributions are nearly identical (p50 0.744 vs 0.741,
|
|
6
|
+
// p90 0.800 vs 0.795), so relatedMinSim carries over unchanged. QUERY-DOC
|
|
7
|
+
// scores run ~0.15 hotter on bge (its query instruction prefix): nomic's
|
|
8
|
+
// 0.3 floor sits ~0.12 below its in-domain minimum (0.416), so bge gets
|
|
9
|
+
// the same margin below its own minimum (0.456) → 0.35. Remaining unknown:
|
|
10
|
+
// where garbage/out-of-domain queries score under bge — measuring that
|
|
11
|
+
// distribution against the vault would pin the floor exactly.
|
|
12
|
+
"bge-small-en-v1.5": { minEmbeddingScore: 0.35, relatedMinSim: 0.6 },
|
|
13
|
+
};
|
|
14
|
+
const FALLBACK = MODEL_THRESHOLDS["nomic-embed-text"];
|
|
15
|
+
export function thresholdsFor(model) {
|
|
16
|
+
return MODEL_THRESHOLDS[model] ?? FALLBACK;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=thresholds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thresholds.js","sourceRoot":"","sources":["../../src/search/thresholds.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,MAAM,gBAAgB,GAAoC;IAC/D,kBAAkB,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE;IAClE,sEAAsE;IACtE,qEAAqE;IACrE,yEAAyE;IACzE,0EAA0E;IAC1E,yEAAyE;IACzE,wEAAwE;IACxE,2EAA2E;IAC3E,uEAAuE;IACvE,8DAA8D;IAC9D,mBAAmB,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE;CACrE,CAAC;AAEF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,kBAAkB,CAAE,CAAC;AAEvD,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,gBAAgB,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC;AAC7C,CAAC"}
|
package/dist/state/db.js
CHANGED
|
@@ -10,6 +10,13 @@ const GATED_SKIP_REASONS = new Set([
|
|
|
10
10
|
"sidechain-transcript",
|
|
11
11
|
"agent-transcript",
|
|
12
12
|
]);
|
|
13
|
+
// Every embedding written before provenance existed came from Ollama's
|
|
14
|
+
// nomic-embed-text (the only embedder any vir binary ever had), so legacy rows
|
|
15
|
+
// backfill to this on migration.
|
|
16
|
+
export const LEGACY_EMBEDDING_PROVENANCE = {
|
|
17
|
+
model: "nomic-embed-text",
|
|
18
|
+
dim: 768,
|
|
19
|
+
};
|
|
13
20
|
const ADDED_COLUMNS = [
|
|
14
21
|
{ name: "content", ddl: "ALTER TABLE sessions ADD COLUMN content TEXT" },
|
|
15
22
|
{ name: "category", ddl: "ALTER TABLE sessions ADD COLUMN category TEXT" },
|
|
@@ -148,6 +155,35 @@ export class StateDb {
|
|
|
148
155
|
if (!existing.has(col.name))
|
|
149
156
|
this.db.exec(col.ddl);
|
|
150
157
|
}
|
|
158
|
+
// Embedding provenance, all four embedding-bearing tables. Backfill is safe
|
|
159
|
+
// and idempotent: rows embedded before provenance existed can only have come
|
|
160
|
+
// from nomic (the sole embedder in every prior release), and the WHERE
|
|
161
|
+
// clause never touches rows that already carry provenance.
|
|
162
|
+
for (const table of ["sessions", "articles", "pdfs", "topics"]) {
|
|
163
|
+
const cols = new Set(this.db.prepare(`PRAGMA table_info(${table})`).all().map((r) => r.name));
|
|
164
|
+
if (!cols.has("embedding_model")) {
|
|
165
|
+
this.db.exec(`ALTER TABLE ${table} ADD COLUMN embedding_model TEXT`);
|
|
166
|
+
}
|
|
167
|
+
if (!cols.has("embedding_dim")) {
|
|
168
|
+
this.db.exec(`ALTER TABLE ${table} ADD COLUMN embedding_dim INTEGER`);
|
|
169
|
+
}
|
|
170
|
+
this.db.exec(`UPDATE ${table}
|
|
171
|
+
SET embedding_model = '${LEGACY_EMBEDDING_PROVENANCE.model}',
|
|
172
|
+
embedding_dim = ${LEGACY_EMBEDDING_PROVENANCE.dim}
|
|
173
|
+
WHERE embedding IS NOT NULL AND embedding_model IS NULL`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// True when `table` carries the provenance columns. The read-only MCP path
|
|
177
|
+
// skips migrations, so an upgraded-but-never-written DB may lack them; read
|
|
178
|
+
// paths must degrade to legacy provenance instead of erroring.
|
|
179
|
+
provenanceCache = new Map();
|
|
180
|
+
hasProvenance(table) {
|
|
181
|
+
const cached = this.provenanceCache.get(table);
|
|
182
|
+
if (cached !== undefined)
|
|
183
|
+
return cached;
|
|
184
|
+
const has = this.db.prepare(`PRAGMA table_info(${table})`).all().some((r) => r.name === "embedding_model");
|
|
185
|
+
this.provenanceCache.set(table, has);
|
|
186
|
+
return has;
|
|
151
187
|
}
|
|
152
188
|
getByPath(path) {
|
|
153
189
|
return this.db
|
|
@@ -451,14 +487,15 @@ export class StateDb {
|
|
|
451
487
|
// Embedding storage is keyed by sessionId (the JSONL basename), since callers
|
|
452
488
|
// typically have that handy and not the full path. Match suffix-anchored:
|
|
453
489
|
// `path LIKE '%/<sessionId>.jsonl'`.
|
|
454
|
-
storeEmbedding(sessionId, embedding) {
|
|
490
|
+
storeEmbedding(sessionId, embedding, provenance) {
|
|
455
491
|
this.db
|
|
456
|
-
.prepare("UPDATE sessions SET embedding = ? WHERE path LIKE ?")
|
|
457
|
-
.run(JSON.stringify(embedding), `%/${sessionId}.jsonl`);
|
|
492
|
+
.prepare("UPDATE sessions SET embedding = ?, embedding_model = ?, embedding_dim = ? WHERE path LIKE ?")
|
|
493
|
+
.run(JSON.stringify(embedding), provenance.model, provenance.dim, `%/${sessionId}.jsonl`);
|
|
458
494
|
}
|
|
459
495
|
getEmbeddings(vaultRoot) {
|
|
496
|
+
const prov = this.hasProvenance("sessions");
|
|
460
497
|
const rows = this.db
|
|
461
|
-
.prepare(`SELECT path, embedding, topic, category, project
|
|
498
|
+
.prepare(`SELECT path, embedding, topic, category, project${prov ? ", embedding_model, embedding_dim" : ""}
|
|
462
499
|
FROM sessions
|
|
463
500
|
WHERE skipped = 0
|
|
464
501
|
AND error IS NULL
|
|
@@ -491,6 +528,8 @@ export class StateDb {
|
|
|
491
528
|
project: r.project ?? "",
|
|
492
529
|
filePath,
|
|
493
530
|
embedding: vec,
|
|
531
|
+
embeddingModel: r.embedding_model ?? LEGACY_EMBEDDING_PROVENANCE.model,
|
|
532
|
+
embeddingDim: r.embedding_dim ?? vec.length,
|
|
494
533
|
});
|
|
495
534
|
}
|
|
496
535
|
return out;
|
|
@@ -505,7 +544,7 @@ export class StateDb {
|
|
|
505
544
|
// would never heal (the 0.8.2-class blind spot, on the UPDATE path).
|
|
506
545
|
updateContent(path, content) {
|
|
507
546
|
this.db
|
|
508
|
-
.prepare("UPDATE sessions SET content = ?, embedding = NULL WHERE path = ?")
|
|
547
|
+
.prepare("UPDATE sessions SET content = ?, embedding = NULL, embedding_model = NULL, embedding_dim = NULL WHERE path = ?")
|
|
509
548
|
.run(content, path);
|
|
510
549
|
}
|
|
511
550
|
reset() {
|
|
@@ -604,10 +643,10 @@ export class StateDb {
|
|
|
604
643
|
AND note_path IS NOT NULL`)
|
|
605
644
|
.all();
|
|
606
645
|
}
|
|
607
|
-
storeArticleEmbedding(path, embedding) {
|
|
646
|
+
storeArticleEmbedding(path, embedding, provenance) {
|
|
608
647
|
this.db
|
|
609
|
-
.prepare("UPDATE articles SET embedding = ? WHERE path = ?")
|
|
610
|
-
.run(JSON.stringify(embedding), path);
|
|
648
|
+
.prepare("UPDATE articles SET embedding = ?, embedding_model = ?, embedding_dim = ? WHERE path = ?")
|
|
649
|
+
.run(JSON.stringify(embedding), provenance.model, provenance.dim, path);
|
|
611
650
|
}
|
|
612
651
|
// Article embeddings, shaped like session EmbeddingRow so the retriever can
|
|
613
652
|
// concat both lists. filePath is the stored note path; project is empty
|
|
@@ -615,8 +654,9 @@ export class StateDb {
|
|
|
615
654
|
getArticleEmbeddings() {
|
|
616
655
|
if (!this.hasArticlesTable())
|
|
617
656
|
return [];
|
|
657
|
+
const prov = this.hasProvenance("articles");
|
|
618
658
|
const rows = this.db
|
|
619
|
-
.prepare(`SELECT note_path, embedding, title, category
|
|
659
|
+
.prepare(`SELECT note_path, embedding, title, category${prov ? ", embedding_model, embedding_dim" : ""}
|
|
620
660
|
FROM articles
|
|
621
661
|
WHERE skipped = 0
|
|
622
662
|
AND error IS NULL
|
|
@@ -644,6 +684,8 @@ export class StateDb {
|
|
|
644
684
|
project: "",
|
|
645
685
|
filePath: r.note_path,
|
|
646
686
|
embedding: vec,
|
|
687
|
+
embeddingModel: r.embedding_model ?? LEGACY_EMBEDDING_PROVENANCE.model,
|
|
688
|
+
embeddingDim: r.embedding_dim ?? vec.length,
|
|
647
689
|
});
|
|
648
690
|
}
|
|
649
691
|
return out;
|
|
@@ -731,10 +773,10 @@ export class StateDb {
|
|
|
731
773
|
AND note_path IS NOT NULL`)
|
|
732
774
|
.all();
|
|
733
775
|
}
|
|
734
|
-
storePdfEmbedding(path, embedding) {
|
|
776
|
+
storePdfEmbedding(path, embedding, provenance) {
|
|
735
777
|
this.db
|
|
736
|
-
.prepare("UPDATE pdfs SET embedding = ? WHERE path = ?")
|
|
737
|
-
.run(JSON.stringify(embedding), path);
|
|
778
|
+
.prepare("UPDATE pdfs SET embedding = ?, embedding_model = ?, embedding_dim = ? WHERE path = ?")
|
|
779
|
+
.run(JSON.stringify(embedding), provenance.model, provenance.dim, path);
|
|
738
780
|
}
|
|
739
781
|
// PDF embeddings, shaped like session/article EmbeddingRow so the retriever can
|
|
740
782
|
// concat all sources. filePath is the stored note path; project is empty (PDFs
|
|
@@ -742,8 +784,9 @@ export class StateDb {
|
|
|
742
784
|
getPdfEmbeddings() {
|
|
743
785
|
if (!this.hasPdfsTable())
|
|
744
786
|
return [];
|
|
787
|
+
const prov = this.hasProvenance("pdfs");
|
|
745
788
|
const rows = this.db
|
|
746
|
-
.prepare(`SELECT note_path, embedding, title, category
|
|
789
|
+
.prepare(`SELECT note_path, embedding, title, category${prov ? ", embedding_model, embedding_dim" : ""}
|
|
747
790
|
FROM pdfs
|
|
748
791
|
WHERE skipped = 0
|
|
749
792
|
AND error IS NULL
|
|
@@ -771,6 +814,8 @@ export class StateDb {
|
|
|
771
814
|
project: "",
|
|
772
815
|
filePath: r.note_path,
|
|
773
816
|
embedding: vec,
|
|
817
|
+
embeddingModel: r.embedding_model ?? LEGACY_EMBEDDING_PROVENANCE.model,
|
|
818
|
+
embeddingDim: r.embedding_dim ?? vec.length,
|
|
774
819
|
});
|
|
775
820
|
}
|
|
776
821
|
return out;
|
|
@@ -784,8 +829,9 @@ export class StateDb {
|
|
|
784
829
|
getTopicEmbeddings(vaultRoot, topicsDir) {
|
|
785
830
|
if (!this.hasTopicsTable())
|
|
786
831
|
return [];
|
|
832
|
+
const prov = this.hasProvenance("topics");
|
|
787
833
|
const rows = this.db
|
|
788
|
-
.prepare(`SELECT id, embedding, title
|
|
834
|
+
.prepare(`SELECT id, embedding, title${prov ? ", embedding_model, embedding_dim" : ""}
|
|
789
835
|
FROM topics
|
|
790
836
|
WHERE embedding IS NOT NULL`)
|
|
791
837
|
.all();
|
|
@@ -810,6 +856,8 @@ export class StateDb {
|
|
|
810
856
|
project: "",
|
|
811
857
|
filePath: join(vaultRoot, topicsDir, `${r.id}.md`),
|
|
812
858
|
embedding: vec,
|
|
859
|
+
embeddingModel: r.embedding_model ?? LEGACY_EMBEDDING_PROVENANCE.model,
|
|
860
|
+
embeddingDim: r.embedding_dim ?? vec.length,
|
|
813
861
|
});
|
|
814
862
|
}
|
|
815
863
|
return out;
|
|
@@ -872,10 +920,10 @@ export class StateDb {
|
|
|
872
920
|
// Future-proofing for v0.7.3 (topic-aware retrieval). Stored now so topics
|
|
873
921
|
// are searchable then without a backfill; the retriever does not read these
|
|
874
922
|
// yet — keeping topics out of `vir query` per the plugin-compat contract.
|
|
875
|
-
storeTopicEmbedding(id, embedding) {
|
|
923
|
+
storeTopicEmbedding(id, embedding, provenance) {
|
|
876
924
|
this.db
|
|
877
|
-
.prepare("UPDATE topics SET embedding = ? WHERE id = ?")
|
|
878
|
-
.run(JSON.stringify(embedding), id);
|
|
925
|
+
.prepare("UPDATE topics SET embedding = ?, embedding_model = ?, embedding_dim = ? WHERE id = ?")
|
|
926
|
+
.run(JSON.stringify(embedding), provenance.model, provenance.dim, id);
|
|
879
927
|
}
|
|
880
928
|
close() {
|
|
881
929
|
this.db.close();
|