@djolex999/vir-cli 0.14.0 → 0.15.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 +265 -264
- package/dist/cli/embedSetup.js +62 -0
- package/dist/cli/embedSetup.js.map +1 -0
- package/dist/cli.js +70 -18
- package/dist/cli.js.map +1 -1
- package/dist/config.js +5 -0
- package/dist/config.js.map +1 -1
- package/dist/diagnostics/doctor.js +116 -18
- package/dist/diagnostics/doctor.js.map +1 -1
- package/dist/pipeline/embeddingSweep.js +17 -11
- package/dist/pipeline/embeddingSweep.js.map +1 -1
- package/dist/pipeline/projects.js +44 -7
- package/dist/pipeline/projects.js.map +1 -1
- package/dist/pipeline/run.js +33 -18
- 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/retriever.js +39 -12
- 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 +68 -17
- package/dist/state/db.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
export const LOCAL_EMBED_MODEL = "bge-small-en-v1.5";
|
|
7
|
+
export const LOCAL_EMBED_DIM = 384;
|
|
8
|
+
// bge-small truncates at 512 tokens. 2000 chars ≈ 500 tokens on the chars/4
|
|
9
|
+
// heuristic — under the model's own cutoff, so what we record as "sent" is
|
|
10
|
+
// what the model actually saw, same discipline as the Ollama context fix.
|
|
11
|
+
export const LOCAL_MAX_CHARS = 2000;
|
|
12
|
+
// fastembed is ~233 MB of node_modules — far too heavy to ship as a dependency
|
|
13
|
+
// of a ~200 KB CLI, so it lives in its own npm prefix under ~/.vir, installed
|
|
14
|
+
// on demand by `vir embed --setup` and loaded dynamically from there.
|
|
15
|
+
export const LOCAL_PROVIDER_DIR = join(homedir(), ".vir", "embedder");
|
|
16
|
+
export const LOCAL_MODEL_CACHE_DIR = join(LOCAL_PROVIDER_DIR, "model-cache");
|
|
17
|
+
// Measured on the 2026-07-31 scratchpad experiment (fastembed 2.1.0, darwin).
|
|
18
|
+
export const SETUP_INSTALL_MB = 233;
|
|
19
|
+
export const SETUP_MODEL_MB = 128;
|
|
20
|
+
export function isLocalProviderInstalled(dir = LOCAL_PROVIDER_DIR) {
|
|
21
|
+
return existsSync(join(dir, "node_modules", "fastembed"));
|
|
22
|
+
}
|
|
23
|
+
async function loadFastembedEngine() {
|
|
24
|
+
const req = createRequire(join(LOCAL_PROVIDER_DIR, "package.json"));
|
|
25
|
+
const resolved = req.resolve("fastembed");
|
|
26
|
+
const imported = (await import(pathToFileURL(resolved).href));
|
|
27
|
+
const mod = "FlagEmbedding" in imported ? imported : imported.default;
|
|
28
|
+
const model = await mod.FlagEmbedding.init({
|
|
29
|
+
model: mod.EmbeddingModel["BGESmallENV15"] ?? "fast-bge-small-en-v1.5",
|
|
30
|
+
cacheDir: LOCAL_MODEL_CACHE_DIR,
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
embedBatch: async (texts) => {
|
|
34
|
+
const out = [];
|
|
35
|
+
for await (const batch of model.embed(texts, 16)) {
|
|
36
|
+
for (const v of batch)
|
|
37
|
+
out.push(Array.from(v));
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
},
|
|
41
|
+
queryEmbed: async (text) => Array.from(await model.queryEmbed(text)),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export class LocalProvider {
|
|
45
|
+
engineFactory;
|
|
46
|
+
name = "local";
|
|
47
|
+
modelName = LOCAL_EMBED_MODEL;
|
|
48
|
+
dimensions = LOCAL_EMBED_DIM;
|
|
49
|
+
maxInputChars = LOCAL_MAX_CHARS;
|
|
50
|
+
enginePromise = null;
|
|
51
|
+
// engineFactory is injectable for tests only — production callers pass
|
|
52
|
+
// nothing and get the real fastembed load from LOCAL_PROVIDER_DIR.
|
|
53
|
+
constructor(engineFactory = loadFastembedEngine) {
|
|
54
|
+
this.engineFactory = engineFactory;
|
|
55
|
+
}
|
|
56
|
+
engine() {
|
|
57
|
+
this.enginePromise ??= this.engineFactory();
|
|
58
|
+
return this.enginePromise;
|
|
59
|
+
}
|
|
60
|
+
async available() {
|
|
61
|
+
return isLocalProviderInstalled();
|
|
62
|
+
}
|
|
63
|
+
async embedDoc(text) {
|
|
64
|
+
const sent = text.slice(0, this.maxInputChars);
|
|
65
|
+
const vecs = await (await this.engine()).embedBatch([sent]);
|
|
66
|
+
const embedding = vecs[0];
|
|
67
|
+
if (!embedding || embedding.length === 0) {
|
|
68
|
+
throw new Error("fastembed returned no embedding");
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
embedding,
|
|
72
|
+
sentChars: sent.length,
|
|
73
|
+
truncated: sent.length < text.length,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
async embedQuery(text) {
|
|
77
|
+
return (await this.engine()).queryEmbed(text.slice(0, this.maxInputChars));
|
|
78
|
+
}
|
|
79
|
+
provenance() {
|
|
80
|
+
return { model: this.modelName, dim: this.dimensions };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// The cost statement `vir embed --setup` prints BEFORE touching the disk or
|
|
84
|
+
// the network. quiet=true drops the decorative lines but never the numbers.
|
|
85
|
+
export function buildSetupPlan(installed, quiet) {
|
|
86
|
+
const lines = [];
|
|
87
|
+
if (installed) {
|
|
88
|
+
lines.push("fastembed already installed — skipping the package install.");
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
lines.push(`This installs fastembed (~${SETUP_INSTALL_MB} MB of node_modules) into ${LOCAL_PROVIDER_DIR}`);
|
|
92
|
+
}
|
|
93
|
+
lines.push(`and downloads the ${LOCAL_EMBED_MODEL} model (~${SETUP_MODEL_MB} MB) on first embed.`);
|
|
94
|
+
if (!quiet) {
|
|
95
|
+
lines.push("Nothing outside ~/.vir is touched; remove that folder to undo.");
|
|
96
|
+
}
|
|
97
|
+
return { lines, needsInstall: !installed };
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=localProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localProvider.js","sourceRoot":"","sources":["../../src/search/localProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { EMBED_DIM, EMBED_MAX_CHARS, EMBED_MODEL, EmbedderError, embed, embedText, isOllamaAvailable, } from "./embedder.js";
|
|
2
|
+
import { LocalProvider, isLocalProviderInstalled } from "./localProvider.js";
|
|
3
|
+
// Resolution order: configured > Ollama detected > local installed > none.
|
|
4
|
+
// `none` is a supported floor (TF-IDF), never an error state — so a configured
|
|
5
|
+
// provider that turns out unusable falls through to detection instead of
|
|
6
|
+
// blocking. Returns null for none.
|
|
7
|
+
export async function resolveEmbeddingProvider(configured, probes = {}) {
|
|
8
|
+
const ollamaUp = probes.ollamaAvailable ?? isOllamaAvailable;
|
|
9
|
+
const localUp = probes.localInstalled ?? isLocalProviderInstalled;
|
|
10
|
+
if (configured === "none")
|
|
11
|
+
return null;
|
|
12
|
+
if (configured === "ollama" && (await ollamaUp()))
|
|
13
|
+
return new OllamaProvider();
|
|
14
|
+
if (configured === "local" && localUp())
|
|
15
|
+
return new LocalProvider();
|
|
16
|
+
if (await ollamaUp())
|
|
17
|
+
return new OllamaProvider();
|
|
18
|
+
if (localUp())
|
|
19
|
+
return new LocalProvider();
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
// Module-level memo mirroring isOllamaAvailableCached: one resolution per
|
|
23
|
+
// process is enough (the daemon restarts every run). Not per-config — a single
|
|
24
|
+
// process never runs two configs.
|
|
25
|
+
let _resolvedProvider = null;
|
|
26
|
+
export function resolveActiveProviderCached(configured) {
|
|
27
|
+
_resolvedProvider ??= resolveEmbeddingProvider(configured);
|
|
28
|
+
return _resolvedProvider;
|
|
29
|
+
}
|
|
30
|
+
// Best-effort embed through a provider: never throws, returns null on failure,
|
|
31
|
+
// reports truncation and failure kind through `log` — the provider-agnostic
|
|
32
|
+
// successor of embedder.ts's embeddingForNote.
|
|
33
|
+
export async function embedNoteWithProvider(provider, text, log) {
|
|
34
|
+
try {
|
|
35
|
+
const result = await provider.embedDoc(text);
|
|
36
|
+
if (result.truncated) {
|
|
37
|
+
log?.(`embedding truncated: sent ${result.sentChars} of ${text.length} chars (model context limit)`);
|
|
38
|
+
}
|
|
39
|
+
return result.embedding;
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
const kind = err instanceof EmbedderError ? err.kind : "network";
|
|
43
|
+
log?.(`embed failed (${kind}): ${err.message}`);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export class OllamaProvider {
|
|
48
|
+
fetchImpl;
|
|
49
|
+
name = "ollama";
|
|
50
|
+
modelName = EMBED_MODEL;
|
|
51
|
+
dimensions = EMBED_DIM;
|
|
52
|
+
maxInputChars = EMBED_MAX_CHARS;
|
|
53
|
+
// fetchImpl is injectable for tests only — production callers pass nothing.
|
|
54
|
+
constructor(fetchImpl) {
|
|
55
|
+
this.fetchImpl = fetchImpl;
|
|
56
|
+
}
|
|
57
|
+
available() {
|
|
58
|
+
return isOllamaAvailable();
|
|
59
|
+
}
|
|
60
|
+
embedDoc(text) {
|
|
61
|
+
return embedText(text, this.fetchImpl);
|
|
62
|
+
}
|
|
63
|
+
// Routed through embed() (not embedText directly) so test suites that mock
|
|
64
|
+
// the embedder module intercept query embedding the same way they always have.
|
|
65
|
+
embedQuery(text) {
|
|
66
|
+
return embed(text, this.fetchImpl);
|
|
67
|
+
}
|
|
68
|
+
provenance() {
|
|
69
|
+
return { model: this.modelName, dim: this.dimensions };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/search/provider.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,7 +10,7 @@ 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
|
|
@@ -27,8 +29,9 @@ export async function search(cfg, db, query, topK = 8) {
|
|
|
27
29
|
return (await searchWithOutcome(cfg, db, query, topK)).hits;
|
|
28
30
|
}
|
|
29
31
|
export async function searchWithOutcome(cfg, db, query, topK = 8) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
const provider = await resolveEmbeddingProvider(cfg.embeddingProvider);
|
|
33
|
+
if (provider) {
|
|
34
|
+
const attempt = await searchByEmbedding(cfg, db, query, topK, provider);
|
|
32
35
|
// If embeddings produced at least one match above the floor, take it.
|
|
33
36
|
// Otherwise fall through to TF-IDF: low cosine on every doc means the
|
|
34
37
|
// query is semantically off; lexical overlap might still find a match.
|
|
@@ -38,6 +41,8 @@ export async function searchWithOutcome(cfg, db, query, topK = 8) {
|
|
|
38
41
|
method: "embedding",
|
|
39
42
|
degraded: false,
|
|
40
43
|
embedError: null,
|
|
44
|
+
excludedMismatched: attempt.excluded,
|
|
45
|
+
noProvider: false,
|
|
41
46
|
};
|
|
42
47
|
}
|
|
43
48
|
return {
|
|
@@ -45,43 +50,61 @@ export async function searchWithOutcome(cfg, db, query, topK = 8) {
|
|
|
45
50
|
method: "tfidf",
|
|
46
51
|
degraded: attempt.error !== null,
|
|
47
52
|
embedError: attempt.error,
|
|
53
|
+
excludedMismatched: attempt.excluded,
|
|
54
|
+
noProvider: false,
|
|
48
55
|
};
|
|
49
56
|
}
|
|
57
|
+
// TF-IDF is the supported floor, not a degraded state — but the caller must
|
|
58
|
+
// be able to say "no provider" rather than "embeddings failed".
|
|
50
59
|
return {
|
|
51
60
|
hits: searchByTfIdf(cfg, query, topK),
|
|
52
61
|
method: "tfidf",
|
|
53
62
|
degraded: false,
|
|
54
63
|
embedError: null,
|
|
64
|
+
excludedMismatched: 0,
|
|
65
|
+
noProvider: true,
|
|
55
66
|
};
|
|
56
67
|
}
|
|
57
|
-
|
|
68
|
+
// Splits an embedding pool into rows comparable with the active model and a
|
|
69
|
+
// count of refusals. Cosine between vectors from different models (or different
|
|
70
|
+
// dimensionalities) is meaningless, so those rows must never enter the ranking.
|
|
71
|
+
export function partitionByEmbeddingModel(rows, activeModel) {
|
|
72
|
+
const compatible = rows.filter((r) => r.embeddingModel === activeModel);
|
|
73
|
+
return { compatible, excluded: rows.length - compatible.length };
|
|
74
|
+
}
|
|
75
|
+
async function searchByEmbedding(cfg, db, query, topK, provider) {
|
|
58
76
|
let queryVec;
|
|
59
77
|
try {
|
|
60
|
-
queryVec = await
|
|
78
|
+
queryVec = await provider.embedQuery(query);
|
|
61
79
|
}
|
|
62
80
|
catch (err) {
|
|
63
|
-
return { hits: [], error: err.message };
|
|
81
|
+
return { hits: [], error: err.message, excluded: 0 };
|
|
64
82
|
}
|
|
65
83
|
const root = vaultRoot(cfg);
|
|
66
84
|
// Sessions, articles, topics, and PDFs are embedded into the same vector
|
|
67
85
|
// space; concat all four so semantic search covers every layer. No layer gets
|
|
68
86
|
// a ranking boost — they compete on cosine like everything else.
|
|
69
|
-
const
|
|
87
|
+
const allRows = [
|
|
70
88
|
...db.getEmbeddings(root),
|
|
71
89
|
...db.getArticleEmbeddings(),
|
|
72
90
|
...db.getTopicEmbeddings(root, cfg.topicsDir),
|
|
73
91
|
...db.getPdfEmbeddings(),
|
|
74
92
|
];
|
|
93
|
+
// Vectors from another model are geometric nonsense against this query —
|
|
94
|
+
// refuse to compare them. Excluded rows are counted, never silently dropped;
|
|
95
|
+
// they re-enter search once re-embedded under the active model.
|
|
96
|
+
const { compatible: rows, excluded } = partitionByEmbeddingModel(allRows, provider.modelName);
|
|
75
97
|
if (rows.length === 0)
|
|
76
|
-
return { hits: [], error: null };
|
|
98
|
+
return { hits: [], error: null, excluded };
|
|
77
99
|
// Read each candidate's content once, here, so the verified boost can be
|
|
78
100
|
// applied BEFORE the topK slice — a verified note must be able to outrank an
|
|
79
101
|
// unverified one just outside the window. Reads are bounded to docs above the
|
|
80
102
|
// cosine floor (a personal-scale vault), and the content is reused for hits.
|
|
103
|
+
const minScore = thresholdsFor(provider.modelName).minEmbeddingScore;
|
|
81
104
|
const enriched = [];
|
|
82
105
|
for (const r of rows) {
|
|
83
106
|
const s = cosineSimilarity(queryVec, r.embedding);
|
|
84
|
-
if (s <
|
|
107
|
+
if (s < minScore)
|
|
85
108
|
continue;
|
|
86
109
|
let content = "";
|
|
87
110
|
try {
|
|
@@ -120,7 +143,7 @@ async function searchByEmbedding(cfg, db, query, topK) {
|
|
|
120
143
|
method: "embedding",
|
|
121
144
|
};
|
|
122
145
|
});
|
|
123
|
-
return { hits, error: null };
|
|
146
|
+
return { hits, error: null, excluded };
|
|
124
147
|
}
|
|
125
148
|
// Maximal Marginal Relevance: greedily reranks a candidate pool to trade off
|
|
126
149
|
// relevance against diversity. lambda is the relevance weight — 1.0 is pure
|
|
@@ -229,7 +252,11 @@ export function searchTfIdf(docs, query, topK = 8) {
|
|
|
229
252
|
const df = dfMap.get(term) ?? 0;
|
|
230
253
|
if (df === 0)
|
|
231
254
|
continue;
|
|
232
|
-
|
|
255
|
+
// Smoothed: log(1 + N/df), never zero. Bare log(N/df) is 0 whenever
|
|
256
|
+
// df === N — which is EVERY term in a single-note vault, making the
|
|
257
|
+
// first note a new user creates unfindable. log(1+x) → log(x) for
|
|
258
|
+
// large x, so established-vault rankings are essentially unchanged.
|
|
259
|
+
const idf = Math.log(1 + totalDocs / df);
|
|
233
260
|
// Normalize TF by doc length so long docs don't dominate.
|
|
234
261
|
const tfNorm = tf / Math.max(1, d.tokens.length);
|
|
235
262
|
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;
|
|
@@ -500,9 +539,12 @@ export class StateDb {
|
|
|
500
539
|
.prepare("UPDATE sessions SET archived = 1 WHERE path = ?")
|
|
501
540
|
.run(path);
|
|
502
541
|
}
|
|
542
|
+
// New content invalidates the stored vector — NULL it so the self-heal sweep
|
|
543
|
+
// re-embeds. The sweep only fills NULLs, so a stale non-NULL embedding here
|
|
544
|
+
// would never heal (the 0.8.2-class blind spot, on the UPDATE path).
|
|
503
545
|
updateContent(path, content) {
|
|
504
546
|
this.db
|
|
505
|
-
.prepare("UPDATE sessions SET content =
|
|
547
|
+
.prepare("UPDATE sessions SET content = ?, embedding = NULL, embedding_model = NULL, embedding_dim = NULL WHERE path = ?")
|
|
506
548
|
.run(content, path);
|
|
507
549
|
}
|
|
508
550
|
reset() {
|
|
@@ -601,10 +643,10 @@ export class StateDb {
|
|
|
601
643
|
AND note_path IS NOT NULL`)
|
|
602
644
|
.all();
|
|
603
645
|
}
|
|
604
|
-
storeArticleEmbedding(path, embedding) {
|
|
646
|
+
storeArticleEmbedding(path, embedding, provenance) {
|
|
605
647
|
this.db
|
|
606
|
-
.prepare("UPDATE articles SET embedding = ? WHERE path = ?")
|
|
607
|
-
.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);
|
|
608
650
|
}
|
|
609
651
|
// Article embeddings, shaped like session EmbeddingRow so the retriever can
|
|
610
652
|
// concat both lists. filePath is the stored note path; project is empty
|
|
@@ -612,8 +654,9 @@ export class StateDb {
|
|
|
612
654
|
getArticleEmbeddings() {
|
|
613
655
|
if (!this.hasArticlesTable())
|
|
614
656
|
return [];
|
|
657
|
+
const prov = this.hasProvenance("articles");
|
|
615
658
|
const rows = this.db
|
|
616
|
-
.prepare(`SELECT note_path, embedding, title, category
|
|
659
|
+
.prepare(`SELECT note_path, embedding, title, category${prov ? ", embedding_model, embedding_dim" : ""}
|
|
617
660
|
FROM articles
|
|
618
661
|
WHERE skipped = 0
|
|
619
662
|
AND error IS NULL
|
|
@@ -641,6 +684,8 @@ export class StateDb {
|
|
|
641
684
|
project: "",
|
|
642
685
|
filePath: r.note_path,
|
|
643
686
|
embedding: vec,
|
|
687
|
+
embeddingModel: r.embedding_model ?? LEGACY_EMBEDDING_PROVENANCE.model,
|
|
688
|
+
embeddingDim: r.embedding_dim ?? vec.length,
|
|
644
689
|
});
|
|
645
690
|
}
|
|
646
691
|
return out;
|
|
@@ -728,10 +773,10 @@ export class StateDb {
|
|
|
728
773
|
AND note_path IS NOT NULL`)
|
|
729
774
|
.all();
|
|
730
775
|
}
|
|
731
|
-
storePdfEmbedding(path, embedding) {
|
|
776
|
+
storePdfEmbedding(path, embedding, provenance) {
|
|
732
777
|
this.db
|
|
733
|
-
.prepare("UPDATE pdfs SET embedding = ? WHERE path = ?")
|
|
734
|
-
.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);
|
|
735
780
|
}
|
|
736
781
|
// PDF embeddings, shaped like session/article EmbeddingRow so the retriever can
|
|
737
782
|
// concat all sources. filePath is the stored note path; project is empty (PDFs
|
|
@@ -739,8 +784,9 @@ export class StateDb {
|
|
|
739
784
|
getPdfEmbeddings() {
|
|
740
785
|
if (!this.hasPdfsTable())
|
|
741
786
|
return [];
|
|
787
|
+
const prov = this.hasProvenance("pdfs");
|
|
742
788
|
const rows = this.db
|
|
743
|
-
.prepare(`SELECT note_path, embedding, title, category
|
|
789
|
+
.prepare(`SELECT note_path, embedding, title, category${prov ? ", embedding_model, embedding_dim" : ""}
|
|
744
790
|
FROM pdfs
|
|
745
791
|
WHERE skipped = 0
|
|
746
792
|
AND error IS NULL
|
|
@@ -768,6 +814,8 @@ export class StateDb {
|
|
|
768
814
|
project: "",
|
|
769
815
|
filePath: r.note_path,
|
|
770
816
|
embedding: vec,
|
|
817
|
+
embeddingModel: r.embedding_model ?? LEGACY_EMBEDDING_PROVENANCE.model,
|
|
818
|
+
embeddingDim: r.embedding_dim ?? vec.length,
|
|
771
819
|
});
|
|
772
820
|
}
|
|
773
821
|
return out;
|
|
@@ -781,8 +829,9 @@ export class StateDb {
|
|
|
781
829
|
getTopicEmbeddings(vaultRoot, topicsDir) {
|
|
782
830
|
if (!this.hasTopicsTable())
|
|
783
831
|
return [];
|
|
832
|
+
const prov = this.hasProvenance("topics");
|
|
784
833
|
const rows = this.db
|
|
785
|
-
.prepare(`SELECT id, embedding, title
|
|
834
|
+
.prepare(`SELECT id, embedding, title${prov ? ", embedding_model, embedding_dim" : ""}
|
|
786
835
|
FROM topics
|
|
787
836
|
WHERE embedding IS NOT NULL`)
|
|
788
837
|
.all();
|
|
@@ -807,6 +856,8 @@ export class StateDb {
|
|
|
807
856
|
project: "",
|
|
808
857
|
filePath: join(vaultRoot, topicsDir, `${r.id}.md`),
|
|
809
858
|
embedding: vec,
|
|
859
|
+
embeddingModel: r.embedding_model ?? LEGACY_EMBEDDING_PROVENANCE.model,
|
|
860
|
+
embeddingDim: r.embedding_dim ?? vec.length,
|
|
810
861
|
});
|
|
811
862
|
}
|
|
812
863
|
return out;
|
|
@@ -869,10 +920,10 @@ export class StateDb {
|
|
|
869
920
|
// Future-proofing for v0.7.3 (topic-aware retrieval). Stored now so topics
|
|
870
921
|
// are searchable then without a backfill; the retriever does not read these
|
|
871
922
|
// yet — keeping topics out of `vir query` per the plugin-compat contract.
|
|
872
|
-
storeTopicEmbedding(id, embedding) {
|
|
923
|
+
storeTopicEmbedding(id, embedding, provenance) {
|
|
873
924
|
this.db
|
|
874
|
-
.prepare("UPDATE topics SET embedding = ? WHERE id = ?")
|
|
875
|
-
.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);
|
|
876
927
|
}
|
|
877
928
|
close() {
|
|
878
929
|
this.db.close();
|