claude-cortex 1.5.2 → 1.6.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 +11 -1
- package/dist/__tests__/consolidation-merge.test.d.ts +9 -0
- package/dist/__tests__/consolidation-merge.test.d.ts.map +1 -0
- package/dist/__tests__/consolidation-merge.test.js +137 -0
- package/dist/__tests__/consolidation-merge.test.js.map +1 -0
- package/dist/__tests__/contradictions.test.d.ts +8 -0
- package/dist/__tests__/contradictions.test.d.ts.map +1 -0
- package/dist/__tests__/contradictions.test.js +78 -0
- package/dist/__tests__/contradictions.test.js.map +1 -0
- package/dist/__tests__/salience-evolution.test.d.ts +7 -0
- package/dist/__tests__/salience-evolution.test.d.ts.map +1 -0
- package/dist/__tests__/salience-evolution.test.js +151 -0
- package/dist/__tests__/salience-evolution.test.js.map +1 -0
- package/dist/__tests__/store.test.js +261 -0
- package/dist/__tests__/store.test.js.map +1 -1
- package/dist/memory/activation.js +1 -1
- package/dist/memory/consolidate.d.ts +4 -2
- package/dist/memory/consolidate.d.ts.map +1 -1
- package/dist/memory/consolidate.js +138 -27
- package/dist/memory/consolidate.js.map +1 -1
- package/dist/memory/salience.d.ts.map +1 -1
- package/dist/memory/salience.js +17 -1
- package/dist/memory/salience.js.map +1 -1
- package/dist/memory/store.d.ts +9 -13
- package/dist/memory/store.d.ts.map +1 -1
- package/dist/memory/store.js +181 -48
- package/dist/memory/store.js.map +1 -1
- package/dist/memory/types.d.ts +6 -0
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/memory/types.js.map +1 -1
- package/dist/tools/recall.d.ts +5 -0
- package/dist/tools/recall.d.ts.map +1 -1
- package/dist/tools/recall.js +17 -1
- package/dist/tools/recall.js.map +1 -1
- package/dist/tools/remember.d.ts +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -279,7 +279,17 @@ npm run watch
|
|
|
279
279
|
|
|
280
280
|
The dashboard provides a 3D brain visualization of your memories with real-time updates.
|
|
281
281
|
|
|
282
|
-
###
|
|
282
|
+
### Auto-Start on Login (Recommended)
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
npx claude-cortex service install # Enable auto-start
|
|
286
|
+
npx claude-cortex service uninstall # Remove auto-start
|
|
287
|
+
npx claude-cortex service status # Check status
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Works on **macOS** (launchd), **Linux** (systemd), and **Windows** (Startup folder). The dashboard and API server will start automatically on login.
|
|
291
|
+
|
|
292
|
+
### Manual Start
|
|
283
293
|
|
|
284
294
|
```bash
|
|
285
295
|
# Terminal 1: Start API server
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consolidation Merge Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests the similarity-based clustering logic used by mergeSimilarMemories.
|
|
5
|
+
* Since the full function requires database access, we test the clustering
|
|
6
|
+
* algorithm components and similarity thresholds.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=consolidation-merge.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidation-merge.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/consolidation-merge.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consolidation Merge Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests the similarity-based clustering logic used by mergeSimilarMemories.
|
|
5
|
+
* Since the full function requires database access, we test the clustering
|
|
6
|
+
* algorithm components and similarity thresholds.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it, expect } from '@jest/globals';
|
|
9
|
+
import { jaccardSimilarity } from '../memory/similarity.js';
|
|
10
|
+
describe('mergeSimilarMemories clustering logic', () => {
|
|
11
|
+
// Simulate the clustering algorithm from mergeSimilarMemories
|
|
12
|
+
function findClusters(memories, threshold = 0.25) {
|
|
13
|
+
const clustered = new Set();
|
|
14
|
+
const clusters = [];
|
|
15
|
+
for (let i = 0; i < memories.length; i++) {
|
|
16
|
+
if (clustered.has(i))
|
|
17
|
+
continue;
|
|
18
|
+
const cluster = [i];
|
|
19
|
+
const memA = memories[i];
|
|
20
|
+
for (let j = i + 1; j < memories.length; j++) {
|
|
21
|
+
if (clustered.has(j))
|
|
22
|
+
continue;
|
|
23
|
+
const memB = memories[j];
|
|
24
|
+
const contentSim = jaccardSimilarity(memA.content, memB.content);
|
|
25
|
+
const titleSim = jaccardSimilarity(memA.title, memB.title);
|
|
26
|
+
const combinedSim = contentSim * 0.6 + titleSim * 0.4;
|
|
27
|
+
if (combinedSim >= threshold) {
|
|
28
|
+
cluster.push(j);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (cluster.length >= 2) {
|
|
32
|
+
for (const idx of cluster)
|
|
33
|
+
clustered.add(idx);
|
|
34
|
+
clusters.push(cluster);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return clusters;
|
|
38
|
+
}
|
|
39
|
+
it('should cluster related JWT memories together', () => {
|
|
40
|
+
const memories = [
|
|
41
|
+
{
|
|
42
|
+
title: 'JWT authentication token setup',
|
|
43
|
+
content: 'Set up JWT authentication token signing using RS256 algorithm in the auth service for user authentication and token validation',
|
|
44
|
+
salience: 0.6,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
title: 'JWT authentication token expiry',
|
|
48
|
+
content: 'JWT authentication tokens expire after 24 hours with refresh token rotation for the auth service user authentication flow',
|
|
49
|
+
salience: 0.5,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
title: 'JWT authentication token middleware',
|
|
53
|
+
content: 'Created JWT authentication token middleware that validates user tokens on every auth service API request and handles token refresh',
|
|
54
|
+
salience: 0.4,
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
const clusters = findClusters(memories, 0.25);
|
|
58
|
+
// All 3 should be in one cluster (they share JWT/token/auth vocabulary)
|
|
59
|
+
expect(clusters.length).toBeGreaterThanOrEqual(1);
|
|
60
|
+
const biggestCluster = clusters.reduce((a, b) => (a.length > b.length ? a : b), []);
|
|
61
|
+
expect(biggestCluster.length).toBeGreaterThanOrEqual(2);
|
|
62
|
+
});
|
|
63
|
+
it('should pick highest salience memory as base', () => {
|
|
64
|
+
const memories = [
|
|
65
|
+
{ title: 'JWT authentication setup', content: 'JWT authentication token signing RS256 in auth service', salience: 0.6 },
|
|
66
|
+
{ title: 'JWT authentication expiry', content: 'JWT authentication token expiry 24 hours auth service', salience: 0.5 },
|
|
67
|
+
{ title: 'JWT authentication middleware', content: 'JWT authentication token middleware validates auth service', salience: 0.4 },
|
|
68
|
+
];
|
|
69
|
+
const clusters = findClusters(memories, 0.25);
|
|
70
|
+
expect(clusters.length).toBeGreaterThanOrEqual(1);
|
|
71
|
+
// Sort cluster by salience desc - index 0 (salience 0.6) should be first
|
|
72
|
+
const cluster = clusters[0];
|
|
73
|
+
const sorted = [...cluster].sort((a, b) => memories[b].salience - memories[a].salience);
|
|
74
|
+
expect(sorted[0]).toBe(0); // Highest salience is index 0
|
|
75
|
+
});
|
|
76
|
+
it('should not cluster unrelated memories', () => {
|
|
77
|
+
const memories = [
|
|
78
|
+
{
|
|
79
|
+
title: 'JWT Setup',
|
|
80
|
+
content: 'Set up JWT authentication using RS256 algorithm',
|
|
81
|
+
salience: 0.5,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
title: 'Database Migration',
|
|
85
|
+
content: 'Migrated PostgreSQL schema to add user preferences table with JSONB columns',
|
|
86
|
+
salience: 0.5,
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
const clusters = findClusters(memories, 0.25);
|
|
90
|
+
// These should NOT cluster - completely different topics
|
|
91
|
+
expect(clusters.length).toBe(0);
|
|
92
|
+
});
|
|
93
|
+
it('should produce correct merged content format', () => {
|
|
94
|
+
// Simulate what mergeSimilarMemories does after clustering
|
|
95
|
+
const base = {
|
|
96
|
+
title: 'JWT Setup',
|
|
97
|
+
content: 'Set up JWT authentication using RS256 algorithm for token signing in the auth service',
|
|
98
|
+
};
|
|
99
|
+
const others = [
|
|
100
|
+
{
|
|
101
|
+
title: 'JWT Token Expiry',
|
|
102
|
+
content: 'JWT tokens expire after 24 hours, refresh tokens last 30 days for the auth system',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
title: 'JWT Middleware',
|
|
106
|
+
content: 'Created JWT middleware that validates tokens on every API request and attaches user context',
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
const bulletPoints = others
|
|
110
|
+
.map(m => `- ${m.title}: ${m.content}`)
|
|
111
|
+
.join('\n');
|
|
112
|
+
const mergedContent = `${base.content}\n\nConsolidated context:\n${bulletPoints}`;
|
|
113
|
+
expect(mergedContent).toContain('RS256');
|
|
114
|
+
expect(mergedContent).toContain('24 hours');
|
|
115
|
+
expect(mergedContent).toContain('middleware');
|
|
116
|
+
expect(mergedContent).toContain('Consolidated context:');
|
|
117
|
+
});
|
|
118
|
+
it('should merge tags as a union', () => {
|
|
119
|
+
const tagSets = [
|
|
120
|
+
['jwt', 'auth'],
|
|
121
|
+
['jwt', 'expiry'],
|
|
122
|
+
['jwt', 'middleware'],
|
|
123
|
+
];
|
|
124
|
+
const allTags = new Set();
|
|
125
|
+
for (const tags of tagSets) {
|
|
126
|
+
for (const t of tags)
|
|
127
|
+
allTags.add(t);
|
|
128
|
+
}
|
|
129
|
+
expect([...allTags].sort()).toEqual(['auth', 'expiry', 'jwt', 'middleware']);
|
|
130
|
+
});
|
|
131
|
+
it('should cap salience at 1.0 after boost', () => {
|
|
132
|
+
const baseSalience = 0.95;
|
|
133
|
+
const newSalience = Math.min(1.0, baseSalience + 0.1);
|
|
134
|
+
expect(newSalience).toBe(1.0);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
//# sourceMappingURL=consolidation-merge.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidation-merge.test.js","sourceRoot":"","sources":["../../src/__tests__/consolidation-merge.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contradictions.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/contradictions.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contradiction Surfacing Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests that contradictions are properly included in search results
|
|
5
|
+
* and displayed in recall output.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect } from '@jest/globals';
|
|
8
|
+
import { formatRecallResult } from '../tools/recall.js';
|
|
9
|
+
function makeMemory(overrides = {}) {
|
|
10
|
+
return {
|
|
11
|
+
id: 1,
|
|
12
|
+
type: 'long_term',
|
|
13
|
+
category: 'architecture',
|
|
14
|
+
title: 'Use PostgreSQL',
|
|
15
|
+
content: 'Decided to use PostgreSQL for the database',
|
|
16
|
+
project: 'test',
|
|
17
|
+
tags: [],
|
|
18
|
+
salience: 0.8,
|
|
19
|
+
accessCount: 1,
|
|
20
|
+
lastAccessed: new Date(),
|
|
21
|
+
createdAt: new Date(),
|
|
22
|
+
decayedScore: 0.7,
|
|
23
|
+
metadata: {},
|
|
24
|
+
scope: 'project',
|
|
25
|
+
transferable: false,
|
|
26
|
+
...overrides,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
describe('SearchResult contradictions field', () => {
|
|
30
|
+
it('should allow contradictions on SearchResult', () => {
|
|
31
|
+
const result = {
|
|
32
|
+
memory: makeMemory(),
|
|
33
|
+
relevanceScore: 0.9,
|
|
34
|
+
contradictions: [
|
|
35
|
+
{ memoryId: 2, title: 'Use SQLite', score: 0.8 },
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
expect(result.contradictions).toBeDefined();
|
|
39
|
+
expect(result.contradictions).toHaveLength(1);
|
|
40
|
+
expect(result.contradictions[0].memoryId).toBe(2);
|
|
41
|
+
expect(result.contradictions[0].title).toBe('Use SQLite');
|
|
42
|
+
expect(result.contradictions[0].score).toBe(0.8);
|
|
43
|
+
});
|
|
44
|
+
it('should allow SearchResult without contradictions', () => {
|
|
45
|
+
const result = {
|
|
46
|
+
memory: makeMemory(),
|
|
47
|
+
relevanceScore: 0.9,
|
|
48
|
+
};
|
|
49
|
+
expect(result.contradictions).toBeUndefined();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
describe('formatRecallResult with contradictions', () => {
|
|
53
|
+
it('should show contradiction warnings in formatted output', () => {
|
|
54
|
+
const mem1 = makeMemory({ id: 1, title: 'Use PostgreSQL' });
|
|
55
|
+
const mem2 = makeMemory({ id: 2, title: 'Use SQLite' });
|
|
56
|
+
const contradictions = new Map();
|
|
57
|
+
contradictions.set(1, [{ memoryId: 2, title: 'Use SQLite', score: 0.8 }]);
|
|
58
|
+
const output = formatRecallResult({
|
|
59
|
+
success: true,
|
|
60
|
+
memories: [mem1, mem2],
|
|
61
|
+
contradictions,
|
|
62
|
+
count: 2,
|
|
63
|
+
});
|
|
64
|
+
expect(output).toContain('CONTRADICTS');
|
|
65
|
+
expect(output).toContain('"Use SQLite"');
|
|
66
|
+
expect(output).toContain('ID 2');
|
|
67
|
+
});
|
|
68
|
+
it('should not show contradiction warning for memories without contradictions', () => {
|
|
69
|
+
const mem = makeMemory({ id: 3, title: 'Some memory' });
|
|
70
|
+
const output = formatRecallResult({
|
|
71
|
+
success: true,
|
|
72
|
+
memories: [mem],
|
|
73
|
+
count: 1,
|
|
74
|
+
});
|
|
75
|
+
expect(output).not.toContain('CONTRADICTS');
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=contradictions.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contradictions.test.js","sourceRoot":"","sources":["../../src/__tests__/contradictions.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"salience-evolution.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/salience-evolution.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Salience Evolution Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests that salience evolves over time based on structural importance.
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeAll, afterAll } from '@jest/globals';
|
|
7
|
+
import Database from 'better-sqlite3';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import os from 'os';
|
|
11
|
+
describe('Salience Evolution', () => {
|
|
12
|
+
let db;
|
|
13
|
+
let dbPath;
|
|
14
|
+
beforeAll(() => {
|
|
15
|
+
// Create a temp database for testing
|
|
16
|
+
dbPath = path.join(os.tmpdir(), `claude-cortex-test-${Date.now()}.db`);
|
|
17
|
+
db = new Database(dbPath);
|
|
18
|
+
// Create minimal schema
|
|
19
|
+
db.exec(`
|
|
20
|
+
CREATE TABLE IF NOT EXISTS memories (
|
|
21
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
22
|
+
type TEXT NOT NULL DEFAULT 'short_term',
|
|
23
|
+
category TEXT NOT NULL DEFAULT 'note',
|
|
24
|
+
title TEXT NOT NULL,
|
|
25
|
+
content TEXT NOT NULL,
|
|
26
|
+
project TEXT,
|
|
27
|
+
tags TEXT DEFAULT '[]',
|
|
28
|
+
salience REAL DEFAULT 0.5,
|
|
29
|
+
decayed_score REAL DEFAULT 0.5,
|
|
30
|
+
access_count INTEGER DEFAULT 0,
|
|
31
|
+
metadata TEXT DEFAULT '{}',
|
|
32
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
33
|
+
last_accessed DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
CREATE TABLE IF NOT EXISTS memory_links (
|
|
37
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
38
|
+
source_id INTEGER NOT NULL,
|
|
39
|
+
target_id INTEGER NOT NULL,
|
|
40
|
+
relationship TEXT NOT NULL DEFAULT 'related',
|
|
41
|
+
strength REAL DEFAULT 0.5,
|
|
42
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
43
|
+
FOREIGN KEY (source_id) REFERENCES memories(id) ON DELETE CASCADE,
|
|
44
|
+
FOREIGN KEY (target_id) REFERENCES memories(id) ON DELETE CASCADE,
|
|
45
|
+
UNIQUE(source_id, target_id, relationship)
|
|
46
|
+
);
|
|
47
|
+
`);
|
|
48
|
+
});
|
|
49
|
+
afterAll(() => {
|
|
50
|
+
db.close();
|
|
51
|
+
try {
|
|
52
|
+
fs.unlinkSync(dbPath);
|
|
53
|
+
}
|
|
54
|
+
catch { }
|
|
55
|
+
});
|
|
56
|
+
it('should boost salience of hub memories with many links', () => {
|
|
57
|
+
// Create a hub memory
|
|
58
|
+
const hubResult = db.prepare(`
|
|
59
|
+
INSERT INTO memories (type, category, title, content, salience)
|
|
60
|
+
VALUES ('long_term', 'architecture', 'Hub Memory', 'Central architecture decision', 0.5)
|
|
61
|
+
`).run();
|
|
62
|
+
const hubId = hubResult.lastInsertRowid;
|
|
63
|
+
// Create 5 linked memories
|
|
64
|
+
const linkedIds = [];
|
|
65
|
+
for (let i = 0; i < 5; i++) {
|
|
66
|
+
const r = db.prepare(`
|
|
67
|
+
INSERT INTO memories (type, category, title, content, salience)
|
|
68
|
+
VALUES ('long_term', 'note', 'Linked ${i}', 'Related content ${i}', 0.4)
|
|
69
|
+
`).run();
|
|
70
|
+
linkedIds.push(r.lastInsertRowid);
|
|
71
|
+
db.prepare(`
|
|
72
|
+
INSERT INTO memory_links (source_id, target_id, relationship, strength)
|
|
73
|
+
VALUES (?, ?, 'related', 0.5)
|
|
74
|
+
`).run(linkedIds[i], hubId);
|
|
75
|
+
}
|
|
76
|
+
const originalSalience = db.prepare('SELECT salience FROM memories WHERE id = ?').get(hubId).salience;
|
|
77
|
+
// Run evolveSalience logic inline (same as the function)
|
|
78
|
+
const hubs = db.prepare(`
|
|
79
|
+
SELECT m.id, m.salience,
|
|
80
|
+
(SELECT COUNT(*) FROM memory_links WHERE source_id = m.id OR target_id = m.id) as link_count
|
|
81
|
+
FROM memories m
|
|
82
|
+
WHERE m.type IN ('long_term', 'episodic')
|
|
83
|
+
`).all();
|
|
84
|
+
for (const hub of hubs) {
|
|
85
|
+
if (hub.link_count < 2)
|
|
86
|
+
continue;
|
|
87
|
+
const linkBonus = Math.min(0.1, Math.log2(hub.link_count) * 0.03);
|
|
88
|
+
const newSalience = Math.min(1.0, hub.salience + linkBonus);
|
|
89
|
+
if (newSalience > hub.salience) {
|
|
90
|
+
db.prepare('UPDATE memories SET salience = ? WHERE id = ?').run(newSalience, hub.id);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const newSalience = db.prepare('SELECT salience FROM memories WHERE id = ?').get(hubId).salience;
|
|
94
|
+
expect(newSalience).toBeGreaterThan(originalSalience);
|
|
95
|
+
});
|
|
96
|
+
it('should penalize contradicted memories', () => {
|
|
97
|
+
// Create two contradicting memories
|
|
98
|
+
const m1 = db.prepare(`
|
|
99
|
+
INSERT INTO memories (type, category, title, content, salience)
|
|
100
|
+
VALUES ('long_term', 'architecture', 'Use REST', 'We should use REST APIs', 0.6)
|
|
101
|
+
`).run();
|
|
102
|
+
const m2 = db.prepare(`
|
|
103
|
+
INSERT INTO memories (type, category, title, content, salience)
|
|
104
|
+
VALUES ('long_term', 'architecture', 'Use GraphQL', 'We should use GraphQL', 0.6)
|
|
105
|
+
`).run();
|
|
106
|
+
db.prepare(`
|
|
107
|
+
INSERT INTO memory_links (source_id, target_id, relationship, strength)
|
|
108
|
+
VALUES (?, ?, 'contradicts', 0.8)
|
|
109
|
+
`).run(m1.lastInsertRowid, m2.lastInsertRowid);
|
|
110
|
+
// Run contradiction penalty logic
|
|
111
|
+
const contradicted = db.prepare(`
|
|
112
|
+
SELECT DISTINCT source_id, target_id
|
|
113
|
+
FROM memory_links
|
|
114
|
+
WHERE relationship = 'contradicts'
|
|
115
|
+
`).all();
|
|
116
|
+
for (const pair of contradicted) {
|
|
117
|
+
for (const id of [pair.source_id, pair.target_id]) {
|
|
118
|
+
const mem = db.prepare('SELECT salience FROM memories WHERE id = ?').get(id);
|
|
119
|
+
if (mem && mem.salience > 0.3) {
|
|
120
|
+
db.prepare('UPDATE memories SET salience = ? WHERE id = ?')
|
|
121
|
+
.run(mem.salience - 0.02, id);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const s1 = db.prepare('SELECT salience FROM memories WHERE id = ?').get(m1.lastInsertRowid).salience;
|
|
126
|
+
const s2 = db.prepare('SELECT salience FROM memories WHERE id = ?').get(m2.lastInsertRowid).salience;
|
|
127
|
+
expect(s1).toBeCloseTo(0.58, 2);
|
|
128
|
+
expect(s2).toBeCloseTo(0.58, 2);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
describe('Mention Count', () => {
|
|
132
|
+
it('should count keyword mentions in text', async () => {
|
|
133
|
+
const { analyzeSalienceFactors } = await import('../memory/salience.js');
|
|
134
|
+
// Text with multiple keyword matches
|
|
135
|
+
const factors = analyzeSalienceFactors({
|
|
136
|
+
title: 'Architecture fix',
|
|
137
|
+
content: 'Fixed a bug in the database schema pattern using a workaround strategy',
|
|
138
|
+
});
|
|
139
|
+
// Should match multiple keywords across categories
|
|
140
|
+
expect(factors.mentionCount).toBeGreaterThan(1);
|
|
141
|
+
});
|
|
142
|
+
it('should return at least 1 for text with no keywords', async () => {
|
|
143
|
+
const { analyzeSalienceFactors } = await import('../memory/salience.js');
|
|
144
|
+
const factors = analyzeSalienceFactors({
|
|
145
|
+
title: 'Hello',
|
|
146
|
+
content: 'Just a simple note',
|
|
147
|
+
});
|
|
148
|
+
expect(factors.mentionCount).toBeGreaterThanOrEqual(1);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
//# sourceMappingURL=salience-evolution.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"salience-evolution.test.js","sourceRoot":"","sources":["../../src/__tests__/salience-evolution.test.ts"],"names":[],"mappings":"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"}
|