cozo-memory 1.2.0 → 1.2.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.
@@ -283,20 +283,22 @@ class TemporalConflictResolutionService {
283
283
  async invalidateObservation(observationId) {
284
284
  // Delete the observation (query without @ "NOW" and filter manually)
285
285
  const datalog = `
286
- ?[id, created_at, entity_id, text, embedding, metadata] :=
286
+ ?[id, created_at, entity_id, text, embedding, metadata, session_id, task_id] :=
287
287
  *observation{
288
288
  id,
289
289
  created_at,
290
290
  entity_id,
291
291
  text,
292
292
  embedding,
293
- metadata
293
+ metadata,
294
+ session_id,
295
+ task_id
294
296
  },
295
297
  id = $id,
296
298
  to_bool(created_at)
297
299
 
298
300
  :delete observation {
299
- id, created_at, entity_id, text, embedding, metadata
301
+ id, created_at, entity_id, text, embedding, metadata, session_id, task_id
300
302
  }
301
303
  `;
302
304
  await this.db.run(datalog, { id: observationId });
@@ -311,16 +313,18 @@ class TemporalConflictResolutionService {
311
313
  const auditText = `[CONFLICT RESOLVED] ${conflict.conflict_type}: Observation superseded by newer information (confidence: ${(conflict.confidence * 100).toFixed(1)}%)`;
312
314
  const embedding = await this.embeddings.embed(auditText);
313
315
  const datalog = `
314
- ?[id, created_at, entity_id, text, embedding, metadata] :=
316
+ ?[id, created_at, entity_id, text, embedding, metadata, session_id, task_id] :=
315
317
  id = $id,
316
318
  created_at = $created_at,
317
319
  entity_id = $entity_id,
318
320
  text = $text,
319
321
  embedding = $embedding,
320
- metadata = $metadata
322
+ metadata = $metadata,
323
+ session_id = "",
324
+ task_id = ""
321
325
 
322
326
  :put observation {
323
- id, created_at => entity_id, text, embedding, metadata
327
+ id, created_at => entity_id, text, embedding, metadata, session_id, task_id
324
328
  }
325
329
  `;
326
330
  await this.db.run(datalog, {
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const index_1 = require("./index");
5
+ async function testActivationMCPTools() {
6
+ console.log("=== Testing ACT-R Memory Activation MCP Tools ===\n");
7
+ const server = new index_1.MemoryServer();
8
+ await server.initPromise;
9
+ try {
10
+ // Step 1: Create test entity
11
+ console.log("1. Creating test entity...");
12
+ const entityResult = await server.createEntity({
13
+ name: "ACT-R Test Entity",
14
+ type: "TestEntity",
15
+ metadata: { purpose: "testing activation" }
16
+ });
17
+ console.log("✓ Entity created:", entityResult.id);
18
+ // Step 2: Add multiple observations
19
+ console.log("\n2. Adding test observations...");
20
+ const observations = [
21
+ "First observation - should have low activation initially",
22
+ "Second observation - will be accessed multiple times",
23
+ "Third observation - will remain unaccessed",
24
+ "Fourth observation - emotionally salient content with URGENT deadline",
25
+ "Fifth observation - normal content"
26
+ ];
27
+ const obsIds = [];
28
+ for (const text of observations) {
29
+ const obs = await server.addObservation({
30
+ entity_id: entityResult.id,
31
+ text: text,
32
+ metadata: { test: true }
33
+ });
34
+ if (obs.id) {
35
+ obsIds.push(obs.id);
36
+ console.log(`✓ Observation added: ${obs.id.substring(0, 8)}...`);
37
+ }
38
+ }
39
+ // Wait a bit to simulate time passing
40
+ await new Promise(resolve => setTimeout(resolve, 100));
41
+ // Step 3: Test get_activation_stats (initial state)
42
+ console.log("\n3. Testing get_activation_stats (initial state)...");
43
+ const stats1 = await server.getActivationService().getActivationStats(entityResult.id);
44
+ console.log("✓ Initial activation stats:");
45
+ console.log(` - Total observations: ${stats1.totalObservations}`);
46
+ console.log(` - Average activation: ${stats1.averageActivation.toFixed(3)}`);
47
+ console.log(` - Average strength: ${stats1.averageStrength.toFixed(2)}`);
48
+ console.log(` - Below threshold: ${stats1.belowThreshold}`);
49
+ console.log(` - Above threshold: ${stats1.aboveThreshold}`);
50
+ console.log(` - Distribution:`, stats1.distribution);
51
+ // Step 4: Test record_memory_access
52
+ console.log("\n4. Testing record_memory_access...");
53
+ // Access the second observation multiple times
54
+ for (let i = 0; i < 3; i++) {
55
+ await server.getActivationService().recordAccess(obsIds[1]);
56
+ console.log(`✓ Access ${i + 1} recorded for observation ${obsIds[1].substring(0, 8)}...`);
57
+ }
58
+ // Access the first observation once
59
+ await server.getActivationService().recordAccess(obsIds[0]);
60
+ console.log(`✓ Access recorded for observation ${obsIds[0].substring(0, 8)}...`);
61
+ // Step 5: Check activation stats after accesses
62
+ console.log("\n5. Checking activation stats after accesses...");
63
+ const stats2 = await server.getActivationService().getActivationStats(entityResult.id);
64
+ console.log("✓ Updated activation stats:");
65
+ console.log(` - Total observations: ${stats2.totalObservations}`);
66
+ console.log(` - Average activation: ${stats2.averageActivation.toFixed(3)}`);
67
+ console.log(` - Average strength: ${stats2.averageStrength.toFixed(2)}`);
68
+ console.log(` - Below threshold: ${stats2.belowThreshold}`);
69
+ console.log(` - Above threshold: ${stats2.aboveThreshold}`);
70
+ console.log(` - Distribution:`, stats2.distribution);
71
+ // Step 6: Get detailed activation scores
72
+ console.log("\n6. Getting detailed activation scores...");
73
+ const scores = await server.getActivationService().calculateActivationScores(entityResult.id);
74
+ console.log("✓ Top 3 most active observations:");
75
+ scores.slice(0, 3).forEach((score, idx) => {
76
+ console.log(` ${idx + 1}. Activation: ${score.activation.toFixed(3)}, Strength: ${score.strength.toFixed(1)}, Access count: ${score.accessCount}`);
77
+ });
78
+ // Step 7: Test prune_weak_memories (dry run)
79
+ console.log("\n7. Testing prune_weak_memories (dry run)...");
80
+ const pruneResult1 = await server.getActivationService().pruneWeakMemories(true, entityResult.id);
81
+ console.log("✓ Dry run prune result:");
82
+ console.log(` - Would prune: ${pruneResult1.pruned}`);
83
+ console.log(` - Would preserve: ${pruneResult1.preserved}`);
84
+ console.log(` - Candidates for pruning: ${pruneResult1.candidates.length}`);
85
+ if (pruneResult1.candidates.length > 0) {
86
+ console.log(` - Sample candidate: activation=${pruneResult1.candidates[0].activation.toFixed(3)}, reason="${pruneResult1.candidates[0].reason}"`);
87
+ }
88
+ // Step 8: Test prune_weak_memories (actual prune)
89
+ console.log("\n8. Testing prune_weak_memories (actual prune)...");
90
+ const pruneResult2 = await server.getActivationService().pruneWeakMemories(false, entityResult.id);
91
+ console.log("✓ Actual prune result:");
92
+ console.log(` - Pruned: ${pruneResult2.pruned}`);
93
+ console.log(` - Preserved: ${pruneResult2.preserved}`);
94
+ // Step 9: Final activation stats
95
+ console.log("\n9. Final activation stats after pruning...");
96
+ const stats3 = await server.getActivationService().getActivationStats(entityResult.id);
97
+ console.log("✓ Final stats:");
98
+ console.log(` - Total observations: ${stats3.totalObservations}`);
99
+ console.log(` - Average activation: ${stats3.averageActivation.toFixed(3)}`);
100
+ console.log(` - Average strength: ${stats3.averageStrength.toFixed(2)}`);
101
+ console.log(` - Below threshold: ${stats3.belowThreshold}`);
102
+ console.log(` - Above threshold: ${stats3.aboveThreshold}`);
103
+ // Step 10: Test global stats (all entities)
104
+ console.log("\n10. Testing global activation stats (all entities)...");
105
+ const globalStats = await server.getActivationService().getActivationStats();
106
+ console.log("✓ Global stats:");
107
+ console.log(` - Total observations: ${globalStats.totalObservations}`);
108
+ console.log(` - Average activation: ${globalStats.averageActivation.toFixed(3)}`);
109
+ console.log(` - Below threshold: ${globalStats.belowThreshold}`);
110
+ console.log(` - Above threshold: ${globalStats.aboveThreshold}`);
111
+ console.log("\n=== ✓ All ACT-R Memory Activation MCP Tools Tests Passed ===");
112
+ }
113
+ catch (error) {
114
+ console.error("\n✗ Test failed:", error);
115
+ process.exit(1);
116
+ }
117
+ }
118
+ testActivationMCPTools();
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const index_1 = require("./index");
37
+ const fs = __importStar(require("fs"));
38
+ const TEST_DB_PATH = 'test_advanced_search_mcp';
39
+ async function runTest() {
40
+ console.error('=== Testing qafd_search and hierarchical_memory_query MCP Tools ===\n');
41
+ // Clean up old test database
42
+ const dbFile = `${TEST_DB_PATH}.db`;
43
+ if (fs.existsSync(dbFile)) {
44
+ try {
45
+ fs.unlinkSync(dbFile);
46
+ console.error('[Cleanup] Removed old test database');
47
+ }
48
+ catch (e) {
49
+ console.error('[Cleanup] Warning: Could not remove old database:', e);
50
+ }
51
+ }
52
+ const server = new index_1.MemoryServer(TEST_DB_PATH);
53
+ await server.initPromise;
54
+ try {
55
+ console.error('1. Creating test entities and relationships...');
56
+ const entity1 = await server.createEntity({
57
+ name: 'Machine Learning',
58
+ type: 'Topic',
59
+ metadata: {}
60
+ });
61
+ const entity2 = await server.createEntity({
62
+ name: 'Neural Networks',
63
+ type: 'Topic',
64
+ metadata: {}
65
+ });
66
+ const entity3 = await server.createEntity({
67
+ name: 'Deep Learning',
68
+ type: 'Topic',
69
+ metadata: {}
70
+ });
71
+ console.error(`✓ Created 3 entities\n`);
72
+ // Create relationships
73
+ await server.createRelation({
74
+ from_id: entity1.id,
75
+ to_id: entity2.id,
76
+ relation_type: 'includes',
77
+ strength: 0.9
78
+ });
79
+ await server.createRelation({
80
+ from_id: entity2.id,
81
+ to_id: entity3.id,
82
+ relation_type: 'specializes_to',
83
+ strength: 0.85
84
+ });
85
+ console.error('✓ Created relationships\n');
86
+ // Add observations at different levels
87
+ await server.addObservation({
88
+ entity_id: entity1.id,
89
+ text: 'Machine learning is a subset of artificial intelligence',
90
+ metadata: { memory_level: 0 },
91
+ deduplicate: false
92
+ });
93
+ await server.addObservation({
94
+ entity_id: entity2.id,
95
+ text: 'Neural networks are inspired by biological neurons',
96
+ metadata: { memory_level: 0 },
97
+ deduplicate: false
98
+ });
99
+ await server.addObservation({
100
+ entity_id: entity3.id,
101
+ text: 'Deep learning uses multiple layers of neural networks',
102
+ metadata: { memory_level: 1 },
103
+ deduplicate: false
104
+ });
105
+ console.error('✓ Added observations at different memory levels\n');
106
+ console.error('2. Testing qafd_search (Query-Aware Flow Diffusion)...');
107
+ const qafdResult = await server.getQueryAwareTraversal().hybridSearch('artificial intelligence and neural networks', {
108
+ seedTopK: 2,
109
+ maxHops: 2,
110
+ dampingFactor: 0.85,
111
+ minScore: 0.05,
112
+ topK: 10
113
+ });
114
+ console.error(`✓ QAFD search completed: ${qafdResult.length} results found`);
115
+ if (qafdResult.length > 0) {
116
+ console.error('\n3. Analyzing QAFD results...');
117
+ qafdResult.slice(0, 3).forEach((result, i) => {
118
+ console.error(`\n Result ${i + 1}:`);
119
+ console.error(` Entity: ${result.name || result.entity_name || 'Unknown'}`);
120
+ console.error(` Score: ${result.score?.toFixed(4) || result.finalScore?.toFixed(4) || 'N/A'}`);
121
+ console.error(` Hops: ${result.hops || result.hop || 0}`);
122
+ });
123
+ }
124
+ console.error('\n4. Testing hierarchical_memory_query...');
125
+ // Query all levels
126
+ const queryEmbedding = await server.embeddingService.embed('neural networks and deep learning');
127
+ const allLevelsResult = await server.db.run(`
128
+ ?[id, entity_id, text, memory_level, dist] :=
129
+ ~observation:semantic{
130
+ id |
131
+ query: vec($embedding),
132
+ k: 10,
133
+ ef: 100,
134
+ bind_distance: dist
135
+ },
136
+ *observation{id, entity_id, text, metadata, @ "NOW"},
137
+ memory_level = get(metadata, "memory_level", 0)
138
+
139
+ :order dist
140
+ `, { embedding: queryEmbedding });
141
+ const observations = allLevelsResult.rows.map((r) => ({
142
+ id: r[0],
143
+ entity_id: r[1],
144
+ text: r[2],
145
+ memory_level: r[3],
146
+ distance: r[4]
147
+ }));
148
+ console.error(`✓ Hierarchical memory query completed: ${observations.length} results found`);
149
+ if (observations.length > 0) {
150
+ console.error('\n5. Analyzing hierarchical memory results...');
151
+ const byLevel = {};
152
+ observations.forEach((obs) => {
153
+ byLevel[obs.memory_level] = (byLevel[obs.memory_level] || 0) + 1;
154
+ });
155
+ console.error(' Distribution by level:');
156
+ Object.entries(byLevel).forEach(([level, count]) => {
157
+ console.error(` L${level}: ${count} observations`);
158
+ });
159
+ console.error('\n Top 3 results:');
160
+ observations.slice(0, 3).forEach((obs, i) => {
161
+ console.error(`\n ${i + 1}. Level ${obs.memory_level}`);
162
+ console.error(` Text: ${obs.text.substring(0, 60)}...`);
163
+ console.error(` Distance: ${obs.distance.toFixed(4)}`);
164
+ });
165
+ }
166
+ console.error('\n6. Testing hierarchical_memory_query with level filter...');
167
+ const l0OnlyResult = await server.db.run(`
168
+ ?[id, entity_id, text, memory_level, dist] :=
169
+ ~observation:semantic{
170
+ id |
171
+ query: vec($embedding),
172
+ k: 10,
173
+ ef: 100,
174
+ bind_distance: dist
175
+ },
176
+ *observation{id, entity_id, text, metadata, @ "NOW"},
177
+ memory_level = get(metadata, "memory_level", 0),
178
+ memory_level = 0
179
+
180
+ :order dist
181
+ `, { embedding: queryEmbedding });
182
+ console.error(`✓ L0-only query completed: ${l0OnlyResult.rows.length} results found`);
183
+ console.error('\n=== ✓ Advanced Search MCP Tools Test Passed ===\n');
184
+ }
185
+ catch (error) {
186
+ console.error('\n=== ✗ Test Failed ===');
187
+ console.error('Error:', error);
188
+ throw error;
189
+ }
190
+ finally {
191
+ // Cleanup
192
+ server.db.close();
193
+ if (fs.existsSync(dbFile)) {
194
+ try {
195
+ fs.unlinkSync(dbFile);
196
+ console.error('[Cleanup] Test database removed');
197
+ }
198
+ catch (e) {
199
+ console.error('[Cleanup] Warning: Could not remove test database');
200
+ }
201
+ }
202
+ }
203
+ }
204
+ runTest().catch(console.error);
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const index_1 = require("./index");
37
+ const fs = __importStar(require("fs"));
38
+ const TEST_DB_PATH = 'test_conflicts_mcp';
39
+ async function runTest() {
40
+ console.error('=== Testing detect_conflicts and resolve_conflicts MCP Tools ===\n');
41
+ // Clean up old test database
42
+ const dbFile = `${TEST_DB_PATH}.db`;
43
+ if (fs.existsSync(dbFile)) {
44
+ try {
45
+ fs.unlinkSync(dbFile);
46
+ console.error('[Cleanup] Removed old test database');
47
+ }
48
+ catch (e) {
49
+ console.error('[Cleanup] Warning: Could not remove old database:', e);
50
+ }
51
+ }
52
+ const server = new index_1.MemoryServer(TEST_DB_PATH);
53
+ await server.initPromise;
54
+ try {
55
+ console.error('1. Creating test entity...');
56
+ const entityResult = await server.createEntity({
57
+ name: 'Project Alpha',
58
+ type: 'Project',
59
+ metadata: {}
60
+ });
61
+ const entityId = entityResult.id;
62
+ console.error(`✓ Created entity: ${entityId}\n`);
63
+ console.error('2. Adding observations with potential conflicts...');
64
+ // Add first observation
65
+ const obs1 = await server.addObservation({
66
+ entity_id: entityId,
67
+ text: 'Project status is pending approval',
68
+ metadata: { timestamp: Date.now() }
69
+ });
70
+ console.error(`✓ Added observation 1: ${obs1.id?.substring(0, 8)}...`);
71
+ // Wait a bit to ensure different timestamps
72
+ await new Promise(resolve => setTimeout(resolve, 100));
73
+ // Add redundant observation (very similar)
74
+ const obs2 = await server.addObservation({
75
+ entity_id: entityId,
76
+ text: 'Project status is pending approval and waiting',
77
+ metadata: { timestamp: Date.now() }
78
+ });
79
+ console.error(`✓ Added observation 2 (redundant): ${obs2.id?.substring(0, 8)}...`);
80
+ await new Promise(resolve => setTimeout(resolve, 100));
81
+ // Add superseding observation
82
+ const obs3 = await server.addObservation({
83
+ entity_id: entityId,
84
+ text: 'Project status updated: now approved and in progress',
85
+ metadata: { timestamp: Date.now() }
86
+ });
87
+ console.error(`✓ Added observation 3 (superseding): ${obs3.id?.substring(0, 8)}...`);
88
+ await new Promise(resolve => setTimeout(resolve, 100));
89
+ // Add contradictory observation
90
+ const obs4 = await server.addObservation({
91
+ entity_id: entityId,
92
+ text: 'Project is not approved and has been rejected',
93
+ metadata: { timestamp: Date.now() }
94
+ });
95
+ console.error(`✓ Added observation 4 (contradictory): ${obs4.id?.substring(0, 8)}...\n`);
96
+ console.error('3. Testing detect_conflicts...');
97
+ const conflicts = await server.getConflictService().detectConflicts(entityId);
98
+ console.error(`✓ Conflict detection completed: ${conflicts.length} conflicts found`);
99
+ if (conflicts.length > 0) {
100
+ console.error('\n4. Analyzing detected conflicts...');
101
+ conflicts.forEach((conflict, i) => {
102
+ console.error(`\n Conflict ${i + 1}:`);
103
+ console.error(` Type: ${conflict.conflict_type}`);
104
+ console.error(` Confidence: ${conflict.confidence.toFixed(2)} (${conflict.confidence_level})`);
105
+ console.error(` Older: "${conflict.older_text.substring(0, 50)}..."`);
106
+ console.error(` Newer: "${conflict.newer_text.substring(0, 50)}..."`);
107
+ console.error(` Reason: ${conflict.reason}`);
108
+ });
109
+ // Verify conflict types
110
+ console.error('\n5. Verifying conflict types...');
111
+ const redundancyConflicts = conflicts.filter(c => c.conflict_type === 'temporal_redundancy');
112
+ const contradictionConflicts = conflicts.filter(c => c.conflict_type === 'semantic_contradiction');
113
+ const supersededConflicts = conflicts.filter(c => c.conflict_type === 'superseded_fact');
114
+ console.error(` - Temporal Redundancy: ${redundancyConflicts.length}`);
115
+ console.error(` - Semantic Contradiction: ${contradictionConflicts.length}`);
116
+ console.error(` - Superseded Fact: ${supersededConflicts.length}`);
117
+ // Check confidence levels
118
+ const highConfidence = conflicts.filter(c => c.confidence_level === 'high');
119
+ const mediumConfidence = conflicts.filter(c => c.confidence_level === 'medium');
120
+ const lowConfidence = conflicts.filter(c => c.confidence_level === 'low');
121
+ console.error('\n6. Confidence distribution:');
122
+ console.error(` - High: ${highConfidence.length}`);
123
+ console.error(` - Medium: ${mediumConfidence.length}`);
124
+ console.error(` - Low: ${lowConfidence.length}`);
125
+ console.error('\n7. Testing resolve_conflicts...');
126
+ const resolution = await server.getConflictService().resolveConflicts(entityId);
127
+ console.error(`✓ Conflict resolution completed:`);
128
+ console.error(` - Resolved conflicts: ${resolution.resolved_conflicts}`);
129
+ console.error(` - Invalidated observations: ${resolution.invalidated_observations.length}`);
130
+ console.error(` - Audit trail entries: ${resolution.audit_observations.length}`);
131
+ if (resolution.invalidated_observations.length > 0) {
132
+ console.error('\n8. Verifying invalidated observations...');
133
+ console.error(` Invalidated IDs: ${resolution.invalidated_observations.map(id => id.substring(0, 8)).join(', ')}...`);
134
+ }
135
+ if (resolution.audit_observations.length > 0) {
136
+ console.error('\n9. Verifying audit trail...');
137
+ console.error(` Audit IDs: ${resolution.audit_observations.map(id => id.substring(0, 8)).join(', ')}...`);
138
+ }
139
+ console.error('\n10. Re-checking for conflicts after resolution...');
140
+ const remainingConflicts = await server.getConflictService().detectConflicts(entityId);
141
+ console.error(`✓ Remaining conflicts: ${remainingConflicts.length} (expected: 0)`);
142
+ if (remainingConflicts.length === 0) {
143
+ console.error(' ✓ All conflicts successfully resolved!');
144
+ }
145
+ else {
146
+ console.error(' ⚠ Some conflicts remain (this may be expected for certain conflict types)');
147
+ }
148
+ }
149
+ else {
150
+ console.error('⚠ No conflicts detected (observations may be too dissimilar)');
151
+ }
152
+ console.error('\n=== ✓ Conflict Detection and Resolution MCP Tools Test Passed ===\n');
153
+ }
154
+ catch (error) {
155
+ console.error('\n=== ✗ Test Failed ===');
156
+ console.error('Error:', error);
157
+ throw error;
158
+ }
159
+ finally {
160
+ // Cleanup
161
+ server.db.close();
162
+ if (fs.existsSync(dbFile)) {
163
+ try {
164
+ fs.unlinkSync(dbFile);
165
+ console.error('[Cleanup] Test database removed');
166
+ }
167
+ catch (e) {
168
+ console.error('[Cleanup] Warning: Could not remove test database');
169
+ }
170
+ }
171
+ }
172
+ }
173
+ runTest().catch(console.error);