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.
- package/dist/emotional-salience.js +295 -0
- package/dist/index.js +726 -9
- package/dist/memory-activation.js +64 -30
- package/dist/memory-service.js +68 -0
- package/dist/pre-storage-reasoning.js +351 -0
- package/dist/temporal-conflict-resolution.js +10 -6
- package/dist/test-activation-mcp.js +118 -0
- package/dist/test-advanced-search-mcp.js +204 -0
- package/dist/test-conflicts-mcp.js +173 -0
- package/dist/test-emotional-salience.js +177 -0
- package/dist/test-hierarchical-mcp.js +135 -0
- package/dist/test-logical-edges-mcp.js +215 -0
- package/dist/test-metadata-check.js +69 -0
- package/dist/test-metadata-update.js +92 -0
- package/dist/test-pre-storage-reasoning.js +149 -0
- package/dist/test-salience-mcp.js +94 -0
- package/dist/test-spreading-mcp.js +155 -0
- package/dist/test-suggest-connections-mcp.js +172 -0
- package/dist/test-zettelkasten-evolution.js +255 -0
- package/dist/test-zettelkasten-fixed.js +74 -0
- package/dist/test-zettelkasten-live.js +117 -0
- package/dist/test-zettelkasten-mcp.js +96 -0
- package/dist/zettelkasten-evolution.js +342 -0
- package/package.json +1 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const cozo_node_1 = require("cozo-node");
|
|
4
|
+
async function testMetadataUpdate() {
|
|
5
|
+
console.log('=== Testing Metadata Update ===\n');
|
|
6
|
+
const db = new cozo_node_1.CozoDb('sqlite', 'memory_db.cozo.db');
|
|
7
|
+
try {
|
|
8
|
+
const obsId = '0edaaeaa-5e3e-479e-a759-42227f59c868';
|
|
9
|
+
// Get current metadata
|
|
10
|
+
console.log('1. Current metadata:');
|
|
11
|
+
const current = await db.run(`
|
|
12
|
+
?[id, metadata] := *observation{id, metadata, @ "NOW"}, id = $id
|
|
13
|
+
`, { id: obsId });
|
|
14
|
+
console.log(' ', JSON.stringify(current.rows[0][1], null, 2));
|
|
15
|
+
console.log();
|
|
16
|
+
// Try updating with concat
|
|
17
|
+
console.log('2. Attempting update with concat...');
|
|
18
|
+
try {
|
|
19
|
+
await db.run(`
|
|
20
|
+
?[id, created_at, entity_id, session_id, task_id, text, embedding, metadata] :=
|
|
21
|
+
*observation{id, created_at, entity_id, session_id, task_id, text, embedding, metadata, @ "NOW"},
|
|
22
|
+
id = $id,
|
|
23
|
+
new_metadata = {
|
|
24
|
+
"zettelkasten_test": "value1",
|
|
25
|
+
"zettelkasten_enriched": true
|
|
26
|
+
},
|
|
27
|
+
metadata = if(is_null(metadata), new_metadata, concat(metadata, new_metadata))
|
|
28
|
+
|
|
29
|
+
:put observation {id, created_at => entity_id, session_id, task_id, text, embedding, metadata}
|
|
30
|
+
`, { id: obsId });
|
|
31
|
+
console.log(' Success!');
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.log(' Failed:', error.message);
|
|
35
|
+
}
|
|
36
|
+
console.log();
|
|
37
|
+
// Check if it worked
|
|
38
|
+
console.log('3. Metadata after concat attempt:');
|
|
39
|
+
const after1 = await db.run(`
|
|
40
|
+
?[id, metadata] := *observation{id, metadata, @ "NOW"}, id = $id
|
|
41
|
+
`, { id: obsId });
|
|
42
|
+
console.log(' ', JSON.stringify(after1.rows[0][1], null, 2));
|
|
43
|
+
console.log();
|
|
44
|
+
// Try a different approach - merge manually
|
|
45
|
+
console.log('4. Attempting update with manual merge...');
|
|
46
|
+
try {
|
|
47
|
+
const currentMeta = await db.run(`
|
|
48
|
+
?[metadata] := *observation{id, metadata, @ "NOW"}, id = $id
|
|
49
|
+
`, { id: obsId });
|
|
50
|
+
const existingMeta = currentMeta.rows[0][0] || {};
|
|
51
|
+
const mergedMeta = {
|
|
52
|
+
...existingMeta,
|
|
53
|
+
zettelkasten_test2: "value2",
|
|
54
|
+
zettelkasten_enriched: true,
|
|
55
|
+
zettelkasten_keywords: ["test", "keywords"]
|
|
56
|
+
};
|
|
57
|
+
await db.run(`
|
|
58
|
+
?[id, created_at, entity_id, session_id, task_id, text, embedding, metadata] :=
|
|
59
|
+
*observation{id, created_at, entity_id, session_id, task_id, text, embedding, @ "NOW"},
|
|
60
|
+
id = $id,
|
|
61
|
+
metadata = $new_metadata
|
|
62
|
+
|
|
63
|
+
:put observation {id, created_at => entity_id, session_id, task_id, text, embedding, metadata}
|
|
64
|
+
`, { id: obsId, new_metadata: mergedMeta });
|
|
65
|
+
console.log(' Success!');
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.log(' Failed:', error.message);
|
|
69
|
+
}
|
|
70
|
+
console.log();
|
|
71
|
+
// Check final result
|
|
72
|
+
console.log('5. Final metadata:');
|
|
73
|
+
const final = await db.run(`
|
|
74
|
+
?[id, metadata] := *observation{id, metadata, @ "NOW"}, id = $id
|
|
75
|
+
`, { id: obsId });
|
|
76
|
+
console.log(' ', JSON.stringify(final.rows[0][1], null, 2));
|
|
77
|
+
console.log();
|
|
78
|
+
// Check if zettelkasten_enriched is now detectable
|
|
79
|
+
console.log('6. Can we query for zettelkasten_enriched?');
|
|
80
|
+
const enrichedCheck = await db.run(`
|
|
81
|
+
?[id] :=
|
|
82
|
+
*observation{id, metadata, @ "NOW"},
|
|
83
|
+
metadata != null,
|
|
84
|
+
metadata->'zettelkasten_enriched' == true
|
|
85
|
+
`);
|
|
86
|
+
console.log(` Found ${enrichedCheck.rows.length} enriched observations`);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
console.error('Error:', error);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
testMetadataUpdate().catch(console.error);
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const cozo_node_1 = require("cozo-node");
|
|
4
|
+
const pre_storage_reasoning_1 = require("./pre-storage-reasoning");
|
|
5
|
+
async function testPreStorageReasoning() {
|
|
6
|
+
console.log('=== Pre-Storage Reasoning Test ===\n');
|
|
7
|
+
const db = new cozo_node_1.CozoDb();
|
|
8
|
+
const preStorageService = new pre_storage_reasoning_1.PreStorageReasoningService(db, {
|
|
9
|
+
enablePreStorage: true,
|
|
10
|
+
ollamaModel: 'llama3.2:3b',
|
|
11
|
+
extractEntities: true,
|
|
12
|
+
extractRelationships: true,
|
|
13
|
+
detectContradictions: true,
|
|
14
|
+
minConfidence: 0.6
|
|
15
|
+
});
|
|
16
|
+
try {
|
|
17
|
+
// Initialize database schema
|
|
18
|
+
await db.run(`
|
|
19
|
+
:create entity {
|
|
20
|
+
id: String,
|
|
21
|
+
=>
|
|
22
|
+
name: String,
|
|
23
|
+
type: String,
|
|
24
|
+
}
|
|
25
|
+
`);
|
|
26
|
+
await db.run(`
|
|
27
|
+
:create observation {
|
|
28
|
+
id: String,
|
|
29
|
+
=>
|
|
30
|
+
entity_id: String,
|
|
31
|
+
text: String,
|
|
32
|
+
metadata: Json?,
|
|
33
|
+
}
|
|
34
|
+
`);
|
|
35
|
+
await db.run(`
|
|
36
|
+
:create relationship {
|
|
37
|
+
from_id: String,
|
|
38
|
+
to_id: String,
|
|
39
|
+
relation_type: String,
|
|
40
|
+
=>
|
|
41
|
+
strength: Float,
|
|
42
|
+
metadata: Json?,
|
|
43
|
+
}
|
|
44
|
+
`);
|
|
45
|
+
console.log('✓ Database initialized\n');
|
|
46
|
+
// Create test entity
|
|
47
|
+
await db.run(`
|
|
48
|
+
?[id, name, type] <- [['project-alpha', 'Project Alpha', 'Project']]
|
|
49
|
+
:put entity {id, name, type}
|
|
50
|
+
`);
|
|
51
|
+
// Test 1: Entity Extraction
|
|
52
|
+
console.log('Test 1: Entity Extraction...');
|
|
53
|
+
const text1 = 'Alice Johnson is working on the new authentication module using TypeScript and PostgreSQL.';
|
|
54
|
+
const analysis1 = await preStorageService.analyzeBeforeStorage(text1, 'project-alpha');
|
|
55
|
+
console.log(`Text: "${text1}"`);
|
|
56
|
+
console.log(`Processing time: ${analysis1.processingTime}ms`);
|
|
57
|
+
console.log(`\nExtracted Entities (${analysis1.entitySuggestions.length}):`);
|
|
58
|
+
for (const entity of analysis1.entitySuggestions) {
|
|
59
|
+
console.log(` - ${entity.name} (${entity.type}) [confidence: ${entity.confidence.toFixed(2)}]`);
|
|
60
|
+
console.log(` Reason: ${entity.reason}`);
|
|
61
|
+
}
|
|
62
|
+
console.log();
|
|
63
|
+
// Test 2: Relationship Extraction
|
|
64
|
+
console.log('Test 2: Relationship Extraction...');
|
|
65
|
+
const text2 = 'Bob manages the frontend team and Alice reports to Bob. The team uses React for the UI.';
|
|
66
|
+
const analysis2 = await preStorageService.analyzeBeforeStorage(text2, 'project-alpha');
|
|
67
|
+
console.log(`Text: "${text2}"`);
|
|
68
|
+
console.log(`\nExtracted Relationships (${analysis2.relationshipSuggestions.length}):`);
|
|
69
|
+
for (const rel of analysis2.relationshipSuggestions) {
|
|
70
|
+
console.log(` - ${rel.fromEntity} --[${rel.relationType}]--> ${rel.toEntity} [confidence: ${rel.confidence.toFixed(2)}]`);
|
|
71
|
+
console.log(` Reason: ${rel.reason}`);
|
|
72
|
+
}
|
|
73
|
+
console.log();
|
|
74
|
+
// Test 3: Contradiction Detection
|
|
75
|
+
console.log('Test 3: Contradiction Detection...');
|
|
76
|
+
// Add existing observation
|
|
77
|
+
await db.run(`
|
|
78
|
+
?[id, entity_id, text, metadata] <- [[
|
|
79
|
+
'obs-1',
|
|
80
|
+
'project-alpha',
|
|
81
|
+
'The project deadline is December 15th, 2025',
|
|
82
|
+
{}
|
|
83
|
+
]]
|
|
84
|
+
:put observation {id, entity_id, text, metadata}
|
|
85
|
+
`);
|
|
86
|
+
const existingObs = await preStorageService.getExistingObservations('project-alpha');
|
|
87
|
+
const text3 = 'The project deadline has been moved to January 30th, 2026';
|
|
88
|
+
const analysis3 = await preStorageService.analyzeBeforeStorage(text3, 'project-alpha', existingObs);
|
|
89
|
+
console.log(`New text: "${text3}"`);
|
|
90
|
+
console.log(`Existing observations: ${existingObs.length}`);
|
|
91
|
+
console.log(`\nDetected Contradictions (${analysis3.contradictionWarnings.length}):`);
|
|
92
|
+
for (const warning of analysis3.contradictionWarnings) {
|
|
93
|
+
console.log(` ⚠ Contradiction detected [confidence: ${warning.confidence.toFixed(2)}]`);
|
|
94
|
+
console.log(` Existing: "${warning.existingObservation}"`);
|
|
95
|
+
console.log(` Contradicts: ${warning.contradiction}`);
|
|
96
|
+
console.log(` Reason: ${warning.reason}`);
|
|
97
|
+
}
|
|
98
|
+
console.log();
|
|
99
|
+
// Test 4: Auto-Apply Suggestions
|
|
100
|
+
console.log('Test 4: Auto-Apply Suggestions...');
|
|
101
|
+
const text4 = 'Sarah leads the DevOps team and works closely with the infrastructure team on Kubernetes deployment.';
|
|
102
|
+
const analysis4 = await preStorageService.analyzeBeforeStorage(text4, 'project-alpha');
|
|
103
|
+
console.log(`Text: "${text4}"`);
|
|
104
|
+
console.log(`Entities suggested: ${analysis4.entitySuggestions.length}`);
|
|
105
|
+
console.log(`Relationships suggested: ${analysis4.relationshipSuggestions.length}`);
|
|
106
|
+
const applied = await preStorageService.autoApplySuggestions(analysis4, true, // auto-create entities
|
|
107
|
+
true // auto-create relationships
|
|
108
|
+
);
|
|
109
|
+
console.log(`\n✓ Auto-applied:`);
|
|
110
|
+
console.log(` - Entities created: ${applied.entitiesCreated}`);
|
|
111
|
+
console.log(` - Relationships created: ${applied.relationshipsCreated}`);
|
|
112
|
+
console.log();
|
|
113
|
+
// Test 5: Performance Test
|
|
114
|
+
console.log('Test 5: Performance Test...');
|
|
115
|
+
const perfTests = [
|
|
116
|
+
'Quick note: Meeting at 3 PM',
|
|
117
|
+
'The API endpoint /users returns a list of all users in JSON format',
|
|
118
|
+
'Critical bug: Authentication fails when using OAuth2 with Google provider'
|
|
119
|
+
];
|
|
120
|
+
let totalTime = 0;
|
|
121
|
+
for (const text of perfTests) {
|
|
122
|
+
const analysis = await preStorageService.analyzeBeforeStorage(text, 'project-alpha');
|
|
123
|
+
totalTime += analysis.processingTime;
|
|
124
|
+
console.log(` "${text.substring(0, 50)}..." => ${analysis.processingTime}ms`);
|
|
125
|
+
}
|
|
126
|
+
console.log(`Average processing time: ${(totalTime / perfTests.length).toFixed(0)}ms\n`);
|
|
127
|
+
// Test 6: Disabled Mode
|
|
128
|
+
console.log('Test 6: Disabled Mode...');
|
|
129
|
+
const disabledService = new pre_storage_reasoning_1.PreStorageReasoningService(db, {
|
|
130
|
+
enablePreStorage: false
|
|
131
|
+
});
|
|
132
|
+
const analysis6 = await disabledService.analyzeBeforeStorage('This should not be analyzed', 'project-alpha');
|
|
133
|
+
console.log(`✓ Disabled mode: ${analysis6.processingTime}ms (should be 0)`);
|
|
134
|
+
console.log(` Entities: ${analysis6.entitySuggestions.length}`);
|
|
135
|
+
console.log(` Relationships: ${analysis6.relationshipSuggestions.length}`);
|
|
136
|
+
console.log(` Contradictions: ${analysis6.contradictionWarnings.length}`);
|
|
137
|
+
console.log();
|
|
138
|
+
console.log('=== All Tests Completed Successfully ===');
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.error('Test failed:', error);
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
db.close();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Run tests
|
|
149
|
+
testPreStorageReasoning().catch(console.error);
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const index_1 = require("./index");
|
|
5
|
+
async function testSalienceMCPTool() {
|
|
6
|
+
console.log("=== Testing Emotional Salience MCP Tool ===\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: "Salience Test Entity",
|
|
14
|
+
type: "TestEntity",
|
|
15
|
+
metadata: { purpose: "testing salience" }
|
|
16
|
+
});
|
|
17
|
+
console.log("✓ Entity created:", entityResult.id);
|
|
18
|
+
// Step 2: Add observations with varying emotional salience
|
|
19
|
+
console.log("\n2. Adding observations with different emotional levels...");
|
|
20
|
+
const observations = [
|
|
21
|
+
"URGENT: Critical security vulnerability discovered in production system!",
|
|
22
|
+
"Important meeting scheduled for tomorrow at 10 AM",
|
|
23
|
+
"The weather is nice today",
|
|
24
|
+
"DEADLINE: Project must be completed by Friday or we lose the client",
|
|
25
|
+
"Regular status update: everything is proceeding normally",
|
|
26
|
+
"Exciting news: We won the innovation award!",
|
|
27
|
+
"Failed deployment caused major outage affecting 10,000 users",
|
|
28
|
+
"Coffee machine needs refilling",
|
|
29
|
+
"Emergency: Server crash requires immediate attention",
|
|
30
|
+
"Routine maintenance completed successfully"
|
|
31
|
+
];
|
|
32
|
+
for (const text of observations) {
|
|
33
|
+
await server.addObservation({
|
|
34
|
+
entity_id: entityResult.id,
|
|
35
|
+
text: text,
|
|
36
|
+
metadata: { test: true }
|
|
37
|
+
});
|
|
38
|
+
console.log(`✓ Added: "${text.substring(0, 50)}..."`);
|
|
39
|
+
}
|
|
40
|
+
// Step 3: Test get_salience_stats
|
|
41
|
+
console.log("\n3. Testing get_salience_stats...");
|
|
42
|
+
const stats = await server.getSalienceService().getSalienceStats();
|
|
43
|
+
console.log("✓ Salience stats retrieved:");
|
|
44
|
+
console.log(` - Total observations: ${stats.totalObservations}`);
|
|
45
|
+
console.log(` - With salience (≥0.3): ${stats.withSalience}`);
|
|
46
|
+
console.log(` - Average salience: ${stats.averageSalience.toFixed(3)}`);
|
|
47
|
+
console.log(` - Distribution:`);
|
|
48
|
+
console.log(` • High: ${stats.distribution.high}`);
|
|
49
|
+
console.log(` • Medium: ${stats.distribution.medium}`);
|
|
50
|
+
console.log(` • Low: ${stats.distribution.low}`);
|
|
51
|
+
console.log(` • Neutral: ${stats.distribution.neutral}`);
|
|
52
|
+
if (stats.topKeywords.length > 0) {
|
|
53
|
+
console.log(` - Top keywords:`);
|
|
54
|
+
stats.topKeywords.slice(0, 5).forEach((kw, idx) => {
|
|
55
|
+
console.log(` ${idx + 1}. ${kw.keyword} (${kw.count})`);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
// Step 4: Verify high-salience observations
|
|
59
|
+
console.log("\n4. Verifying high-salience observations...");
|
|
60
|
+
const allScores = await server.getSalienceService().scoreAllObservations();
|
|
61
|
+
const highSalience = allScores.filter(s => s.category === 'high');
|
|
62
|
+
console.log(`✓ Found ${highSalience.length} high-salience observations:`);
|
|
63
|
+
highSalience.forEach((score, idx) => {
|
|
64
|
+
console.log(` ${idx + 1}. Score: ${score.salienceScore.toFixed(2)}, Keywords: ${score.detectedKeywords.join(", ")}`);
|
|
65
|
+
console.log(` Text: "${score.text.substring(0, 60)}..."`);
|
|
66
|
+
});
|
|
67
|
+
// Step 5: Check emotional categories
|
|
68
|
+
console.log("\n5. Checking emotional category distribution...");
|
|
69
|
+
const categories = {
|
|
70
|
+
critical: allScores.filter(s => s.detectedKeywords.some(k => ['urgent', 'critical', 'emergency'].includes(k.toLowerCase()))).length,
|
|
71
|
+
important: allScores.filter(s => s.detectedKeywords.some(k => ['important', 'deadline'].includes(k.toLowerCase()))).length,
|
|
72
|
+
emotional: allScores.filter(s => s.detectedKeywords.some(k => ['exciting', 'failed'].includes(k.toLowerCase()))).length,
|
|
73
|
+
neutral: allScores.filter(s => s.salienceScore === 0).length
|
|
74
|
+
};
|
|
75
|
+
console.log("✓ Category breakdown:");
|
|
76
|
+
console.log(` - Critical/Emergency: ${categories.critical}`);
|
|
77
|
+
console.log(` - Important/Deadline: ${categories.important}`);
|
|
78
|
+
console.log(` - Emotional: ${categories.emotional}`);
|
|
79
|
+
console.log(` - Neutral: ${categories.neutral}`);
|
|
80
|
+
// Step 6: Verify salience affects activation
|
|
81
|
+
console.log("\n6. Verifying salience integration with ACT-R...");
|
|
82
|
+
const activationStats = await server.getActivationService().getActivationStats(entityResult.id);
|
|
83
|
+
console.log("✓ ACT-R activation stats:");
|
|
84
|
+
console.log(` - Total observations: ${activationStats.totalObservations}`);
|
|
85
|
+
console.log(` - Average strength: ${activationStats.averageStrength.toFixed(2)}`);
|
|
86
|
+
console.log(` - Note: High-salience observations have boosted strength`);
|
|
87
|
+
console.log("\n=== ✓ Emotional Salience MCP Tool Test Passed ===");
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
console.error("\n✗ Test failed:", error);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
testSalienceMCPTool();
|
|
@@ -0,0 +1,155 @@
|
|
|
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_spreading_mcp';
|
|
39
|
+
async function runTest() {
|
|
40
|
+
console.error('=== Testing spreading_activation MCP Tool ===\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 knowledge graph...');
|
|
56
|
+
// Create entities
|
|
57
|
+
const aiResult = await server.createEntity({ name: 'Artificial Intelligence', type: 'Concept', metadata: {} });
|
|
58
|
+
const aiId = aiResult.id;
|
|
59
|
+
console.error(`✓ Created AI: ${aiId}`);
|
|
60
|
+
const mlResult = await server.createEntity({ name: 'Machine Learning', type: 'Concept', metadata: {} });
|
|
61
|
+
const mlId = mlResult.id;
|
|
62
|
+
console.error(`✓ Created ML: ${mlId}`);
|
|
63
|
+
const dlResult = await server.createEntity({ name: 'Deep Learning', type: 'Concept', metadata: {} });
|
|
64
|
+
const dlId = dlResult.id;
|
|
65
|
+
console.error(`✓ Created DL: ${dlId}`);
|
|
66
|
+
const nnResult = await server.createEntity({ name: 'Neural Networks', type: 'Concept', metadata: {} });
|
|
67
|
+
const nnId = nnResult.id;
|
|
68
|
+
console.error(`✓ Created NN: ${nnId}`);
|
|
69
|
+
const cnnResult = await server.createEntity({ name: 'Convolutional Neural Networks', type: 'Concept', metadata: {} });
|
|
70
|
+
const cnnId = cnnResult.id;
|
|
71
|
+
console.error(`✓ Created CNN: ${cnnId}`);
|
|
72
|
+
const rnnResult = await server.createEntity({ name: 'Recurrent Neural Networks', type: 'Concept', metadata: {} });
|
|
73
|
+
const rnnId = rnnResult.id;
|
|
74
|
+
console.error(`✓ Created RNN: ${rnnId}`);
|
|
75
|
+
const transformerResult = await server.createEntity({ name: 'Transformers', type: 'Concept', metadata: {} });
|
|
76
|
+
const transformerId = transformerResult.id;
|
|
77
|
+
console.error(`✓ Created Transformers: ${transformerId}\n`);
|
|
78
|
+
console.error('2. Creating relationships (knowledge graph structure)...');
|
|
79
|
+
// AI -> ML -> DL -> NN -> CNN/RNN/Transformers
|
|
80
|
+
await server.createRelation({ from_id: aiId, to_id: mlId, relation_type: 'includes', strength: 1.0, metadata: {} });
|
|
81
|
+
console.error('✓ AI includes ML');
|
|
82
|
+
await server.createRelation({ from_id: mlId, to_id: dlId, relation_type: 'includes', strength: 0.9, metadata: {} });
|
|
83
|
+
console.error('✓ ML includes DL');
|
|
84
|
+
await server.createRelation({ from_id: dlId, to_id: nnId, relation_type: 'uses', strength: 1.0, metadata: {} });
|
|
85
|
+
console.error('✓ DL uses NN');
|
|
86
|
+
await server.createRelation({ from_id: nnId, to_id: cnnId, relation_type: 'type_of', strength: 0.8, metadata: {} });
|
|
87
|
+
console.error('✓ NN type_of CNN');
|
|
88
|
+
await server.createRelation({ from_id: nnId, to_id: rnnId, relation_type: 'type_of', strength: 0.8, metadata: {} });
|
|
89
|
+
console.error('✓ NN type_of RNN');
|
|
90
|
+
await server.createRelation({ from_id: nnId, to_id: transformerId, relation_type: 'type_of', strength: 0.9, metadata: {} });
|
|
91
|
+
console.error('✓ NN type_of Transformers\n');
|
|
92
|
+
console.error('3. Testing spreading_activation with query "neural networks"...');
|
|
93
|
+
const result = await server.getSpreadingService().spreadActivation('neural networks', 3);
|
|
94
|
+
console.error('✓ Spreading activation completed:', {
|
|
95
|
+
totalScores: result.scores.length,
|
|
96
|
+
iterations: result.iterations,
|
|
97
|
+
converged: result.converged,
|
|
98
|
+
seedNodes: result.seedNodes.length
|
|
99
|
+
});
|
|
100
|
+
if (result.scores.length > 0) {
|
|
101
|
+
console.error('\n4. Analyzing activation scores...');
|
|
102
|
+
result.scores.slice(0, 10).forEach((score, i) => {
|
|
103
|
+
console.error(` ${i + 1}. Entity: ${score.entityId.substring(0, 8)}...`);
|
|
104
|
+
console.error(` Activation: ${score.activation.toFixed(4)}`);
|
|
105
|
+
console.error(` Source: ${score.source}`);
|
|
106
|
+
console.error(` Hops: ${score.hops}`);
|
|
107
|
+
console.error('');
|
|
108
|
+
});
|
|
109
|
+
// Verify seed nodes
|
|
110
|
+
console.error('5. Verifying seed nodes...');
|
|
111
|
+
const seedCount = result.scores.filter(s => s.source === 'seed').length;
|
|
112
|
+
const propagatedCount = result.scores.filter(s => s.source === 'propagated').length;
|
|
113
|
+
console.error(` - Seed nodes: ${seedCount}`);
|
|
114
|
+
console.error(` - Propagated nodes: ${propagatedCount}`);
|
|
115
|
+
// Check convergence
|
|
116
|
+
console.error('\n6. Convergence analysis:');
|
|
117
|
+
console.error(` - Converged: ${result.converged ? 'Yes' : 'No'}`);
|
|
118
|
+
console.error(` - Iterations: ${result.iterations}`);
|
|
119
|
+
// Verify activation distribution
|
|
120
|
+
const highActivation = result.scores.filter(s => s.activation >= 0.7).length;
|
|
121
|
+
const mediumActivation = result.scores.filter(s => s.activation >= 0.3 && s.activation < 0.7).length;
|
|
122
|
+
const lowActivation = result.scores.filter(s => s.activation < 0.3).length;
|
|
123
|
+
console.error('\n7. Activation distribution:');
|
|
124
|
+
console.error(` - High (≥0.7): ${highActivation}`);
|
|
125
|
+
console.error(` - Medium (0.3-0.7): ${mediumActivation}`);
|
|
126
|
+
console.error(` - Low (<0.3): ${lowActivation}`);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
console.error('⚠ No activation scores found');
|
|
130
|
+
}
|
|
131
|
+
console.error('\n8. Testing with different seed_top_k...');
|
|
132
|
+
const result2 = await server.getSpreadingService().spreadActivation('deep learning', 2);
|
|
133
|
+
console.error(`✓ With seed_top_k=2: ${result2.scores.length} results, ${result2.iterations} iterations`);
|
|
134
|
+
console.error('\n=== ✓ spreading_activation MCP Tool Test Passed ===\n');
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
console.error('\n=== ✗ Test Failed ===');
|
|
138
|
+
console.error('Error:', error);
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
// Cleanup
|
|
143
|
+
server.db.close();
|
|
144
|
+
if (fs.existsSync(dbFile)) {
|
|
145
|
+
try {
|
|
146
|
+
fs.unlinkSync(dbFile);
|
|
147
|
+
console.error('[Cleanup] Test database removed');
|
|
148
|
+
}
|
|
149
|
+
catch (e) {
|
|
150
|
+
console.error('[Cleanup] Warning: Could not remove test database');
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
runTest().catch(console.error);
|
|
@@ -0,0 +1,172 @@
|
|
|
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_suggest_connections_mcp';
|
|
39
|
+
async function runTest() {
|
|
40
|
+
console.error('=== Testing suggest_connections MCP Tool ===\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...');
|
|
56
|
+
// Create entities
|
|
57
|
+
const aliceResult = await server.createEntity({ name: 'Alice', type: 'Person', metadata: { role: 'Developer', team: 'Backend' } });
|
|
58
|
+
const aliceId = aliceResult.id;
|
|
59
|
+
console.error(`✓ Created Alice: ${aliceId}`);
|
|
60
|
+
const bobResult = await server.createEntity({ name: 'Bob', type: 'Person', metadata: { role: 'Engineer', team: 'Backend' } });
|
|
61
|
+
const bobId = bobResult.id;
|
|
62
|
+
console.error(`✓ Created Bob: ${bobId}`);
|
|
63
|
+
const charlieResult = await server.createEntity({ name: 'Charlie', type: 'Person', metadata: { role: 'Manager', team: 'Backend' } });
|
|
64
|
+
const charlieId = charlieResult.id;
|
|
65
|
+
console.error(`✓ Created Charlie: ${charlieId}`);
|
|
66
|
+
const davidResult = await server.createEntity({ name: 'David', type: 'Person', metadata: { role: 'Designer', team: 'Frontend' } });
|
|
67
|
+
const davidId = davidResult.id;
|
|
68
|
+
console.error(`✓ Created David: ${davidId}`);
|
|
69
|
+
const projectXResult = await server.createEntity({ name: 'Project X', type: 'Project', metadata: { status: 'active' } });
|
|
70
|
+
const projectXId = projectXResult.id;
|
|
71
|
+
console.error(`✓ Created Project X: ${projectXId}`);
|
|
72
|
+
const projectYResult = await server.createEntity({ name: 'Project Y', type: 'Project', metadata: { status: 'planning' } });
|
|
73
|
+
const projectYId = projectYResult.id;
|
|
74
|
+
console.error(`✓ Created Project Y: ${projectYId}\n`);
|
|
75
|
+
console.error('2. Creating relationships...');
|
|
76
|
+
// Alice works on Project X
|
|
77
|
+
await server.createRelation({ from_id: aliceId, to_id: projectXId, relation_type: 'works_on', strength: 1.0, metadata: {} });
|
|
78
|
+
console.error('✓ Alice works_on Project X');
|
|
79
|
+
// Bob works on Project X
|
|
80
|
+
await server.createRelation({ from_id: bobId, to_id: projectXId, relation_type: 'works_on', strength: 1.0, metadata: {} });
|
|
81
|
+
console.error('✓ Bob works_on Project X');
|
|
82
|
+
// Charlie manages Project X
|
|
83
|
+
await server.createRelation({ from_id: charlieId, to_id: projectXId, relation_type: 'manages', strength: 1.0, metadata: {} });
|
|
84
|
+
console.error('✓ Charlie manages Project X');
|
|
85
|
+
// Bob knows Charlie
|
|
86
|
+
await server.createRelation({ from_id: bobId, to_id: charlieId, relation_type: 'knows', strength: 0.8, metadata: {} });
|
|
87
|
+
console.error('✓ Bob knows Charlie');
|
|
88
|
+
// David works on Project Y
|
|
89
|
+
await server.createRelation({ from_id: davidId, to_id: projectYId, relation_type: 'works_on', strength: 1.0, metadata: {} });
|
|
90
|
+
console.error('✓ David works_on Project Y\n');
|
|
91
|
+
console.error('3. Testing suggest_connections for Alice via direct method...');
|
|
92
|
+
const suggestions = await server.getSuggestionsService().suggestConnections(aliceId);
|
|
93
|
+
console.error('✓ Suggestions retrieved:', {
|
|
94
|
+
entity_id: aliceId,
|
|
95
|
+
count: suggestions.length
|
|
96
|
+
});
|
|
97
|
+
console.error('3. Testing suggest_connections for Alice via direct method...');
|
|
98
|
+
const aliceSuggestions = await server.getSuggestionsService().suggestConnections(aliceId);
|
|
99
|
+
console.error('✓ Suggestions retrieved:', {
|
|
100
|
+
entity_id: aliceId,
|
|
101
|
+
count: aliceSuggestions.length
|
|
102
|
+
});
|
|
103
|
+
if (aliceSuggestions && aliceSuggestions.length > 0) {
|
|
104
|
+
console.error('\n4. Analyzing suggestions...');
|
|
105
|
+
aliceSuggestions.forEach((s, i) => {
|
|
106
|
+
console.error(` ${i + 1}. ${s.entity_name} (${s.entity_type})`);
|
|
107
|
+
console.error(` Source: ${s.source}`);
|
|
108
|
+
console.error(` Confidence: ${s.confidence.toFixed(2)} (${s.confidence_level})`);
|
|
109
|
+
console.error(` Reason: ${s.reason}`);
|
|
110
|
+
if (s.metadata) {
|
|
111
|
+
console.error(` Metadata:`, JSON.stringify(s.metadata));
|
|
112
|
+
}
|
|
113
|
+
console.error('');
|
|
114
|
+
});
|
|
115
|
+
// Verify expected suggestions
|
|
116
|
+
console.error('5. Verifying expected patterns...');
|
|
117
|
+
const bobSuggestion = aliceSuggestions.find((s) => s.entity_name === 'Bob');
|
|
118
|
+
if (bobSuggestion) {
|
|
119
|
+
console.error('✓ Found Bob (common neighbor via Project X)');
|
|
120
|
+
}
|
|
121
|
+
const charlieSuggestion = aliceSuggestions.find((s) => s.entity_name === 'Charlie');
|
|
122
|
+
if (charlieSuggestion) {
|
|
123
|
+
console.error('✓ Found Charlie (graph proximity via Project X)');
|
|
124
|
+
}
|
|
125
|
+
const projectYSuggestion = aliceSuggestions.find((s) => s.entity_name === 'Project Y');
|
|
126
|
+
if (projectYSuggestion) {
|
|
127
|
+
console.error('✓ Found Project Y (vector similarity)');
|
|
128
|
+
}
|
|
129
|
+
// Check confidence levels
|
|
130
|
+
const highConfidence = aliceSuggestions.filter((s) => s.confidence_level === 'high');
|
|
131
|
+
const mediumConfidence = aliceSuggestions.filter((s) => s.confidence_level === 'medium');
|
|
132
|
+
const lowConfidence = aliceSuggestions.filter((s) => s.confidence_level === 'low');
|
|
133
|
+
console.error('\n6. Confidence distribution:');
|
|
134
|
+
console.error(` - High: ${highConfidence.length}`);
|
|
135
|
+
console.error(` - Medium: ${mediumConfidence.length}`);
|
|
136
|
+
console.error(` - Low: ${lowConfidence.length}`);
|
|
137
|
+
// Check sources
|
|
138
|
+
const sources = new Set(aliceSuggestions.map((s) => s.source));
|
|
139
|
+
console.error('\n7. Discovery sources used:');
|
|
140
|
+
sources.forEach(source => {
|
|
141
|
+
const count = aliceSuggestions.filter((s) => s.source === source).length;
|
|
142
|
+
console.error(` - ${source}: ${count}`);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
console.error('⚠ No suggestions found (this might be expected for sparse graphs)');
|
|
147
|
+
}
|
|
148
|
+
console.error('\n8. Testing with custom parameters...');
|
|
149
|
+
const customSuggestions = await server.getSuggestionsService().suggestConnections(bobId);
|
|
150
|
+
console.error(`✓ Custom suggestions for Bob: ${customSuggestions.length} results`);
|
|
151
|
+
console.error('\n=== ✓ suggest_connections MCP Tool Test Passed ===\n');
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
console.error('\n=== ✗ Test Failed ===');
|
|
155
|
+
console.error('Error:', error);
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
// Cleanup
|
|
160
|
+
server.db.close();
|
|
161
|
+
if (fs.existsSync(dbFile)) {
|
|
162
|
+
try {
|
|
163
|
+
fs.unlinkSync(dbFile);
|
|
164
|
+
console.error('[Cleanup] Test database removed');
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
console.error('[Cleanup] Warning: Could not remove test database');
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
runTest().catch(console.error);
|