mcp-memory-keeper 0.10.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/CHANGELOG.md +433 -0
- package/LICENSE +21 -0
- package/README.md +1051 -0
- package/bin/mcp-memory-keeper +52 -0
- package/dist/__tests__/helpers/database-test-helper.js +160 -0
- package/dist/__tests__/helpers/test-server.js +92 -0
- package/dist/__tests__/integration/advanced-features.test.js +614 -0
- package/dist/__tests__/integration/backward-compatibility.test.js +245 -0
- package/dist/__tests__/integration/batchOperationsE2E.test.js +396 -0
- package/dist/__tests__/integration/batchOperationsHandler.test.js +1230 -0
- package/dist/__tests__/integration/channelManagementHandler.test.js +1291 -0
- package/dist/__tests__/integration/channels.test.js +376 -0
- package/dist/__tests__/integration/checkpoint.test.js +251 -0
- package/dist/__tests__/integration/concurrent-access.test.js +190 -0
- package/dist/__tests__/integration/context-operations.test.js +243 -0
- package/dist/__tests__/integration/contextDiff.test.js +852 -0
- package/dist/__tests__/integration/contextDiffHandler.test.js +976 -0
- package/dist/__tests__/integration/contextExportHandler.test.js +510 -0
- package/dist/__tests__/integration/contextGetPaginationDefaults.test.js +298 -0
- package/dist/__tests__/integration/contextReassignChannelHandler.test.js +908 -0
- package/dist/__tests__/integration/contextRelationshipsHandler.test.js +1151 -0
- package/dist/__tests__/integration/contextSearch.test.js +938 -0
- package/dist/__tests__/integration/contextSearchHandler.test.js +552 -0
- package/dist/__tests__/integration/contextWatchActual.test.js +165 -0
- package/dist/__tests__/integration/contextWatchHandler.test.js +1500 -0
- package/dist/__tests__/integration/cross-session-sharing.test.js +302 -0
- package/dist/__tests__/integration/database-initialization.test.js +134 -0
- package/dist/__tests__/integration/enhanced-context-operations.test.js +1082 -0
- package/dist/__tests__/integration/enhancedContextGetHandler.test.js +915 -0
- package/dist/__tests__/integration/enhancedContextTimelineHandler.test.js +716 -0
- package/dist/__tests__/integration/error-cases.test.js +407 -0
- package/dist/__tests__/integration/export-import.test.js +367 -0
- package/dist/__tests__/integration/feature-flags.test.js +542 -0
- package/dist/__tests__/integration/file-operations.test.js +264 -0
- package/dist/__tests__/integration/git-integration.test.js +237 -0
- package/dist/__tests__/integration/index-tools.test.js +496 -0
- package/dist/__tests__/integration/issue11-actual-bug-demo.test.js +304 -0
- package/dist/__tests__/integration/issue11-search-filters-bug.test.js +561 -0
- package/dist/__tests__/integration/issue12-checkpoint-restore-behavior.test.js +621 -0
- package/dist/__tests__/integration/issue13-key-validation.test.js +433 -0
- package/dist/__tests__/integration/knowledge-graph.test.js +338 -0
- package/dist/__tests__/integration/migrations.test.js +528 -0
- package/dist/__tests__/integration/multi-agent.test.js +546 -0
- package/dist/__tests__/integration/pagination-critical-fix.test.js +296 -0
- package/dist/__tests__/integration/paginationDefaultsHandler.test.js +600 -0
- package/dist/__tests__/integration/project-directory.test.js +283 -0
- package/dist/__tests__/integration/resource-cleanup.test.js +149 -0
- package/dist/__tests__/integration/retention.test.js +513 -0
- package/dist/__tests__/integration/search.test.js +333 -0
- package/dist/__tests__/integration/semantic-search.test.js +266 -0
- package/dist/__tests__/integration/server-initialization.test.js +307 -0
- package/dist/__tests__/integration/session-management.test.js +219 -0
- package/dist/__tests__/integration/simplified-sharing.test.js +346 -0
- package/dist/__tests__/integration/smart-compaction.test.js +230 -0
- package/dist/__tests__/integration/summarization.test.js +308 -0
- package/dist/__tests__/integration/watcher-migration-validation.test.js +544 -0
- package/dist/__tests__/security/input-validation.test.js +115 -0
- package/dist/__tests__/utils/agents.test.js +473 -0
- package/dist/__tests__/utils/database.test.js +177 -0
- package/dist/__tests__/utils/git.test.js +122 -0
- package/dist/__tests__/utils/knowledge-graph.test.js +297 -0
- package/dist/__tests__/utils/migrationHealthCheck.test.js +302 -0
- package/dist/__tests__/utils/project-directory-messages.test.js +188 -0
- package/dist/__tests__/utils/timezone-safe-dates.js +119 -0
- package/dist/__tests__/utils/validation.test.js +200 -0
- package/dist/__tests__/utils/vector-store.test.js +231 -0
- package/dist/handlers/contextWatchHandlers.js +206 -0
- package/dist/index.js +4310 -0
- package/dist/index.phase1.backup.js +410 -0
- package/dist/index.phase2.backup.js +704 -0
- package/dist/migrations/003_add_channels.js +174 -0
- package/dist/migrations/004_add_context_watch.js +151 -0
- package/dist/migrations/005_add_context_watch.js +98 -0
- package/dist/migrations/simplify-sharing.js +117 -0
- package/dist/repositories/BaseRepository.js +30 -0
- package/dist/repositories/CheckpointRepository.js +140 -0
- package/dist/repositories/ContextRepository.js +1873 -0
- package/dist/repositories/FileRepository.js +104 -0
- package/dist/repositories/RepositoryManager.js +62 -0
- package/dist/repositories/SessionRepository.js +66 -0
- package/dist/repositories/WatcherRepository.js +252 -0
- package/dist/repositories/index.js +15 -0
- package/dist/server.js +384 -0
- package/dist/test-helpers/database-helper.js +128 -0
- package/dist/types/entities.js +3 -0
- package/dist/utils/agents.js +791 -0
- package/dist/utils/channels.js +150 -0
- package/dist/utils/database.js +731 -0
- package/dist/utils/feature-flags.js +476 -0
- package/dist/utils/git.js +145 -0
- package/dist/utils/knowledge-graph.js +264 -0
- package/dist/utils/migrationHealthCheck.js +373 -0
- package/dist/utils/migrations.js +452 -0
- package/dist/utils/retention.js +460 -0
- package/dist/utils/timestamps.js +112 -0
- package/dist/utils/validation.js +296 -0
- package/dist/utils/vector-store.js +247 -0
- package/package.json +84 -0
|
@@ -0,0 +1,338 @@
|
|
|
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 database_1 = require("../../utils/database");
|
|
37
|
+
const knowledge_graph_1 = require("../../utils/knowledge-graph");
|
|
38
|
+
const os = __importStar(require("os"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const uuid_1 = require("uuid");
|
|
42
|
+
describe('Knowledge Graph Integration Tests', () => {
|
|
43
|
+
let dbManager;
|
|
44
|
+
let knowledgeGraph;
|
|
45
|
+
let tempDbPath;
|
|
46
|
+
let db;
|
|
47
|
+
let testSessionId;
|
|
48
|
+
beforeEach(() => {
|
|
49
|
+
tempDbPath = path.join(os.tmpdir(), `test-kg-integration-${Date.now()}.db`);
|
|
50
|
+
dbManager = new database_1.DatabaseManager({
|
|
51
|
+
filename: tempDbPath,
|
|
52
|
+
maxSize: 10 * 1024 * 1024,
|
|
53
|
+
walMode: true,
|
|
54
|
+
});
|
|
55
|
+
db = dbManager.getDatabase();
|
|
56
|
+
knowledgeGraph = new knowledge_graph_1.KnowledgeGraphManager(db);
|
|
57
|
+
// Create test session
|
|
58
|
+
testSessionId = (0, uuid_1.v4)();
|
|
59
|
+
db.prepare('INSERT INTO sessions (id, name, description) VALUES (?, ?, ?)').run(testSessionId, 'KG Integration Test', 'Testing knowledge graph integration');
|
|
60
|
+
});
|
|
61
|
+
afterEach(() => {
|
|
62
|
+
dbManager.close();
|
|
63
|
+
try {
|
|
64
|
+
fs.unlinkSync(tempDbPath);
|
|
65
|
+
fs.unlinkSync(`${tempDbPath}-wal`);
|
|
66
|
+
fs.unlinkSync(`${tempDbPath}-shm`);
|
|
67
|
+
}
|
|
68
|
+
catch (_e) {
|
|
69
|
+
// Ignore
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
describe('context_analyze', () => {
|
|
73
|
+
beforeEach(() => {
|
|
74
|
+
// Add some context items to analyze
|
|
75
|
+
const items = [
|
|
76
|
+
{
|
|
77
|
+
key: 'task_auth',
|
|
78
|
+
value: 'Working on AuthService class that implements authentication using JWT tokens',
|
|
79
|
+
category: 'task',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
key: 'decision_db',
|
|
83
|
+
value: 'UserModel extends BaseModel and uses PostgreSQL database',
|
|
84
|
+
category: 'decision',
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
key: 'progress_api',
|
|
88
|
+
value: 'The function validateToken calls checkExpiry and getUserById',
|
|
89
|
+
category: 'progress',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
key: 'note_files',
|
|
93
|
+
value: 'Modified files: auth.service.ts, user.model.ts, and token.utils.ts',
|
|
94
|
+
category: 'note',
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
items.forEach(item => {
|
|
98
|
+
db.prepare('INSERT INTO context_items (id, session_id, key, value, category) VALUES (?, ?, ?, ?, ?)').run((0, uuid_1.v4)(), testSessionId, item.key, item.value, item.category);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
it('should analyze all context items and extract entities', () => {
|
|
102
|
+
// Simulate context_analyze tool call
|
|
103
|
+
const items = db
|
|
104
|
+
.prepare('SELECT * FROM context_items WHERE session_id = ?')
|
|
105
|
+
.all(testSessionId);
|
|
106
|
+
let entitiesCreated = 0;
|
|
107
|
+
let _relationsCreated = 0;
|
|
108
|
+
for (const item of items) {
|
|
109
|
+
const analysis = knowledgeGraph.analyzeContext(testSessionId, item.value);
|
|
110
|
+
for (const entityData of analysis.entities) {
|
|
111
|
+
const existing = knowledgeGraph.findEntity(testSessionId, entityData.name, entityData.type);
|
|
112
|
+
if (!existing) {
|
|
113
|
+
knowledgeGraph.createEntity(testSessionId, entityData.type, entityData.name, {
|
|
114
|
+
confidence: entityData.confidence,
|
|
115
|
+
source: item.key,
|
|
116
|
+
});
|
|
117
|
+
entitiesCreated++;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
for (const relationData of analysis.relations) {
|
|
121
|
+
const subject = knowledgeGraph.findEntity(testSessionId, relationData.subject);
|
|
122
|
+
const object = knowledgeGraph.findEntity(testSessionId, relationData.object);
|
|
123
|
+
if (subject && object) {
|
|
124
|
+
knowledgeGraph.createRelation(testSessionId, subject.id, relationData.predicate, object.id, relationData.confidence);
|
|
125
|
+
_relationsCreated++;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
expect(entitiesCreated).toBeGreaterThan(0);
|
|
130
|
+
// Verify specific entities were created
|
|
131
|
+
expect(knowledgeGraph.findEntity(testSessionId, 'AuthService')).toBeDefined();
|
|
132
|
+
expect(knowledgeGraph.findEntity(testSessionId, 'auth.service.ts')).toBeDefined();
|
|
133
|
+
expect(knowledgeGraph.findEntity(testSessionId, 'validateToken')).toBeDefined();
|
|
134
|
+
});
|
|
135
|
+
it('should analyze specific categories only', () => {
|
|
136
|
+
const categories = ['task', 'decision'];
|
|
137
|
+
const items = db
|
|
138
|
+
.prepare(`SELECT * FROM context_items WHERE session_id = ? AND category IN (${categories.map(() => '?').join(',')})`)
|
|
139
|
+
.all(testSessionId, ...categories);
|
|
140
|
+
expect(items).toHaveLength(2);
|
|
141
|
+
for (const item of items) {
|
|
142
|
+
const analysis = knowledgeGraph.analyzeContext(testSessionId, item.value);
|
|
143
|
+
expect(analysis.entities.length).toBeGreaterThan(0);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
describe('context_find_related', () => {
|
|
148
|
+
beforeEach(() => {
|
|
149
|
+
// Create a network of entities
|
|
150
|
+
const authService = knowledgeGraph.createEntity(testSessionId, 'class', 'AuthService');
|
|
151
|
+
const userModel = knowledgeGraph.createEntity(testSessionId, 'class', 'UserModel');
|
|
152
|
+
const tokenUtil = knowledgeGraph.createEntity(testSessionId, 'module', 'TokenUtil');
|
|
153
|
+
const database = knowledgeGraph.createEntity(testSessionId, 'database', 'PostgreSQL');
|
|
154
|
+
const validateFunc = knowledgeGraph.createEntity(testSessionId, 'function', 'validateToken');
|
|
155
|
+
// Create relations
|
|
156
|
+
knowledgeGraph.createRelation(testSessionId, authService.id, 'uses', userModel.id);
|
|
157
|
+
knowledgeGraph.createRelation(testSessionId, authService.id, 'imports', tokenUtil.id);
|
|
158
|
+
knowledgeGraph.createRelation(testSessionId, userModel.id, 'stores_in', database.id);
|
|
159
|
+
knowledgeGraph.createRelation(testSessionId, authService.id, 'contains', validateFunc.id);
|
|
160
|
+
// Add a context item that references AuthService
|
|
161
|
+
db.prepare('INSERT INTO context_items (id, session_id, key, value) VALUES (?, ?, ?, ?)').run((0, uuid_1.v4)(), testSessionId, 'auth_task', 'Working on AuthService authentication');
|
|
162
|
+
});
|
|
163
|
+
it('should find related entities by entity name', () => {
|
|
164
|
+
const entity = knowledgeGraph.findEntity(testSessionId, 'AuthService');
|
|
165
|
+
expect(entity).toBeDefined();
|
|
166
|
+
const connected = knowledgeGraph.getConnectedEntities(entity.id, 2);
|
|
167
|
+
expect(connected.size).toBeGreaterThan(1);
|
|
168
|
+
// Should include AuthService and its connections
|
|
169
|
+
const entities = Array.from(connected).map(id => {
|
|
170
|
+
const e = db.prepare('SELECT * FROM entities WHERE id = ?').get(id);
|
|
171
|
+
return e.name;
|
|
172
|
+
});
|
|
173
|
+
expect(entities).toContain('AuthService');
|
|
174
|
+
expect(entities).toContain('UserModel');
|
|
175
|
+
expect(entities).toContain('TokenUtil');
|
|
176
|
+
expect(entities).toContain('validateToken');
|
|
177
|
+
});
|
|
178
|
+
it('should find related entities by context key', () => {
|
|
179
|
+
const contextItem = db
|
|
180
|
+
.prepare('SELECT * FROM context_items WHERE session_id = ? AND key = ?')
|
|
181
|
+
.get(testSessionId, 'auth_task');
|
|
182
|
+
expect(contextItem).toBeDefined();
|
|
183
|
+
// Extract entity from context
|
|
184
|
+
const analysis = knowledgeGraph.analyzeContext(testSessionId, contextItem.value);
|
|
185
|
+
expect(analysis.entities.length).toBeGreaterThan(0);
|
|
186
|
+
const entity = knowledgeGraph.findEntity(testSessionId, 'AuthService');
|
|
187
|
+
expect(entity).toBeDefined();
|
|
188
|
+
});
|
|
189
|
+
it('should filter by relation types', () => {
|
|
190
|
+
const entity = knowledgeGraph.findEntity(testSessionId, 'AuthService');
|
|
191
|
+
const relations = knowledgeGraph.getRelations(entity.id);
|
|
192
|
+
const usesRelations = relations.filter(r => r.predicate === 'uses');
|
|
193
|
+
const importsRelations = relations.filter(r => r.predicate === 'imports');
|
|
194
|
+
expect(usesRelations.length).toBeGreaterThan(0);
|
|
195
|
+
expect(importsRelations.length).toBeGreaterThan(0);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
describe('context_visualize', () => {
|
|
199
|
+
beforeEach(() => {
|
|
200
|
+
// Create entities for visualization
|
|
201
|
+
knowledgeGraph.createEntity(testSessionId, 'class', 'User');
|
|
202
|
+
knowledgeGraph.createEntity(testSessionId, 'class', 'Product');
|
|
203
|
+
knowledgeGraph.createEntity(testSessionId, 'service', 'AuthService');
|
|
204
|
+
// Create context items with different categories and times
|
|
205
|
+
const now = new Date();
|
|
206
|
+
for (let i = 0; i < 10; i++) {
|
|
207
|
+
const category = ['task', 'decision', 'progress'][i % 3];
|
|
208
|
+
const priority = ['high', 'normal', 'low'][i % 3];
|
|
209
|
+
db.prepare(`INSERT INTO context_items
|
|
210
|
+
(id, session_id, key, value, category, priority, created_at)
|
|
211
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`).run((0, uuid_1.v4)(), testSessionId, `item_${i}`, `Test item ${i}`, category, priority, new Date(now.getTime() - i * 3600000).toISOString() // 1 hour apart
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
it('should generate graph visualization data', () => {
|
|
216
|
+
const user = knowledgeGraph.findEntity(testSessionId, 'User');
|
|
217
|
+
const auth = knowledgeGraph.findEntity(testSessionId, 'AuthService');
|
|
218
|
+
knowledgeGraph.createRelation(testSessionId, auth.id, 'validates', user.id);
|
|
219
|
+
const graphData = knowledgeGraph.getGraphData(testSessionId);
|
|
220
|
+
expect(graphData.nodes.length).toBeGreaterThan(0);
|
|
221
|
+
expect(graphData.edges.length).toBeGreaterThan(0);
|
|
222
|
+
// Verify structure
|
|
223
|
+
expect(graphData.nodes[0]).toHaveProperty('id');
|
|
224
|
+
expect(graphData.nodes[0]).toHaveProperty('type');
|
|
225
|
+
expect(graphData.nodes[0]).toHaveProperty('name');
|
|
226
|
+
expect(graphData.edges[0]).toHaveProperty('source');
|
|
227
|
+
expect(graphData.edges[0]).toHaveProperty('target');
|
|
228
|
+
expect(graphData.edges[0]).toHaveProperty('predicate');
|
|
229
|
+
});
|
|
230
|
+
it('should generate timeline visualization data', () => {
|
|
231
|
+
const timeline = db
|
|
232
|
+
.prepare(`
|
|
233
|
+
SELECT
|
|
234
|
+
strftime('%Y-%m-%d %H:00', created_at) as hour,
|
|
235
|
+
COUNT(*) as events,
|
|
236
|
+
GROUP_CONCAT(DISTINCT category) as categories
|
|
237
|
+
FROM context_items
|
|
238
|
+
WHERE session_id = ?
|
|
239
|
+
GROUP BY hour
|
|
240
|
+
ORDER BY hour DESC
|
|
241
|
+
LIMIT 24
|
|
242
|
+
`)
|
|
243
|
+
.all(testSessionId);
|
|
244
|
+
expect(timeline.length).toBeGreaterThan(0);
|
|
245
|
+
expect(timeline[0]).toHaveProperty('hour');
|
|
246
|
+
expect(timeline[0]).toHaveProperty('events');
|
|
247
|
+
expect(timeline[0]).toHaveProperty('categories');
|
|
248
|
+
});
|
|
249
|
+
it('should generate heatmap visualization data', () => {
|
|
250
|
+
const heatmap = db
|
|
251
|
+
.prepare(`
|
|
252
|
+
SELECT
|
|
253
|
+
category,
|
|
254
|
+
priority,
|
|
255
|
+
COUNT(*) as count
|
|
256
|
+
FROM context_items
|
|
257
|
+
WHERE session_id = ?
|
|
258
|
+
GROUP BY category, priority
|
|
259
|
+
`)
|
|
260
|
+
.all(testSessionId);
|
|
261
|
+
expect(heatmap.length).toBeGreaterThan(0);
|
|
262
|
+
expect(heatmap[0]).toHaveProperty('category');
|
|
263
|
+
expect(heatmap[0]).toHaveProperty('priority');
|
|
264
|
+
expect(heatmap[0]).toHaveProperty('count');
|
|
265
|
+
// Verify we have data for different category/priority combinations
|
|
266
|
+
const categories = new Set(heatmap.map(h => h.category));
|
|
267
|
+
const priorities = new Set(heatmap.map(h => h.priority));
|
|
268
|
+
expect(categories.size).toBeGreaterThanOrEqual(2);
|
|
269
|
+
expect(priorities.size).toBeGreaterThanOrEqual(2);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
describe('Complex scenarios', () => {
|
|
273
|
+
it('should handle code analysis workflow', () => {
|
|
274
|
+
// Simulate analyzing a codebase
|
|
275
|
+
const codeContext = [
|
|
276
|
+
'The AuthController class handles authentication endpoints',
|
|
277
|
+
'It uses AuthService which implements IAuthService interface',
|
|
278
|
+
'AuthService calls UserRepository to fetch user data',
|
|
279
|
+
'The validateToken function uses jwt.verify from jsonwebtoken library',
|
|
280
|
+
'Files involved: auth.controller.ts, auth.service.ts, user.repository.ts',
|
|
281
|
+
];
|
|
282
|
+
// Analyze each piece of context
|
|
283
|
+
const allEntities = new Set();
|
|
284
|
+
const allRelations = [];
|
|
285
|
+
codeContext.forEach(text => {
|
|
286
|
+
const analysis = knowledgeGraph.analyzeContext(testSessionId, text);
|
|
287
|
+
analysis.entities.forEach(e => {
|
|
288
|
+
if (!knowledgeGraph.findEntity(testSessionId, e.name, e.type)) {
|
|
289
|
+
knowledgeGraph.createEntity(testSessionId, e.type, e.name);
|
|
290
|
+
allEntities.add(e.name);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
analysis.relations.forEach(r => {
|
|
294
|
+
const subject = knowledgeGraph.findEntity(testSessionId, r.subject);
|
|
295
|
+
const object = knowledgeGraph.findEntity(testSessionId, r.object);
|
|
296
|
+
if (subject && object) {
|
|
297
|
+
knowledgeGraph.createRelation(testSessionId, subject.id, r.predicate, object.id, r.confidence);
|
|
298
|
+
allRelations.push(r);
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
// Verify entities were extracted
|
|
303
|
+
expect(allEntities.size).toBeGreaterThan(5);
|
|
304
|
+
expect(allEntities).toContain('AuthController');
|
|
305
|
+
expect(allEntities).toContain('AuthService');
|
|
306
|
+
expect(allEntities).toContain('auth.controller.ts');
|
|
307
|
+
// Verify relationships
|
|
308
|
+
expect(allRelations.length).toBeGreaterThan(0);
|
|
309
|
+
// Test finding related entities
|
|
310
|
+
const authService = knowledgeGraph.findEntity(testSessionId, 'AuthService');
|
|
311
|
+
if (authService) {
|
|
312
|
+
const connected = knowledgeGraph.getConnectedEntities(authService.id, 2);
|
|
313
|
+
expect(connected.size).toBeGreaterThan(1);
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
it('should maintain graph consistency across operations', () => {
|
|
317
|
+
// Create initial graph
|
|
318
|
+
const module1 = knowledgeGraph.createEntity(testSessionId, 'module', 'CoreModule');
|
|
319
|
+
const module2 = knowledgeGraph.createEntity(testSessionId, 'module', 'UtilsModule');
|
|
320
|
+
const service = knowledgeGraph.createEntity(testSessionId, 'service', 'DataService');
|
|
321
|
+
knowledgeGraph.createRelation(testSessionId, module1.id, 'imports', module2.id);
|
|
322
|
+
knowledgeGraph.createRelation(testSessionId, module1.id, 'provides', service.id);
|
|
323
|
+
// Add observations
|
|
324
|
+
knowledgeGraph.addObservation(service.id, 'Handles data transformation');
|
|
325
|
+
// Verify graph integrity
|
|
326
|
+
const graphData = knowledgeGraph.getGraphData(testSessionId);
|
|
327
|
+
expect(graphData.nodes).toHaveLength(3);
|
|
328
|
+
expect(graphData.edges).toHaveLength(2);
|
|
329
|
+
// Test pruning doesn't remove entities with relations
|
|
330
|
+
const pruned = knowledgeGraph.pruneOrphanedEntities(testSessionId);
|
|
331
|
+
expect(pruned).toBe(0);
|
|
332
|
+
// All entities should still exist
|
|
333
|
+
expect(knowledgeGraph.findEntity(testSessionId, 'CoreModule')).toBeDefined();
|
|
334
|
+
expect(knowledgeGraph.findEntity(testSessionId, 'UtilsModule')).toBeDefined();
|
|
335
|
+
expect(knowledgeGraph.findEntity(testSessionId, 'DataService')).toBeDefined();
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
});
|