@soleri/core 2.0.0 → 2.0.2
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/dist/brain/brain.d.ts +3 -12
- package/dist/brain/brain.d.ts.map +1 -1
- package/dist/brain/brain.js +13 -245
- package/dist/brain/brain.js.map +1 -1
- package/dist/curator/curator.d.ts +28 -0
- package/dist/curator/curator.d.ts.map +1 -0
- package/dist/curator/curator.js +523 -0
- package/dist/curator/curator.js.map +1 -0
- package/dist/curator/types.d.ts +87 -0
- package/dist/curator/types.d.ts.map +1 -0
- package/dist/curator/types.js +3 -0
- package/dist/curator/types.js.map +1 -0
- package/dist/facades/types.d.ts +1 -1
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/dist/llm/llm-client.d.ts +28 -0
- package/dist/llm/llm-client.d.ts.map +1 -0
- package/dist/llm/llm-client.js +219 -0
- package/dist/llm/llm-client.js.map +1 -0
- package/dist/runtime/core-ops.d.ts +17 -0
- package/dist/runtime/core-ops.d.ts.map +1 -0
- package/dist/runtime/core-ops.js +448 -0
- package/dist/runtime/core-ops.js.map +1 -0
- package/dist/runtime/domain-ops.d.ts +25 -0
- package/dist/runtime/domain-ops.d.ts.map +1 -0
- package/dist/runtime/domain-ops.js +130 -0
- package/dist/runtime/domain-ops.js.map +1 -0
- package/dist/runtime/runtime.d.ts +19 -0
- package/dist/runtime/runtime.d.ts.map +1 -0
- package/dist/runtime/runtime.js +62 -0
- package/dist/runtime/runtime.js.map +1 -0
- package/dist/runtime/types.d.ts +39 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +2 -0
- package/dist/{cognee → runtime}/types.js.map +1 -1
- package/dist/text/similarity.d.ts +8 -0
- package/dist/text/similarity.d.ts.map +1 -0
- package/dist/text/similarity.js +161 -0
- package/dist/text/similarity.js.map +1 -0
- package/package.json +6 -2
- package/src/__tests__/brain.test.ts +27 -222
- package/src/__tests__/core-ops.test.ts +190 -0
- package/src/__tests__/curator.test.ts +479 -0
- package/src/__tests__/domain-ops.test.ts +124 -0
- package/src/__tests__/llm-client.test.ts +69 -0
- package/src/__tests__/runtime.test.ts +93 -0
- package/src/brain/brain.ts +19 -275
- package/src/curator/curator.ts +662 -0
- package/src/curator/types.ts +114 -0
- package/src/index.ts +40 -11
- package/src/llm/llm-client.ts +316 -0
- package/src/runtime/core-ops.ts +472 -0
- package/src/runtime/domain-ops.ts +144 -0
- package/src/runtime/runtime.ts +71 -0
- package/src/runtime/types.ts +37 -0
- package/src/text/similarity.ts +168 -0
- package/dist/cognee/client.d.ts +0 -35
- package/dist/cognee/client.d.ts.map +0 -1
- package/dist/cognee/client.js +0 -289
- package/dist/cognee/client.js.map +0 -1
- package/dist/cognee/types.d.ts +0 -46
- package/dist/cognee/types.d.ts.map +0 -1
- package/dist/cognee/types.js +0 -3
- package/src/__tests__/cognee-client.test.ts +0 -524
- package/src/cognee/client.ts +0 -350
- package/src/cognee/types.ts +0 -62
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from 'vitest';
|
|
2
|
+
import { createAgentRuntime } from '../runtime/runtime.js';
|
|
3
|
+
import type { AgentRuntime } from '../runtime/types.js';
|
|
4
|
+
|
|
5
|
+
describe('createAgentRuntime', () => {
|
|
6
|
+
let runtime: AgentRuntime | null = null;
|
|
7
|
+
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
runtime?.close();
|
|
10
|
+
runtime = null;
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should create a runtime with all modules initialized', () => {
|
|
14
|
+
runtime = createAgentRuntime({
|
|
15
|
+
agentId: 'test-agent',
|
|
16
|
+
vaultPath: ':memory:',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
expect(runtime.config.agentId).toBe('test-agent');
|
|
20
|
+
expect(runtime.vault).toBeDefined();
|
|
21
|
+
expect(runtime.brain).toBeDefined();
|
|
22
|
+
expect(runtime.planner).toBeDefined();
|
|
23
|
+
expect(runtime.curator).toBeDefined();
|
|
24
|
+
expect(runtime.keyPool.openai).toBeDefined();
|
|
25
|
+
expect(runtime.keyPool.anthropic).toBeDefined();
|
|
26
|
+
expect(runtime.llmClient).toBeDefined();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should use :memory: vault when specified', () => {
|
|
30
|
+
runtime = createAgentRuntime({
|
|
31
|
+
agentId: 'test-mem',
|
|
32
|
+
vaultPath: ':memory:',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const stats = runtime.vault.stats();
|
|
36
|
+
expect(stats.totalEntries).toBe(0);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should preserve config on runtime', () => {
|
|
40
|
+
runtime = createAgentRuntime({
|
|
41
|
+
agentId: 'test-cfg',
|
|
42
|
+
vaultPath: ':memory:',
|
|
43
|
+
dataDir: '/nonexistent',
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
expect(runtime.config.agentId).toBe('test-cfg');
|
|
47
|
+
expect(runtime.config.vaultPath).toBe(':memory:');
|
|
48
|
+
expect(runtime.config.dataDir).toBe('/nonexistent');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('close() should not throw', () => {
|
|
52
|
+
runtime = createAgentRuntime({
|
|
53
|
+
agentId: 'test-close',
|
|
54
|
+
vaultPath: ':memory:',
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
expect(() => runtime!.close()).not.toThrow();
|
|
58
|
+
runtime = null; // already closed
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('brain should be wired to vault', () => {
|
|
62
|
+
runtime = createAgentRuntime({
|
|
63
|
+
agentId: 'test-brain-wire',
|
|
64
|
+
vaultPath: ':memory:',
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Seed some data through vault
|
|
68
|
+
runtime.vault.seed([{
|
|
69
|
+
id: 'rt-1',
|
|
70
|
+
type: 'pattern',
|
|
71
|
+
domain: 'testing',
|
|
72
|
+
title: 'Runtime test pattern',
|
|
73
|
+
severity: 'warning',
|
|
74
|
+
description: 'A test.',
|
|
75
|
+
tags: ['test'],
|
|
76
|
+
}]);
|
|
77
|
+
|
|
78
|
+
// Brain should find it
|
|
79
|
+
runtime.brain.rebuildVocabulary();
|
|
80
|
+
const results = runtime.brain.intelligentSearch('runtime test', { limit: 5 });
|
|
81
|
+
expect(results.length).toBeGreaterThan(0);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('curator should be wired to vault', () => {
|
|
85
|
+
runtime = createAgentRuntime({
|
|
86
|
+
agentId: 'test-curator-wire',
|
|
87
|
+
vaultPath: ':memory:',
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const status = runtime.curator.getStatus();
|
|
91
|
+
expect(status.initialized).toBe(true);
|
|
92
|
+
});
|
|
93
|
+
});
|
package/src/brain/brain.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import type { Vault } from '../vault/vault.js';
|
|
2
2
|
import type { SearchResult } from '../vault/vault.js';
|
|
3
3
|
import type { IntelligenceEntry } from '../intelligence/types.js';
|
|
4
|
-
import
|
|
4
|
+
import {
|
|
5
|
+
tokenize,
|
|
6
|
+
calculateTf,
|
|
7
|
+
calculateTfIdf,
|
|
8
|
+
cosineSimilarity,
|
|
9
|
+
jaccardSimilarity,
|
|
10
|
+
} from '../text/similarity.js';
|
|
5
11
|
|
|
6
12
|
// ─── Types ───────────────────────────────────────────────────────────
|
|
7
13
|
|
|
8
14
|
export interface ScoringWeights {
|
|
9
15
|
semantic: number;
|
|
10
|
-
vector: number;
|
|
11
16
|
severity: number;
|
|
12
17
|
recency: number;
|
|
13
18
|
tagOverlap: number;
|
|
@@ -16,7 +21,6 @@ export interface ScoringWeights {
|
|
|
16
21
|
|
|
17
22
|
export interface ScoreBreakdown {
|
|
18
23
|
semantic: number;
|
|
19
|
-
vector: number;
|
|
20
24
|
severity: number;
|
|
21
25
|
recency: number;
|
|
22
26
|
tagOverlap: number;
|
|
@@ -58,172 +62,6 @@ export interface QueryContext {
|
|
|
58
62
|
tags?: string[];
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
type SparseVector = Map<string, number>;
|
|
62
|
-
|
|
63
|
-
// ─── Stopwords ─────────────────────────────────────────────────────
|
|
64
|
-
|
|
65
|
-
const STOPWORDS = new Set([
|
|
66
|
-
'a',
|
|
67
|
-
'an',
|
|
68
|
-
'the',
|
|
69
|
-
'and',
|
|
70
|
-
'or',
|
|
71
|
-
'but',
|
|
72
|
-
'in',
|
|
73
|
-
'on',
|
|
74
|
-
'at',
|
|
75
|
-
'to',
|
|
76
|
-
'for',
|
|
77
|
-
'of',
|
|
78
|
-
'with',
|
|
79
|
-
'by',
|
|
80
|
-
'from',
|
|
81
|
-
'as',
|
|
82
|
-
'is',
|
|
83
|
-
'was',
|
|
84
|
-
'are',
|
|
85
|
-
'were',
|
|
86
|
-
'been',
|
|
87
|
-
'be',
|
|
88
|
-
'have',
|
|
89
|
-
'has',
|
|
90
|
-
'had',
|
|
91
|
-
'do',
|
|
92
|
-
'does',
|
|
93
|
-
'did',
|
|
94
|
-
'will',
|
|
95
|
-
'would',
|
|
96
|
-
'could',
|
|
97
|
-
'should',
|
|
98
|
-
'may',
|
|
99
|
-
'might',
|
|
100
|
-
'shall',
|
|
101
|
-
'can',
|
|
102
|
-
'need',
|
|
103
|
-
'must',
|
|
104
|
-
'it',
|
|
105
|
-
'its',
|
|
106
|
-
'this',
|
|
107
|
-
'that',
|
|
108
|
-
'these',
|
|
109
|
-
'those',
|
|
110
|
-
'i',
|
|
111
|
-
'you',
|
|
112
|
-
'he',
|
|
113
|
-
'she',
|
|
114
|
-
'we',
|
|
115
|
-
'they',
|
|
116
|
-
'me',
|
|
117
|
-
'him',
|
|
118
|
-
'her',
|
|
119
|
-
'us',
|
|
120
|
-
'them',
|
|
121
|
-
'my',
|
|
122
|
-
'your',
|
|
123
|
-
'his',
|
|
124
|
-
'our',
|
|
125
|
-
'their',
|
|
126
|
-
'what',
|
|
127
|
-
'which',
|
|
128
|
-
'who',
|
|
129
|
-
'whom',
|
|
130
|
-
'when',
|
|
131
|
-
'where',
|
|
132
|
-
'why',
|
|
133
|
-
'how',
|
|
134
|
-
'all',
|
|
135
|
-
'each',
|
|
136
|
-
'every',
|
|
137
|
-
'both',
|
|
138
|
-
'few',
|
|
139
|
-
'more',
|
|
140
|
-
'most',
|
|
141
|
-
'other',
|
|
142
|
-
'some',
|
|
143
|
-
'such',
|
|
144
|
-
'no',
|
|
145
|
-
'not',
|
|
146
|
-
'only',
|
|
147
|
-
'same',
|
|
148
|
-
'so',
|
|
149
|
-
'than',
|
|
150
|
-
'too',
|
|
151
|
-
'very',
|
|
152
|
-
'just',
|
|
153
|
-
'because',
|
|
154
|
-
'if',
|
|
155
|
-
'then',
|
|
156
|
-
'else',
|
|
157
|
-
'about',
|
|
158
|
-
'up',
|
|
159
|
-
'out',
|
|
160
|
-
'into',
|
|
161
|
-
]);
|
|
162
|
-
|
|
163
|
-
// ─── Text Processing (pure functions) ────────────────────────────
|
|
164
|
-
|
|
165
|
-
function tokenize(text: string): string[] {
|
|
166
|
-
return text
|
|
167
|
-
.toLowerCase()
|
|
168
|
-
.replace(/[^a-z0-9\s-]/g, ' ')
|
|
169
|
-
.split(/\s+/)
|
|
170
|
-
.filter((t) => t.length > 2 && !STOPWORDS.has(t));
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
function calculateTf(tokens: string[]): SparseVector {
|
|
174
|
-
const tf: SparseVector = new Map();
|
|
175
|
-
for (const token of tokens) {
|
|
176
|
-
tf.set(token, (tf.get(token) ?? 0) + 1);
|
|
177
|
-
}
|
|
178
|
-
const len = tokens.length || 1;
|
|
179
|
-
for (const [term, count] of tf) {
|
|
180
|
-
tf.set(term, count / len);
|
|
181
|
-
}
|
|
182
|
-
return tf;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
function calculateTfIdf(tokens: string[], vocabulary: Map<string, number>): SparseVector {
|
|
186
|
-
const tf = calculateTf(tokens);
|
|
187
|
-
const tfidf: SparseVector = new Map();
|
|
188
|
-
for (const [term, tfValue] of tf) {
|
|
189
|
-
const idf = vocabulary.get(term) ?? 0;
|
|
190
|
-
if (idf > 0) {
|
|
191
|
-
tfidf.set(term, tfValue * idf);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return tfidf;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function cosineSimilarity(a: SparseVector, b: SparseVector): number {
|
|
198
|
-
let dot = 0;
|
|
199
|
-
let normA = 0;
|
|
200
|
-
let normB = 0;
|
|
201
|
-
for (const [term, valA] of a) {
|
|
202
|
-
normA += valA * valA;
|
|
203
|
-
const valB = b.get(term);
|
|
204
|
-
if (valB !== undefined) {
|
|
205
|
-
dot += valA * valB;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
for (const [, valB] of b) {
|
|
209
|
-
normB += valB * valB;
|
|
210
|
-
}
|
|
211
|
-
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
212
|
-
return denom === 0 ? 0 : dot / denom;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function jaccardSimilarity(a: string[], b: string[]): number {
|
|
216
|
-
if (a.length === 0 && b.length === 0) return 0;
|
|
217
|
-
const setA = new Set(a);
|
|
218
|
-
const setB = new Set(b);
|
|
219
|
-
let intersection = 0;
|
|
220
|
-
for (const item of setA) {
|
|
221
|
-
if (setB.has(item)) intersection++;
|
|
222
|
-
}
|
|
223
|
-
const union = new Set([...a, ...b]).size;
|
|
224
|
-
return union === 0 ? 0 : intersection / union;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
65
|
// ─── Severity scoring ──────────────────────────────────────────────
|
|
228
66
|
|
|
229
67
|
const SEVERITY_SCORES: Record<string, number> = {
|
|
@@ -236,22 +74,12 @@ const SEVERITY_SCORES: Record<string, number> = {
|
|
|
236
74
|
|
|
237
75
|
const DEFAULT_WEIGHTS: ScoringWeights = {
|
|
238
76
|
semantic: 0.4,
|
|
239
|
-
vector: 0.0,
|
|
240
77
|
severity: 0.15,
|
|
241
78
|
recency: 0.15,
|
|
242
79
|
tagOverlap: 0.15,
|
|
243
80
|
domainMatch: 0.15,
|
|
244
81
|
};
|
|
245
82
|
|
|
246
|
-
const COGNEE_WEIGHTS: ScoringWeights = {
|
|
247
|
-
semantic: 0.25,
|
|
248
|
-
vector: 0.35,
|
|
249
|
-
severity: 0.1,
|
|
250
|
-
recency: 0.1,
|
|
251
|
-
tagOverlap: 0.1,
|
|
252
|
-
domainMatch: 0.1,
|
|
253
|
-
};
|
|
254
|
-
|
|
255
83
|
const WEIGHT_BOUND = 0.15;
|
|
256
84
|
const FEEDBACK_THRESHOLD = 30;
|
|
257
85
|
const DUPLICATE_BLOCK_THRESHOLD = 0.8;
|
|
@@ -260,18 +88,16 @@ const RECENCY_HALF_LIFE_DAYS = 365;
|
|
|
260
88
|
|
|
261
89
|
export class Brain {
|
|
262
90
|
private vault: Vault;
|
|
263
|
-
private cognee: CogneeClient | undefined;
|
|
264
91
|
private vocabulary: Map<string, number> = new Map();
|
|
265
92
|
private weights: ScoringWeights = { ...DEFAULT_WEIGHTS };
|
|
266
93
|
|
|
267
|
-
constructor(vault: Vault
|
|
94
|
+
constructor(vault: Vault) {
|
|
268
95
|
this.vault = vault;
|
|
269
|
-
this.cognee = cognee;
|
|
270
96
|
this.rebuildVocabulary();
|
|
271
97
|
this.recomputeWeights();
|
|
272
98
|
}
|
|
273
99
|
|
|
274
|
-
|
|
100
|
+
intelligentSearch(query: string, options?: SearchOptions): RankedResult[] {
|
|
275
101
|
const limit = options?.limit ?? 10;
|
|
276
102
|
const rawResults = this.vault.search(query, {
|
|
277
103
|
domain: options?.domain,
|
|
@@ -280,30 +106,6 @@ export class Brain {
|
|
|
280
106
|
limit: Math.max(limit * 3, 30),
|
|
281
107
|
});
|
|
282
108
|
|
|
283
|
-
// Cognee vector search (parallel, with timeout fallback)
|
|
284
|
-
let cogneeScoreMap: Map<string, number> = new Map();
|
|
285
|
-
const cogneeAvailable = this.cognee?.isAvailable ?? false;
|
|
286
|
-
if (cogneeAvailable && this.cognee) {
|
|
287
|
-
try {
|
|
288
|
-
const cogneeResults = await this.cognee.search(query, { limit: Math.max(limit * 2, 20) });
|
|
289
|
-
for (const cr of cogneeResults) {
|
|
290
|
-
if (cr.id) cogneeScoreMap.set(cr.id, cr.score);
|
|
291
|
-
}
|
|
292
|
-
// Merge cognee-only entries into candidate pool
|
|
293
|
-
for (const cr of cogneeResults) {
|
|
294
|
-
if (cr.id && !rawResults.some((r) => r.entry.id === cr.id)) {
|
|
295
|
-
const vaultEntry = this.vault.get(cr.id);
|
|
296
|
-
if (vaultEntry) {
|
|
297
|
-
rawResults.push({ entry: vaultEntry, score: cr.score });
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
} catch {
|
|
302
|
-
// Cognee failed — fall back to FTS5 only
|
|
303
|
-
cogneeScoreMap = new Map();
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
109
|
if (rawResults.length === 0) return [];
|
|
308
110
|
|
|
309
111
|
const queryTokens = tokenize(query);
|
|
@@ -311,22 +113,9 @@ export class Brain {
|
|
|
311
113
|
const queryDomain = options?.domain;
|
|
312
114
|
const now = Math.floor(Date.now() / 1000);
|
|
313
115
|
|
|
314
|
-
// Use cognee-aware weights only if at least one ranked candidate has a vector score
|
|
315
|
-
const hasVectorCandidate = rawResults.some((r) => cogneeScoreMap.has(r.entry.id));
|
|
316
|
-
const activeWeights = hasVectorCandidate ? this.getCogneeWeights() : this.weights;
|
|
317
|
-
|
|
318
116
|
const ranked = rawResults.map((result) => {
|
|
319
117
|
const entry = result.entry;
|
|
320
|
-
const
|
|
321
|
-
const breakdown = this.scoreEntry(
|
|
322
|
-
entry,
|
|
323
|
-
queryTokens,
|
|
324
|
-
queryTags,
|
|
325
|
-
queryDomain,
|
|
326
|
-
now,
|
|
327
|
-
vectorScore,
|
|
328
|
-
activeWeights,
|
|
329
|
-
);
|
|
118
|
+
const breakdown = this.scoreEntry(entry, queryTokens, queryTags, queryDomain, now);
|
|
330
119
|
return { entry, score: breakdown.total, breakdown };
|
|
331
120
|
});
|
|
332
121
|
|
|
@@ -377,11 +166,6 @@ export class Brain {
|
|
|
377
166
|
this.vault.add(fullEntry);
|
|
378
167
|
this.updateVocabularyIncremental(fullEntry);
|
|
379
168
|
|
|
380
|
-
// Fire-and-forget Cognee sync
|
|
381
|
-
if (this.cognee?.isAvailable) {
|
|
382
|
-
this.cognee.addEntries([fullEntry]).catch(() => {});
|
|
383
|
-
}
|
|
384
|
-
|
|
385
169
|
const result: CaptureResult = {
|
|
386
170
|
captured: true,
|
|
387
171
|
id: entry.id,
|
|
@@ -405,39 +189,13 @@ export class Brain {
|
|
|
405
189
|
this.recomputeWeights();
|
|
406
190
|
}
|
|
407
191
|
|
|
408
|
-
|
|
192
|
+
getRelevantPatterns(context: QueryContext): RankedResult[] {
|
|
409
193
|
return this.intelligentSearch(context.query, {
|
|
410
194
|
domain: context.domain,
|
|
411
195
|
tags: context.tags,
|
|
412
196
|
});
|
|
413
197
|
}
|
|
414
198
|
|
|
415
|
-
async syncToCognee(): Promise<{ synced: number; cognified: boolean }> {
|
|
416
|
-
if (!this.cognee?.isAvailable) return { synced: 0, cognified: false };
|
|
417
|
-
|
|
418
|
-
const batchSize = 1000;
|
|
419
|
-
let offset = 0;
|
|
420
|
-
let totalSynced = 0;
|
|
421
|
-
|
|
422
|
-
while (true) {
|
|
423
|
-
const batch = this.vault.list({ limit: batchSize, offset });
|
|
424
|
-
if (batch.length === 0) break;
|
|
425
|
-
|
|
426
|
-
const { added } = await this.cognee.addEntries(batch);
|
|
427
|
-
totalSynced += added;
|
|
428
|
-
offset += batch.length;
|
|
429
|
-
|
|
430
|
-
if (batch.length < batchSize) break;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
if (totalSynced === 0) return { synced: 0, cognified: false };
|
|
434
|
-
|
|
435
|
-
let cognified = false;
|
|
436
|
-
const cognifyResult = await this.cognee.cognify();
|
|
437
|
-
cognified = cognifyResult.status === 'ok';
|
|
438
|
-
return { synced: totalSynced, cognified };
|
|
439
|
-
}
|
|
440
|
-
|
|
441
199
|
rebuildVocabulary(): void {
|
|
442
200
|
const entries = this.vault.list({ limit: 100000 });
|
|
443
201
|
const docCount = entries.length;
|
|
@@ -491,11 +249,7 @@ export class Brain {
|
|
|
491
249
|
queryTags: string[],
|
|
492
250
|
queryDomain: string | undefined,
|
|
493
251
|
now: number,
|
|
494
|
-
vectorScore: number = 0,
|
|
495
|
-
activeWeights?: ScoringWeights,
|
|
496
252
|
): ScoreBreakdown {
|
|
497
|
-
const w = activeWeights ?? this.weights;
|
|
498
|
-
|
|
499
253
|
let semantic = 0;
|
|
500
254
|
if (this.vocabulary.size > 0 && queryTokens.length > 0) {
|
|
501
255
|
const entryText = [
|
|
@@ -520,17 +274,14 @@ export class Brain {
|
|
|
520
274
|
|
|
521
275
|
const domainMatch = queryDomain && entry.domain === queryDomain ? 1.0 : 0;
|
|
522
276
|
|
|
523
|
-
const vector = vectorScore;
|
|
524
|
-
|
|
525
277
|
const total =
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
return { semantic, vector, severity, recency, tagOverlap, domainMatch, total };
|
|
278
|
+
this.weights.semantic * semantic +
|
|
279
|
+
this.weights.severity * severity +
|
|
280
|
+
this.weights.recency * recency +
|
|
281
|
+
this.weights.tagOverlap * tagOverlap +
|
|
282
|
+
this.weights.domainMatch * domainMatch;
|
|
283
|
+
|
|
284
|
+
return { semantic, severity, recency, tagOverlap, domainMatch, total };
|
|
534
285
|
}
|
|
535
286
|
|
|
536
287
|
private generateTags(title: string, description: string, context?: string): string[] {
|
|
@@ -624,10 +375,6 @@ export class Brain {
|
|
|
624
375
|
tx();
|
|
625
376
|
}
|
|
626
377
|
|
|
627
|
-
private getCogneeWeights(): ScoringWeights {
|
|
628
|
-
return { ...COGNEE_WEIGHTS };
|
|
629
|
-
}
|
|
630
|
-
|
|
631
378
|
private recomputeWeights(): void {
|
|
632
379
|
const db = this.vault.getDb();
|
|
633
380
|
const feedbackCount = (
|
|
@@ -654,10 +401,7 @@ export class Brain {
|
|
|
654
401
|
DEFAULT_WEIGHTS.semantic + WEIGHT_BOUND,
|
|
655
402
|
);
|
|
656
403
|
|
|
657
|
-
|
|
658
|
-
newWeights.vector = 0;
|
|
659
|
-
|
|
660
|
-
const remaining = 1.0 - newWeights.semantic - newWeights.vector;
|
|
404
|
+
const remaining = 1.0 - newWeights.semantic;
|
|
661
405
|
const otherSum =
|
|
662
406
|
DEFAULT_WEIGHTS.severity +
|
|
663
407
|
DEFAULT_WEIGHTS.recency +
|