daftari 1.9.1 → 1.11.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.
@@ -0,0 +1,425 @@
1
+ // vault_themes — thematic clustering over document-pooled embeddings.
2
+ //
3
+ // Cluster DOCUMENTS, not chunks: for each document we mean-pool its chunk
4
+ // embeddings into one vector, L2-normalise it, and cluster the resulting
5
+ // ~N-doc set. ~3.5k document vectors instead of ~44k chunk vectors makes
6
+ // every algorithm cheap (silhouette becomes tractable on the full set; no
7
+ // sampling needed at this scale).
8
+ //
9
+ // v1 constraints (locked):
10
+ // - One-doc-one-theme. Each document lives in exactly one cluster.
11
+ // - Heuristic labels from TF-IDF over titles + tags. No LLM call.
12
+ // - No new storage — the tool is read-only against the existing
13
+ // embeddings / chunks / documents tables.
14
+ // - Default k-sweep over {10, 15, 20, 25}; an explicit `k` argument
15
+ // skips the sweep.
16
+ // - Deterministic via a fixed seed for the k-means RNG.
17
+ import { canRead } from "../access/rbac.js";
18
+ import { err, ok } from "../frontmatter/types.js";
19
+ import { getProvider } from "../search/vector.js";
20
+ import { blobToEmbedding } from "../storage/index-db.js";
21
+ import { clusterCoherence, kmeans, meanPoolL2, pickK, seededRng, selectSecondaryMemberships, } from "../themes/clustering.js";
22
+ import { ensureIndexReady, openIndexForActiveProvider } from "./search.js";
23
+ // Fixed seed for the k-means RNG. The whole point of vault_themes is that
24
+ // the same vault produces the same themes — a random seed would give the
25
+ // user different themes every run and erode trust in the output.
26
+ const THEMES_RNG_SEED = 0x7da17f1; // arbitrary; constant is what matters
27
+ // Default k-sweep range (from the issue dialogue). Each is clamped to the
28
+ // number of clusterable documents inside pickK.
29
+ const DEFAULT_K_CANDIDATES = [10, 15, 20, 25];
30
+ // k-means iteration cap. Documents on the unit sphere converge fast in
31
+ // practice; this is a safety bound for pathological inputs.
32
+ const KMEANS_MAX_ITER = 50;
33
+ // Representative-doc count returned per theme. 5 is enough to be useful in
34
+ // the UI without dragging in marginal members.
35
+ const REPRESENTATIVE_DOCS_PER_THEME = 5;
36
+ // Tag-frequency cutoff per theme. Five most-common tags is enough signal
37
+ // without burying the user in noise.
38
+ const RELATED_TAGS_PER_THEME = 5;
39
+ // Secondary-membership tuning. A doc qualifies as a secondary member of a
40
+ // non-primary cluster when its centroid similarity is BOTH within DELTA of
41
+ // the primary AND above MIN_ABS_SIMILARITY. The cap prevents a centroid-
42
+ // of-mass doc from showing up in every cluster. Defaults are deliberately
43
+ // conservative — secondaries should surface cross-cutting docs, not bury
44
+ // the primary signal.
45
+ const SECONDARY_DELTA = 0.1;
46
+ const SECONDARY_MIN_SIMILARITY = 0.5;
47
+ const SECONDARY_MAX_PER_DOC = 2;
48
+ // Hard cap on secondaries reported per theme. Same UX rationale as
49
+ // REPRESENTATIVE_DOCS_PER_THEME — enough to be useful, bounded enough to
50
+ // not bury the user.
51
+ const SECONDARY_DOCS_PER_THEME = 5;
52
+ // Tokenisation for TF-IDF labels: lowercase, split on non-alphanumeric,
53
+ // drop stopwords. This is deliberately a smaller list than bm25's — the
54
+ // label step doesn't need FTS5 alignment, and we keep "tag-like" tokens.
55
+ const LABEL_STOPWORDS = new Set([
56
+ "a",
57
+ "an",
58
+ "and",
59
+ "are",
60
+ "as",
61
+ "at",
62
+ "be",
63
+ "but",
64
+ "by",
65
+ "for",
66
+ "from",
67
+ "has",
68
+ "have",
69
+ "in",
70
+ "is",
71
+ "it",
72
+ "its",
73
+ "of",
74
+ "on",
75
+ "or",
76
+ "that",
77
+ "the",
78
+ "their",
79
+ "them",
80
+ "they",
81
+ "this",
82
+ "to",
83
+ "was",
84
+ "were",
85
+ "will",
86
+ "with",
87
+ "you",
88
+ "your",
89
+ ]);
90
+ function labelTokens(text) {
91
+ return text
92
+ .toLowerCase()
93
+ .split(/[^a-z0-9]+/)
94
+ .filter((t) => t.length > 1 && !LABEL_STOPWORDS.has(t));
95
+ }
96
+ // Loads every (path, content_hash, embedding) row for the active model, in
97
+ // path-then-chunk-index order, and groups embeddings by document path.
98
+ function loadEmbeddingsByPath(db, model) {
99
+ const rows = db
100
+ .prepare(`SELECT c.path AS path, e.embedding AS embedding, e.dim AS dim
101
+ FROM chunks c
102
+ LEFT JOIN embeddings e
103
+ ON e.content_hash = c.content_hash AND e.model = ?
104
+ ORDER BY c.path, c.chunk_index`)
105
+ .all(model);
106
+ const provider = getProvider();
107
+ const expectedDim = provider.dim;
108
+ const out = new Map();
109
+ for (const row of rows) {
110
+ if (!row.embedding)
111
+ continue;
112
+ // Defense-in-depth: skip rows whose stored dim disagrees with the
113
+ // provider's expected dim — same guard `getAllChunks` applies.
114
+ const blobOk = row.embedding.length === expectedDim * 4;
115
+ const dimOk = row.dim === expectedDim;
116
+ if (!blobOk || !dimOk)
117
+ continue;
118
+ const vec = blobToEmbedding(row.embedding);
119
+ const list = out.get(row.path);
120
+ if (list)
121
+ list.push(vec);
122
+ else
123
+ out.set(row.path, [vec]);
124
+ }
125
+ return out;
126
+ }
127
+ // Applies the scope filter (collection, tags), RBAC, and the doc-has-an-
128
+ // embedded-chunk requirement; returns the clusterable doc set and the count
129
+ // of docs the embedding requirement skipped.
130
+ function buildScopedDocs(documents, embeddingsByPath, filters, access) {
131
+ const scoped = [];
132
+ let skipped = 0;
133
+ for (const doc of documents) {
134
+ if (filters.collection && doc.collection !== filters.collection)
135
+ continue;
136
+ if (filters.tags && filters.tags.length > 0) {
137
+ const hasAll = filters.tags.every((t) => doc.tags.includes(t));
138
+ if (!hasAll)
139
+ continue;
140
+ }
141
+ if (access && !canRead(access.role, doc.collection))
142
+ continue;
143
+ const chunkVecs = embeddingsByPath.get(doc.path) ?? [];
144
+ const pooled = meanPoolL2(chunkVecs);
145
+ if (!pooled) {
146
+ // No embedded chunks (or an all-zero pool): count as skipped per
147
+ // the v1 contract.
148
+ skipped += 1;
149
+ continue;
150
+ }
151
+ scoped.push({
152
+ path: doc.path,
153
+ title: doc.title,
154
+ collection: doc.collection,
155
+ tags: doc.tags,
156
+ vector: pooled,
157
+ });
158
+ }
159
+ return { scoped, skipped };
160
+ }
161
+ // Cosine similarity for L2-normalised vectors == dot product. Used for
162
+ // representative-doc ranking against a cluster centroid.
163
+ function dotNormalized(a, b) {
164
+ let s = 0;
165
+ const n = Math.min(a.length, b.length);
166
+ for (let i = 0; i < n; i++)
167
+ s += a[i] * b[i];
168
+ return s;
169
+ }
170
+ // TF-IDF over the cluster: term frequency among the cluster's titles +
171
+ // tags, divided by the document-frequency across ALL clusters (so a term
172
+ // that names every theme — e.g. "doc" — doesn't dominate any one of them).
173
+ // Falls back to the most common tags if TF-IDF yields nothing useful, and
174
+ // finally to a generic "theme N" placeholder.
175
+ function buildLabel(clusterDocs, globalDocCount, globalDf, themeIndex) {
176
+ const tf = new Map();
177
+ for (const doc of clusterDocs) {
178
+ const seen = new Set();
179
+ for (const tok of labelTokens(doc.title))
180
+ seen.add(tok);
181
+ for (const tag of doc.tags) {
182
+ for (const tok of labelTokens(tag))
183
+ seen.add(tok);
184
+ }
185
+ for (const tok of seen)
186
+ tf.set(tok, (tf.get(tok) ?? 0) + 1);
187
+ }
188
+ const scored = [];
189
+ for (const [term, freq] of tf) {
190
+ const df = globalDf.get(term) ?? 1;
191
+ // Standard smoothed IDF.
192
+ const idf = Math.log((globalDocCount + 1) / (df + 1)) + 1;
193
+ if (idf <= 0)
194
+ continue;
195
+ scored.push({ term, score: freq * idf });
196
+ }
197
+ scored.sort((a, b) => b.score - a.score);
198
+ const top = scored.slice(0, 3).map((s) => s.term);
199
+ if (top.length > 0)
200
+ return top.join(" / ");
201
+ // Fallback: most common tags.
202
+ const tagFreq = new Map();
203
+ for (const doc of clusterDocs) {
204
+ for (const tag of doc.tags)
205
+ tagFreq.set(tag, (tagFreq.get(tag) ?? 0) + 1);
206
+ }
207
+ const topTags = [...tagFreq.entries()]
208
+ .sort((a, b) => b[1] - a[1])
209
+ .slice(0, 3)
210
+ .map(([t]) => t);
211
+ if (topTags.length > 0)
212
+ return topTags.join(" / ");
213
+ return `theme ${themeIndex + 1}`;
214
+ }
215
+ // Builds the global document-frequency map across the clustered set. Used
216
+ // by buildLabel; computed once and shared because every cluster's IDF must
217
+ // agree on the document base.
218
+ function buildGlobalDf(docs) {
219
+ const df = new Map();
220
+ for (const doc of docs) {
221
+ const seen = new Set();
222
+ for (const tok of labelTokens(doc.title))
223
+ seen.add(tok);
224
+ for (const tag of doc.tags) {
225
+ for (const tok of labelTokens(tag))
226
+ seen.add(tok);
227
+ }
228
+ for (const tok of seen)
229
+ df.set(tok, (df.get(tok) ?? 0) + 1);
230
+ }
231
+ return df;
232
+ }
233
+ function topTagsForCluster(clusterDocs) {
234
+ const freq = new Map();
235
+ for (const doc of clusterDocs) {
236
+ for (const tag of doc.tags)
237
+ freq.set(tag, (freq.get(tag) ?? 0) + 1);
238
+ }
239
+ return [...freq.entries()]
240
+ .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
241
+ .slice(0, RELATED_TAGS_PER_THEME)
242
+ .map(([t]) => t);
243
+ }
244
+ function representativesForCluster(clusterDocs, centroid) {
245
+ return [...clusterDocs]
246
+ .map((d) => ({ path: d.path, sim: dotNormalized(d.vector, centroid) }))
247
+ .sort((a, b) => b.sim - a.sim || a.path.localeCompare(b.path))
248
+ .slice(0, REPRESENTATIVE_DOCS_PER_THEME)
249
+ .map((d) => d.path);
250
+ }
251
+ function parseArgs(args) {
252
+ let k;
253
+ if (args.k !== undefined) {
254
+ if (typeof args.k !== "number" || !Number.isInteger(args.k) || args.k <= 0) {
255
+ return err(new Error("vault_themes: 'k' must be a positive integer when provided"));
256
+ }
257
+ k = args.k;
258
+ }
259
+ const collection = typeof args.collection === "string" && args.collection.length > 0 ? args.collection : undefined;
260
+ let tags;
261
+ if (Array.isArray(args.tags)) {
262
+ const filtered = args.tags.filter((t) => typeof t === "string" && t.length > 0);
263
+ if (filtered.length > 0)
264
+ tags = filtered;
265
+ }
266
+ return ok({ k, collection, tags });
267
+ }
268
+ export async function vaultThemes(vaultRoot, args, access) {
269
+ const parsed = parseArgs(args);
270
+ if (!parsed.ok)
271
+ return parsed;
272
+ const ready = await ensureIndexReady(vaultRoot);
273
+ if (!ready.ok)
274
+ return ready;
275
+ const dbResult = openIndexForActiveProvider(vaultRoot);
276
+ if (!dbResult.ok)
277
+ return dbResult;
278
+ const db = dbResult.value;
279
+ try {
280
+ const provider = getProvider();
281
+ const docRows = db
282
+ .prepare("SELECT path, title, collection, tags FROM documents ORDER BY path")
283
+ .all();
284
+ const documents = docRows.map((r) => ({
285
+ path: r.path,
286
+ title: r.title,
287
+ collection: r.collection,
288
+ domain: "",
289
+ status: "",
290
+ confidence: "",
291
+ updated: "",
292
+ tags: JSON.parse(r.tags),
293
+ content: "",
294
+ tokens: [],
295
+ ttlDays: null,
296
+ created: "",
297
+ supersededBy: null,
298
+ }));
299
+ const embeddingsByPath = loadEmbeddingsByPath(db, provider.id);
300
+ const { scoped, skipped } = buildScopedDocs(documents, embeddingsByPath, parsed.value, access);
301
+ if (scoped.length === 0) {
302
+ return ok({
303
+ themes: [],
304
+ totalDocuments: 0,
305
+ skippedDocuments: skipped,
306
+ selectedK: 0,
307
+ clusteredAt: new Date().toISOString(),
308
+ });
309
+ }
310
+ const vectors = scoped.map((s) => s.vector);
311
+ const rng = seededRng(THEMES_RNG_SEED);
312
+ let selectedK;
313
+ let assignments;
314
+ let centroids;
315
+ if (parsed.value.k !== undefined) {
316
+ const result = kmeans(vectors, parsed.value.k, rng, KMEANS_MAX_ITER);
317
+ selectedK = result.centroids.length;
318
+ assignments = result.assignments;
319
+ centroids = result.centroids;
320
+ }
321
+ else {
322
+ const result = pickK(vectors, DEFAULT_K_CANDIDATES, rng, KMEANS_MAX_ITER);
323
+ selectedK = result.centroids.length;
324
+ assignments = result.assignments;
325
+ centroids = result.centroids;
326
+ }
327
+ // Group docs by cluster.
328
+ const byCluster = new Map();
329
+ for (let i = 0; i < scoped.length; i++) {
330
+ const c = assignments[i];
331
+ const doc = scoped[i];
332
+ const list = byCluster.get(c);
333
+ if (list)
334
+ list.push(doc);
335
+ else
336
+ byCluster.set(c, [doc]);
337
+ }
338
+ const globalDf = buildGlobalDf(scoped);
339
+ // Secondary memberships: for each doc, find non-primary clusters its
340
+ // pooled vector also aligns with. This is the soft-reporting layer on
341
+ // top of the hard partition — it does NOT change documentCount, which
342
+ // still reflects primary membership only.
343
+ const secondaryByCluster = selectSecondaryMemberships(vectors, assignments, centroids, {
344
+ delta: SECONDARY_DELTA,
345
+ minSimilarity: SECONDARY_MIN_SIMILARITY,
346
+ maxPerDoc: SECONDARY_MAX_PER_DOC,
347
+ });
348
+ const themes = [];
349
+ let themeIndex = 0;
350
+ for (const [clusterIdx, clusterDocs] of byCluster) {
351
+ if (clusterDocs.length === 0)
352
+ continue;
353
+ const centroid = centroids[clusterIdx];
354
+ if (!centroid)
355
+ continue;
356
+ // Singleton clusters have no pairs to average — return null rather
357
+ // than the mathematically-trivial 1.0, which would falsely imply
358
+ // tightness.
359
+ const coherence = clusterDocs.length < 2 ? null : clusterCoherence(clusterDocs.map((d) => d.vector));
360
+ const secondaries = (secondaryByCluster.get(clusterIdx) ?? [])
361
+ .slice(0, SECONDARY_DOCS_PER_THEME)
362
+ .map((s) => scoped[s.docIndex].path);
363
+ themes.push({
364
+ label: buildLabel(clusterDocs, scoped.length, globalDf, themeIndex),
365
+ documentCount: clusterDocs.length,
366
+ coherence,
367
+ representativeDocs: representativesForCluster(clusterDocs, centroid),
368
+ secondaryDocs: secondaries,
369
+ relatedTags: topTagsForCluster(clusterDocs),
370
+ });
371
+ themeIndex += 1;
372
+ }
373
+ themes.sort((a, b) => b.documentCount - a.documentCount || a.label.localeCompare(b.label));
374
+ return ok({
375
+ themes,
376
+ totalDocuments: scoped.length,
377
+ skippedDocuments: skipped,
378
+ selectedK,
379
+ clusteredAt: new Date().toISOString(),
380
+ });
381
+ }
382
+ finally {
383
+ db.close();
384
+ }
385
+ }
386
+ // ---------------------------------------------------------------------------
387
+ // MCP tool definition
388
+ // ---------------------------------------------------------------------------
389
+ export const themesTools = [
390
+ {
391
+ name: "vault_themes",
392
+ description: "Surface thematic clusters across the vault using k-means over " +
393
+ "document-pooled embeddings. Each document's chunk vectors are " +
394
+ "mean-pooled into one vector, L2-normalised, and clustered. By " +
395
+ "default the tool sweeps k ∈ {10, 15, 20, 25} and picks the k with " +
396
+ "the best mean silhouette; pass `k` to skip the sweep. Each theme " +
397
+ "reports a heuristic label (TF-IDF over titles + tags), a coherence " +
398
+ "score (mean pairwise cosine inside the cluster), representative " +
399
+ "documents nearest the centroid, and the most frequent tags. " +
400
+ "Output is deterministic for the same vault.",
401
+ inputSchema: {
402
+ type: "object",
403
+ properties: {
404
+ k: {
405
+ type: "integer",
406
+ description: "Optional explicit cluster count. When omitted, the tool sweeps " +
407
+ "k ∈ {10, 15, 20, 25} and picks the k with the best silhouette.",
408
+ minimum: 1,
409
+ },
410
+ collection: {
411
+ type: "string",
412
+ description: "Restrict clustering to documents in this collection.",
413
+ },
414
+ tags: {
415
+ type: "array",
416
+ items: { type: "string" },
417
+ description: "Restrict to documents that have all of these tags.",
418
+ },
419
+ },
420
+ additionalProperties: false,
421
+ },
422
+ handler: (vaultRoot, args, access) => vaultThemes(vaultRoot, args, access),
423
+ },
424
+ ];
425
+ //# sourceMappingURL=themes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themes.js","sourceRoot":"","sources":["../../src/tools/themes.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "daftari",
3
- "version": "1.9.1",
3
+ "version": "1.11.0",
4
4
  "description": "An open-source, multi-user knowledge vault exposed to AI agents via an MCP server.",
5
5
  "license": "MIT",
6
6
  "author": "Mihir Wagle / mavaali",