@nxuss/lemma 0.9.2 → 1.0.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.
Files changed (69) hide show
  1. package/README.md +79 -12
  2. package/bin/cli.js +97 -0
  3. package/bin/init.js +307 -0
  4. package/cache-proxy.js +191 -0
  5. package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
  6. package/dist/cjs/cli/lemma-proxy.js +2 -4
  7. package/dist/cjs/cli/lemma-proxy.js.map +1 -1
  8. package/dist/cjs/mcp/index.js +1 -1
  9. package/dist/cjs/mcp/tools.d.ts.map +1 -1
  10. package/dist/cjs/mcp/tools.js +911 -71
  11. package/dist/cjs/mcp/tools.js.map +1 -1
  12. package/dist/cjs/subconscious/TheBrainV2.d.ts +102 -0
  13. package/dist/cjs/subconscious/TheBrainV2.d.ts.map +1 -0
  14. package/dist/cjs/subconscious/TheBrainV2.js +444 -0
  15. package/dist/cjs/subconscious/TheBrainV2.js.map +1 -0
  16. package/dist/cjs/utils/ContextCollapser.d.ts +21 -0
  17. package/dist/cjs/utils/ContextCollapser.d.ts.map +1 -0
  18. package/dist/cjs/utils/ContextCollapser.js +132 -0
  19. package/dist/cjs/utils/ContextCollapser.js.map +1 -0
  20. package/dist/cjs/utils/ExecutiveReport.d.ts +29 -0
  21. package/dist/cjs/utils/ExecutiveReport.d.ts.map +1 -0
  22. package/dist/cjs/utils/ExecutiveReport.js +111 -0
  23. package/dist/cjs/utils/ExecutiveReport.js.map +1 -0
  24. package/dist/cjs/utils/SurgicalASTInsert.d.ts +21 -0
  25. package/dist/cjs/utils/SurgicalASTInsert.d.ts.map +1 -0
  26. package/dist/cjs/utils/SurgicalASTInsert.js +173 -0
  27. package/dist/cjs/utils/SurgicalASTInsert.js.map +1 -0
  28. package/dist/cjs/utils/SymbolSurgicalContext.d.ts +25 -0
  29. package/dist/cjs/utils/SymbolSurgicalContext.d.ts.map +1 -0
  30. package/dist/cjs/utils/SymbolSurgicalContext.js +265 -0
  31. package/dist/cjs/utils/SymbolSurgicalContext.js.map +1 -0
  32. package/dist/cjs/utils/WormholeCompressor.d.ts +22 -0
  33. package/dist/cjs/utils/WormholeCompressor.d.ts.map +1 -0
  34. package/dist/cjs/utils/WormholeCompressor.js +152 -0
  35. package/dist/cjs/utils/WormholeCompressor.js.map +1 -0
  36. package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
  37. package/dist/esm/cli/lemma-proxy.js +2 -4
  38. package/dist/esm/cli/lemma-proxy.js.map +1 -1
  39. package/dist/esm/mcp/index.js +1 -1
  40. package/dist/esm/mcp/tools.d.ts.map +1 -1
  41. package/dist/esm/mcp/tools.js +911 -71
  42. package/dist/esm/mcp/tools.js.map +1 -1
  43. package/dist/esm/subconscious/TheBrainV2.d.ts +102 -0
  44. package/dist/esm/subconscious/TheBrainV2.d.ts.map +1 -0
  45. package/dist/esm/subconscious/TheBrainV2.js +431 -0
  46. package/dist/esm/subconscious/TheBrainV2.js.map +1 -0
  47. package/dist/esm/utils/ContextCollapser.d.ts +21 -0
  48. package/dist/esm/utils/ContextCollapser.d.ts.map +1 -0
  49. package/dist/esm/utils/ContextCollapser.js +128 -0
  50. package/dist/esm/utils/ContextCollapser.js.map +1 -0
  51. package/dist/esm/utils/ExecutiveReport.d.ts +29 -0
  52. package/dist/esm/utils/ExecutiveReport.d.ts.map +1 -0
  53. package/dist/esm/utils/ExecutiveReport.js +105 -0
  54. package/dist/esm/utils/ExecutiveReport.js.map +1 -0
  55. package/dist/esm/utils/SurgicalASTInsert.d.ts +21 -0
  56. package/dist/esm/utils/SurgicalASTInsert.d.ts.map +1 -0
  57. package/dist/esm/utils/SurgicalASTInsert.js +134 -0
  58. package/dist/esm/utils/SurgicalASTInsert.js.map +1 -0
  59. package/dist/esm/utils/SymbolSurgicalContext.d.ts +25 -0
  60. package/dist/esm/utils/SymbolSurgicalContext.d.ts.map +1 -0
  61. package/dist/esm/utils/SymbolSurgicalContext.js +226 -0
  62. package/dist/esm/utils/SymbolSurgicalContext.js.map +1 -0
  63. package/dist/esm/utils/WormholeCompressor.d.ts +22 -0
  64. package/dist/esm/utils/WormholeCompressor.d.ts.map +1 -0
  65. package/dist/esm/utils/WormholeCompressor.js +148 -0
  66. package/dist/esm/utils/WormholeCompressor.js.map +1 -0
  67. package/lemma-proxy.cjs +31 -14
  68. package/mcp-server.js +220 -0
  69. package/package.json +5 -1
@@ -0,0 +1,102 @@
1
+ /**
2
+ * TheBrainV2 — Zero-dependency semantic memory engine for Lemma.
3
+ *
4
+ * Replaces: Ollama (embeddings) + ChromaDB (vector store)
5
+ * Algorithm: BM25 (Okapi) + Inverted Index + Bloom Filter + Jaccard re-rank
6
+ * Storage: ~/.lemma-cache/brain/ (NDJSON, no external DB)
7
+ * Latency: <10ms per query (vs ~200ms with Ollama)
8
+ *
9
+ * Compatible with: Claude CLI, Codex, OpenCode, Cursor, Windsurf, Kiro,
10
+ * Cline, VS Code Copilot — any MCP client.
11
+ */
12
+ export interface BrainEntry {
13
+ id: string;
14
+ query: string;
15
+ response: string;
16
+ terms: string[];
17
+ termFreq: Record<string, number>;
18
+ provider: string;
19
+ timestamp: string;
20
+ hits: number;
21
+ charCount: number;
22
+ }
23
+ export interface BrainSearchResult {
24
+ id: string;
25
+ query: string;
26
+ response: string;
27
+ similarity: number;
28
+ provider: string;
29
+ timestamp: string;
30
+ }
31
+ export interface BrainStats {
32
+ totalEntries: number;
33
+ totalTerms: number;
34
+ avgDocLength: number;
35
+ bloomFilterSize: number;
36
+ cacheHits: number;
37
+ cacheMisses: number;
38
+ }
39
+ /**
40
+ * Tokenize text into stemmed, filtered terms.
41
+ * Handles: camelCase splitting, snake_case, stop-word removal, n-grams.
42
+ */
43
+ export declare function tokenize(text: string): string[];
44
+ /**
45
+ * Compute term frequencies for a token list.
46
+ */
47
+ export declare function termFrequencies(terms: string[]): Record<string, number>;
48
+ export declare class BloomFilter {
49
+ private bits;
50
+ constructor(serialized?: string);
51
+ add(item: string): void;
52
+ has(item: string): boolean;
53
+ serialize(): string;
54
+ }
55
+ export declare function bm25Score(queryTerms: string[], docTermFreq: Record<string, number>, docLength: number, avgDocLength: number, idf: Record<string, number>): number;
56
+ /**
57
+ * Jaccard similarity between two term sets.
58
+ */
59
+ export declare function jaccardSimilarity(setA: Set<string>, setB: Set<string>): number;
60
+ export declare class TheBrainV2 {
61
+ private entries;
62
+ private invertedIndex;
63
+ private bloom;
64
+ private avgDocLength;
65
+ private sessionHits;
66
+ private sessionMisses;
67
+ private dirty;
68
+ private flushTimer;
69
+ constructor();
70
+ private ensureDir;
71
+ private load;
72
+ private recalcAvgDocLength;
73
+ private scheduleSave;
74
+ private save;
75
+ /**
76
+ * Store a query+response pair in the brain.
77
+ * Returns false if detected as duplicate (>= dupThreshold similarity).
78
+ */
79
+ store(query: string, response: string, provider?: string, dupThreshold?: number): {
80
+ stored: boolean;
81
+ reason: string;
82
+ duplicate?: BrainSearchResult;
83
+ };
84
+ /**
85
+ * Search brain using BM25 + Jaccard re-ranking.
86
+ * Returns results with similarity scores normalized to 0-1.
87
+ */
88
+ search(query: string, limit?: number, minSimilarity?: number): BrainSearchResult[];
89
+ /**
90
+ * Check if a query is likely a duplicate before storing.
91
+ * Uses bloom filter for O(1) fast-path.
92
+ */
93
+ checkDuplicate(query: string, response: string, threshold?: number): {
94
+ isDuplicate: boolean;
95
+ similarity: number;
96
+ existing?: BrainSearchResult;
97
+ };
98
+ getStats(): BrainStats;
99
+ clear(): void;
100
+ }
101
+ export declare function getBrain(): TheBrainV2;
102
+ //# sourceMappingURL=TheBrainV2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TheBrainV2.d.ts","sourceRoot":"","sources":["../../../src/subconscious/TheBrainV2.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,444 @@
1
+ "use strict";
2
+ /**
3
+ * TheBrainV2 — Zero-dependency semantic memory engine for Lemma.
4
+ *
5
+ * Replaces: Ollama (embeddings) + ChromaDB (vector store)
6
+ * Algorithm: BM25 (Okapi) + Inverted Index + Bloom Filter + Jaccard re-rank
7
+ * Storage: ~/.lemma-cache/brain/ (NDJSON, no external DB)
8
+ * Latency: <10ms per query (vs ~200ms with Ollama)
9
+ *
10
+ * Compatible with: Claude CLI, Codex, OpenCode, Cursor, Windsurf, Kiro,
11
+ * Cline, VS Code Copilot — any MCP client.
12
+ */
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.TheBrainV2 = exports.BloomFilter = void 0;
18
+ exports.tokenize = tokenize;
19
+ exports.termFrequencies = termFrequencies;
20
+ exports.bm25Score = bm25Score;
21
+ exports.jaccardSimilarity = jaccardSimilarity;
22
+ exports.getBrain = getBrain;
23
+ const fs_1 = __importDefault(require("fs"));
24
+ const path_1 = __importDefault(require("path"));
25
+ const os_1 = __importDefault(require("os"));
26
+ const crypto_1 = __importDefault(require("crypto"));
27
+ // ─── BM25 Constants ───────────────────────────────────────────────────────────
28
+ const BM25_K1 = 1.5; // Term saturation (1.2-2.0)
29
+ const BM25_B = 0.75; // Length normalization (0-1)
30
+ // ─── Storage Paths ────────────────────────────────────────────────────────────
31
+ const BRAIN_DIR = path_1.default.join(os_1.default.homedir(), '.lemma-cache', 'brain');
32
+ const ENTRIES_FILE = path_1.default.join(BRAIN_DIR, 'entries.ndjson');
33
+ const INDEX_FILE = path_1.default.join(BRAIN_DIR, 'index.json');
34
+ const META_FILE = path_1.default.join(BRAIN_DIR, 'meta.json');
35
+ // ─── Tokenizer ────────────────────────────────────────────────────────────────
36
+ /**
37
+ * Tokenize text into stemmed, filtered terms.
38
+ * Handles: camelCase splitting, snake_case, stop-word removal, n-grams.
39
+ */
40
+ function tokenize(text) {
41
+ // 1. Split camelCase and PascalCase → "AuthService" → "auth service"
42
+ let normalized = text.replace(/([a-z])([A-Z])/g, '$1 $2');
43
+ // 2. Split snake_case and kebab-case
44
+ normalized = normalized.replace(/[_\-]/g, ' ');
45
+ // 3. Remove punctuation, keep alphanumerics
46
+ normalized = normalized.replace(/[^\w\s]/g, ' ');
47
+ // 4. Lowercase
48
+ normalized = normalized.toLowerCase();
49
+ const STOP_WORDS = new Set([
50
+ 'the', 'a', 'an', 'is', 'in', 'it', 'of', 'to', 'and', 'or', 'for', 'with',
51
+ 'this', 'that', 'these', 'those', 'are', 'was', 'were', 'be', 'been', 'being',
52
+ 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could', 'should',
53
+ 'may', 'might', 'shall', 'can', 'need', 'must', 'from', 'by', 'at', 'on', 'up',
54
+ 'if', 'as', 'so', 'but', 'not', 'no', 'nor', 'yet', 'both', 'either', 'neither',
55
+ 'than', 'then', 'when', 'where', 'which', 'who', 'how', 'what', 'why', 'all',
56
+ 'any', 'each', 'few', 'more', 'most', 'other', 'some', 'such', 'into', 'onto',
57
+ 'off', 'out', 'over', 'under', 'again', 'further', 'once', 'here', 'there',
58
+ ]);
59
+ const terms = normalized
60
+ .split(/\s+/)
61
+ .filter(t => t.length >= 2 && !STOP_WORDS.has(t));
62
+ // 5. Add bigrams for better phrase matching
63
+ const bigrams = [];
64
+ for (let i = 0; i < terms.length - 1; i++) {
65
+ bigrams.push(`${terms[i]}_${terms[i + 1]}`);
66
+ }
67
+ return [...new Set([...terms, ...bigrams])];
68
+ }
69
+ /**
70
+ * Compute term frequencies for a token list.
71
+ */
72
+ function termFrequencies(terms) {
73
+ const freq = {};
74
+ for (const t of terms) {
75
+ freq[t] = (freq[t] || 0) + 1;
76
+ }
77
+ return freq;
78
+ }
79
+ // ─── Bloom Filter (pure bit-array, no deps) ──────────────────────────────────
80
+ const BLOOM_SIZE = 1 << 18; // 256K bits = 32KB
81
+ const BLOOM_HASHES = 5;
82
+ function bloomHash(item, seed) {
83
+ let h = seed ^ 0xdeadbeef;
84
+ for (let i = 0; i < item.length; i++) {
85
+ h = Math.imul(h ^ item.charCodeAt(i), 0x9e3779b9);
86
+ h ^= h >>> 16;
87
+ }
88
+ return (h >>> 0) % BLOOM_SIZE;
89
+ }
90
+ class BloomFilter {
91
+ constructor(serialized) {
92
+ this.bits = new Uint8Array(BLOOM_SIZE >> 3);
93
+ if (serialized) {
94
+ const buf = Buffer.from(serialized, 'base64');
95
+ this.bits.set(buf);
96
+ }
97
+ }
98
+ add(item) {
99
+ for (let i = 0; i < BLOOM_HASHES; i++) {
100
+ const pos = bloomHash(item, i * 0x5f3759df);
101
+ this.bits[pos >> 3] |= (1 << (pos & 7));
102
+ }
103
+ }
104
+ has(item) {
105
+ for (let i = 0; i < BLOOM_HASHES; i++) {
106
+ const pos = bloomHash(item, i * 0x5f3759df);
107
+ if (!(this.bits[pos >> 3] & (1 << (pos & 7))))
108
+ return false;
109
+ }
110
+ return true;
111
+ }
112
+ serialize() {
113
+ return Buffer.from(this.bits).toString('base64');
114
+ }
115
+ }
116
+ exports.BloomFilter = BloomFilter;
117
+ // ─── BM25 Scorer ─────────────────────────────────────────────────────────────
118
+ function bm25Score(queryTerms, docTermFreq, docLength, avgDocLength, idf) {
119
+ let score = 0;
120
+ for (const term of queryTerms) {
121
+ if (!(term in docTermFreq))
122
+ continue;
123
+ const tf = docTermFreq[term];
124
+ const termIdf = idf[term] || 0;
125
+ const numerator = tf * (BM25_K1 + 1);
126
+ const denominator = tf + BM25_K1 * (1 - BM25_B + BM25_B * (docLength / avgDocLength));
127
+ score += termIdf * (numerator / denominator);
128
+ }
129
+ return score;
130
+ }
131
+ /**
132
+ * Jaccard similarity between two term sets.
133
+ */
134
+ function jaccardSimilarity(setA, setB) {
135
+ if (setA.size === 0 && setB.size === 0)
136
+ return 1;
137
+ let intersection = 0;
138
+ for (const t of setA) {
139
+ if (setB.has(t))
140
+ intersection++;
141
+ }
142
+ return intersection / (setA.size + setB.size - intersection);
143
+ }
144
+ // ─── TheBrainV2 ──────────────────────────────────────────────────────────────
145
+ class TheBrainV2 {
146
+ // ─── Initialization ───────────────────────────────────────────────────────
147
+ constructor() {
148
+ this.entries = new Map();
149
+ this.invertedIndex = new Map(); // term → entry IDs
150
+ this.bloom = new BloomFilter();
151
+ this.avgDocLength = 0;
152
+ this.sessionHits = 0;
153
+ this.sessionMisses = 0;
154
+ this.dirty = false;
155
+ this.flushTimer = null;
156
+ this.ensureDir();
157
+ this.load();
158
+ }
159
+ ensureDir() {
160
+ if (!fs_1.default.existsSync(BRAIN_DIR)) {
161
+ fs_1.default.mkdirSync(BRAIN_DIR, { recursive: true });
162
+ }
163
+ }
164
+ load() {
165
+ try {
166
+ // Load entries from NDJSON
167
+ if (fs_1.default.existsSync(ENTRIES_FILE)) {
168
+ const lines = fs_1.default.readFileSync(ENTRIES_FILE, 'utf8').split('\n').filter(Boolean);
169
+ for (const line of lines) {
170
+ try {
171
+ const entry = JSON.parse(line);
172
+ this.entries.set(entry.id, entry);
173
+ }
174
+ catch { /* skip corrupt lines */ }
175
+ }
176
+ }
177
+ // Load inverted index
178
+ if (fs_1.default.existsSync(INDEX_FILE)) {
179
+ const raw = JSON.parse(fs_1.default.readFileSync(INDEX_FILE, 'utf8'));
180
+ for (const [term, ids] of Object.entries(raw)) {
181
+ this.invertedIndex.set(term, new Set(ids));
182
+ }
183
+ }
184
+ // Load bloom filter and meta
185
+ if (fs_1.default.existsSync(META_FILE)) {
186
+ const meta = JSON.parse(fs_1.default.readFileSync(META_FILE, 'utf8'));
187
+ if (meta.bloom) {
188
+ this.bloom = new BloomFilter(meta.bloom);
189
+ }
190
+ this.avgDocLength = meta.avgDocLength || 0;
191
+ }
192
+ this.recalcAvgDocLength();
193
+ }
194
+ catch (err) {
195
+ // Brain is empty or corrupt — start fresh
196
+ this.entries.clear();
197
+ this.invertedIndex.clear();
198
+ this.bloom = new BloomFilter();
199
+ }
200
+ }
201
+ recalcAvgDocLength() {
202
+ if (this.entries.size === 0) {
203
+ this.avgDocLength = 0;
204
+ return;
205
+ }
206
+ const total = Array.from(this.entries.values()).reduce((s, e) => s + e.terms.length, 0);
207
+ this.avgDocLength = total / this.entries.size;
208
+ }
209
+ scheduleSave() {
210
+ this.dirty = true;
211
+ if (this.flushTimer)
212
+ return;
213
+ this.flushTimer = setTimeout(() => {
214
+ this.flushTimer = null;
215
+ if (this.dirty)
216
+ this.save();
217
+ }, 500);
218
+ }
219
+ save() {
220
+ try {
221
+ this.ensureDir();
222
+ // Write NDJSON entries
223
+ const ndjson = Array.from(this.entries.values())
224
+ .map(e => JSON.stringify(e))
225
+ .join('\n');
226
+ fs_1.default.writeFileSync(ENTRIES_FILE, ndjson, 'utf8');
227
+ // Write inverted index
228
+ const indexObj = {};
229
+ for (const [term, ids] of this.invertedIndex) {
230
+ indexObj[term] = Array.from(ids);
231
+ }
232
+ fs_1.default.writeFileSync(INDEX_FILE, JSON.stringify(indexObj), 'utf8');
233
+ // Write meta
234
+ fs_1.default.writeFileSync(META_FILE, JSON.stringify({
235
+ bloom: this.bloom.serialize(),
236
+ avgDocLength: this.avgDocLength,
237
+ totalEntries: this.entries.size,
238
+ savedAt: new Date().toISOString(),
239
+ }), 'utf8');
240
+ this.dirty = false;
241
+ }
242
+ catch { /* fail silently */ }
243
+ }
244
+ // ─── Store ────────────────────────────────────────────────────────────────
245
+ /**
246
+ * Store a query+response pair in the brain.
247
+ * Returns false if detected as duplicate (>= dupThreshold similarity).
248
+ */
249
+ store(query, response, provider = 'generic', dupThreshold = 0.92) {
250
+ // Quick bloom check
251
+ const queryKey = query.trim().toLowerCase().substring(0, 200);
252
+ if (this.bloom.has(queryKey)) {
253
+ // Possible duplicate — run full search
254
+ const existing = this.search(query, 1, dupThreshold);
255
+ if (existing.length > 0 && existing[0].similarity >= dupThreshold) {
256
+ return {
257
+ stored: false,
258
+ reason: `Duplicate detected (${(existing[0].similarity * 100).toFixed(1)}% similar)`,
259
+ duplicate: existing[0],
260
+ };
261
+ }
262
+ }
263
+ const terms = tokenize(query + ' ' + response);
264
+ const termFreq = termFrequencies(terms);
265
+ const id = crypto_1.default
266
+ .createHash('sha1')
267
+ .update(queryKey + Date.now())
268
+ .digest('hex')
269
+ .substring(0, 12);
270
+ const entry = {
271
+ id,
272
+ query: query.trim(),
273
+ response: response.trim(),
274
+ terms: [...new Set(terms)],
275
+ termFreq,
276
+ provider,
277
+ timestamp: new Date().toISOString(),
278
+ hits: 0,
279
+ charCount: query.length + response.length,
280
+ };
281
+ this.entries.set(id, entry);
282
+ // Update inverted index
283
+ for (const term of entry.terms) {
284
+ if (!this.invertedIndex.has(term)) {
285
+ this.invertedIndex.set(term, new Set());
286
+ }
287
+ this.invertedIndex.get(term).add(id);
288
+ }
289
+ // Update bloom
290
+ this.bloom.add(queryKey);
291
+ this.recalcAvgDocLength();
292
+ this.scheduleSave();
293
+ return { stored: true, reason: 'Stored successfully' };
294
+ }
295
+ // ─── Search ───────────────────────────────────────────────────────────────
296
+ /**
297
+ * Search brain using BM25 + Jaccard re-ranking.
298
+ * Returns results with similarity scores normalized to 0-1.
299
+ */
300
+ search(query, limit = 5, minSimilarity = 0) {
301
+ if (this.entries.size === 0) {
302
+ this.sessionMisses++;
303
+ return [];
304
+ }
305
+ const queryTerms = tokenize(query);
306
+ const queryTermSet = new Set(queryTerms);
307
+ if (queryTerms.length === 0) {
308
+ this.sessionMisses++;
309
+ return [];
310
+ }
311
+ // 1. Compute IDF for query terms
312
+ const N = this.entries.size;
313
+ const idf = {};
314
+ for (const term of queryTerms) {
315
+ const df = this.invertedIndex.get(term)?.size ?? 0;
316
+ idf[term] = df > 0 ? Math.log((N - df + 0.5) / (df + 0.5) + 1) : 0;
317
+ }
318
+ // 2. Candidate retrieval via inverted index (only docs containing at least 1 query term)
319
+ const candidateIds = new Set();
320
+ for (const term of queryTerms) {
321
+ const ids = this.invertedIndex.get(term);
322
+ if (ids) {
323
+ for (const id of ids)
324
+ candidateIds.add(id);
325
+ }
326
+ }
327
+ if (candidateIds.size === 0) {
328
+ this.sessionMisses++;
329
+ return [];
330
+ }
331
+ // 3. Score candidates with BM25
332
+ const scored = [];
333
+ for (const id of candidateIds) {
334
+ const entry = this.entries.get(id);
335
+ if (!entry)
336
+ continue;
337
+ const bm25 = bm25Score(queryTerms, entry.termFreq, entry.terms.length, this.avgDocLength || 10, idf);
338
+ const docTermSet = new Set(entry.terms);
339
+ const jaccard = jaccardSimilarity(queryTermSet, docTermSet);
340
+ scored.push({ entry, bm25, jaccard });
341
+ }
342
+ if (scored.length === 0) {
343
+ this.sessionMisses++;
344
+ return [];
345
+ }
346
+ // 4. Normalize BM25 to 0-1 range
347
+ const maxBm25 = Math.max(...scored.map(s => s.bm25), 1);
348
+ // 5. Combined score: 70% BM25 + 30% Jaccard
349
+ const combined = scored.map(s => ({
350
+ entry: s.entry,
351
+ similarity: (s.bm25 / maxBm25) * 0.7 + s.jaccard * 0.3,
352
+ }));
353
+ // 6. Sort and filter
354
+ combined.sort((a, b) => b.similarity - a.similarity);
355
+ const results = combined
356
+ .filter(r => r.similarity >= minSimilarity)
357
+ .slice(0, limit)
358
+ .map(r => ({
359
+ id: r.entry.id,
360
+ query: r.entry.query,
361
+ response: r.entry.response,
362
+ similarity: Math.min(r.similarity, 1),
363
+ provider: r.entry.provider,
364
+ timestamp: r.entry.timestamp,
365
+ }));
366
+ // 7. Update hit counters
367
+ if (results.length > 0) {
368
+ this.sessionHits++;
369
+ // Increment hit counter on top result (LRU-style freshness)
370
+ const topEntry = this.entries.get(results[0].id);
371
+ if (topEntry) {
372
+ topEntry.hits++;
373
+ this.scheduleSave();
374
+ }
375
+ }
376
+ else {
377
+ this.sessionMisses++;
378
+ }
379
+ return results;
380
+ }
381
+ // ─── Dedup Check ─────────────────────────────────────────────────────────
382
+ /**
383
+ * Check if a query is likely a duplicate before storing.
384
+ * Uses bloom filter for O(1) fast-path.
385
+ */
386
+ checkDuplicate(query, response, threshold = 0.92) {
387
+ const queryKey = query.trim().toLowerCase().substring(0, 200);
388
+ // Fast path: bloom filter says no → definitely not a duplicate
389
+ if (!this.bloom.has(queryKey)) {
390
+ return { isDuplicate: false, similarity: 0 };
391
+ }
392
+ // Slow path: full BM25 search to confirm
393
+ const results = this.search(query, 1, 0);
394
+ if (results.length === 0) {
395
+ return { isDuplicate: false, similarity: 0 };
396
+ }
397
+ const top = results[0];
398
+ let sim = top.similarity;
399
+ if (top.query.trim().toLowerCase() === query.trim().toLowerCase()) {
400
+ sim = 1.0;
401
+ }
402
+ if (sim >= threshold) {
403
+ return { isDuplicate: true, similarity: sim, existing: top };
404
+ }
405
+ return { isDuplicate: false, similarity: sim };
406
+ }
407
+ // ─── Stats ────────────────────────────────────────────────────────────────
408
+ getStats() {
409
+ return {
410
+ totalEntries: this.entries.size,
411
+ totalTerms: this.invertedIndex.size,
412
+ avgDocLength: Math.round(this.avgDocLength),
413
+ bloomFilterSize: BLOOM_SIZE,
414
+ cacheHits: this.sessionHits,
415
+ cacheMisses: this.sessionMisses,
416
+ };
417
+ }
418
+ clear() {
419
+ this.entries.clear();
420
+ this.invertedIndex.clear();
421
+ this.bloom = new BloomFilter();
422
+ this.avgDocLength = 0;
423
+ this.sessionHits = 0;
424
+ this.sessionMisses = 0;
425
+ try {
426
+ if (fs_1.default.existsSync(ENTRIES_FILE))
427
+ fs_1.default.unlinkSync(ENTRIES_FILE);
428
+ if (fs_1.default.existsSync(INDEX_FILE))
429
+ fs_1.default.unlinkSync(INDEX_FILE);
430
+ if (fs_1.default.existsSync(META_FILE))
431
+ fs_1.default.unlinkSync(META_FILE);
432
+ }
433
+ catch { /* ignore */ }
434
+ }
435
+ }
436
+ exports.TheBrainV2 = TheBrainV2;
437
+ // ─── Global singleton ────────────────────────────────────────────────────────
438
+ let _brain = null;
439
+ function getBrain() {
440
+ if (!_brain)
441
+ _brain = new TheBrainV2();
442
+ return _brain;
443
+ }
444
+ //# sourceMappingURL=TheBrainV2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TheBrainV2.js","sourceRoot":"","sources":["../../../src/subconscious/TheBrainV2.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * ContextCollapser — Zero-dependency extraction summarizer for technical logs & history.
3
+ *
4
+ * Replaces: Ollama for summarize_long_text and compress_context.
5
+ * Algorithm: Query-Focused TF-IDF Centroid sentence extraction + Jaccard dedup.
6
+ * Latency: <15ms for 100k characters.
7
+ */
8
+ export interface CollapseOptions {
9
+ maxLength?: number;
10
+ query?: string;
11
+ ratio?: number;
12
+ }
13
+ /**
14
+ * Split text into logical blocks (sentences or log chunks).
15
+ */
16
+ export declare function splitIntoSentences(text: string): string[];
17
+ /**
18
+ * Summarize long text locally by selecting the most semantically dense sentences.
19
+ */
20
+ export declare function collapseContext(text: string, options?: CollapseOptions): string;
21
+ //# sourceMappingURL=ContextCollapser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextCollapser.d.ts","sourceRoot":"","sources":["../../../src/utils/ContextCollapser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAoBzD;AAcD;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CAyFnF"}