@henrychong-ai/mcp-neo4j-knowledge-graph 2.0.3 → 2.1.1

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.
Files changed (36) hide show
  1. package/SETUP_AUTOMATION.md +2 -2
  2. package/dist/KnowledgeGraphManager.js +10 -10
  3. package/dist/KnowledgeGraphManager.js.map +1 -1
  4. package/dist/__test-utils__/fixtures.js +1 -1
  5. package/dist/__test-utils__/fixtures.js.map +1 -1
  6. package/dist/cli/generate-embeddings.js +3 -3
  7. package/dist/cli/generate-embeddings.js.map +1 -1
  8. package/dist/cli/neo4j-setup.js +2 -2
  9. package/dist/cli/neo4j-setup.js.map +1 -1
  10. package/dist/embeddings/DefaultEmbeddingService.js +1 -1
  11. package/dist/embeddings/DefaultEmbeddingService.js.map +1 -1
  12. package/dist/embeddings/EmbeddingJobManager.js +2 -2
  13. package/dist/embeddings/EmbeddingJobManager.js.map +1 -1
  14. package/dist/embeddings/OpenAIEmbeddingService.js +1 -1
  15. package/dist/embeddings/OpenAIEmbeddingService.js.map +1 -1
  16. package/dist/index.js +2 -2
  17. package/dist/index.js.map +1 -1
  18. package/dist/retrieval/scorers/ConnectionStrengthScorer.js +3 -3
  19. package/dist/retrieval/scorers/ConnectionStrengthScorer.js.map +1 -1
  20. package/dist/retrieval/scorers/GraphTraversalScorer.js +5 -5
  21. package/dist/retrieval/scorers/GraphTraversalScorer.js.map +1 -1
  22. package/dist/server/handlers/callToolHandler.js +421 -429
  23. package/dist/server/handlers/callToolHandler.js.map +1 -1
  24. package/dist/server/setup.js +2 -14
  25. package/dist/server/setup.js.map +1 -1
  26. package/dist/storage/SearchResultCache.js +1 -1
  27. package/dist/storage/SearchResultCache.js.map +1 -1
  28. package/dist/storage/StorageProviderFactory.js +1 -1
  29. package/dist/storage/StorageProviderFactory.js.map +1 -1
  30. package/dist/storage/neo4j/Neo4jSchemaManager.js +4 -4
  31. package/dist/storage/neo4j/Neo4jSchemaManager.js.map +1 -1
  32. package/dist/storage/neo4j/Neo4jStorageProvider.js +39 -39
  33. package/dist/storage/neo4j/Neo4jStorageProvider.js.map +1 -1
  34. package/dist/storage/neo4j/Neo4jVectorStore.js +3 -3
  35. package/dist/storage/neo4j/Neo4jVectorStore.js.map +1 -1
  36. package/package.json +12 -24
@@ -25,490 +25,482 @@ knowledgeGraphManager) {
25
25
  if (!args) {
26
26
  throw new Error(`No arguments provided for tool: ${name}`);
27
27
  }
28
- try {
29
- switch (name) {
30
- case 'create_entities': {
31
- return await toolHandlers.handleCreateEntities(args, knowledgeGraphManager);
32
- }
33
- case 'read_graph': {
34
- return await toolHandlers.handleReadGraph(args, knowledgeGraphManager);
35
- }
36
- case 'create_relations': {
37
- return await toolHandlers.handleCreateRelations(args, knowledgeGraphManager);
38
- }
39
- case 'add_observations': {
40
- return await toolHandlers.handleAddObservations(args, knowledgeGraphManager);
41
- }
42
- case 'delete_entities': {
43
- return await toolHandlers.handleDeleteEntities(args, knowledgeGraphManager);
44
- }
45
- case 'delete_observations': {
46
- await knowledgeGraphManager.deleteObservations(args.deletions);
47
- return { content: [{ type: 'text', text: 'Observations deleted successfully' }] };
48
- }
49
- case 'delete_relations': {
50
- await knowledgeGraphManager.deleteRelations(args.relations);
51
- return { content: [{ type: 'text', text: 'Relations deleted successfully' }] };
52
- }
53
- case 'get_relation': {
54
- const relation = await knowledgeGraphManager.getRelation(args.from, args.to, args.relationType);
55
- if (!relation) {
56
- return {
57
- content: [
58
- {
59
- type: 'text',
60
- text: `Relation not found: ${args.from} -> ${args.relationType} -> ${args.to}`,
61
- },
62
- ],
63
- };
64
- }
65
- return { content: [{ type: 'text', text: JSON.stringify(relation, null, 2) }] };
66
- }
67
- case 'update_relation': {
68
- await knowledgeGraphManager.updateRelation(args.relation);
69
- return { content: [{ type: 'text', text: 'Relation updated successfully' }] };
70
- }
71
- case 'search_nodes': {
28
+ switch (name) {
29
+ case 'create_entities': {
30
+ return await toolHandlers.handleCreateEntities(args, knowledgeGraphManager);
31
+ }
32
+ case 'read_graph': {
33
+ return await toolHandlers.handleReadGraph(args, knowledgeGraphManager);
34
+ }
35
+ case 'create_relations': {
36
+ return await toolHandlers.handleCreateRelations(args, knowledgeGraphManager);
37
+ }
38
+ case 'add_observations': {
39
+ return await toolHandlers.handleAddObservations(args, knowledgeGraphManager);
40
+ }
41
+ case 'delete_entities': {
42
+ return await toolHandlers.handleDeleteEntities(args, knowledgeGraphManager);
43
+ }
44
+ case 'delete_observations': {
45
+ await knowledgeGraphManager.deleteObservations(args.deletions);
46
+ return { content: [{ type: 'text', text: 'Observations deleted successfully' }] };
47
+ }
48
+ case 'delete_relations': {
49
+ await knowledgeGraphManager.deleteRelations(args.relations);
50
+ return { content: [{ type: 'text', text: 'Relations deleted successfully' }] };
51
+ }
52
+ case 'get_relation': {
53
+ const relation = await knowledgeGraphManager.getRelation(args.from, args.to, args.relationType);
54
+ if (!relation) {
72
55
  return {
73
56
  content: [
74
57
  {
75
58
  type: 'text',
76
- text: JSON.stringify(await knowledgeGraphManager.searchNodes(args.query, {
77
- domain: args.domain,
78
- includeNullDomain: args.include_null_domain,
79
- }), null, 2),
59
+ text: `Relation not found: ${args.from} -> ${args.relationType} -> ${args.to}`,
80
60
  },
81
61
  ],
82
62
  };
83
63
  }
84
- case 'open_nodes': {
64
+ return { content: [{ type: 'text', text: JSON.stringify(relation, null, 2) }] };
65
+ }
66
+ case 'update_relation': {
67
+ await knowledgeGraphManager.updateRelation(args.relation);
68
+ return { content: [{ type: 'text', text: 'Relation updated successfully' }] };
69
+ }
70
+ case 'search_nodes': {
71
+ return {
72
+ content: [
73
+ {
74
+ type: 'text',
75
+ text: JSON.stringify(await knowledgeGraphManager.searchNodes(args.query, {
76
+ domain: args.domain,
77
+ includeNullDomain: args.include_null_domain,
78
+ }), null, 2),
79
+ },
80
+ ],
81
+ };
82
+ }
83
+ case 'open_nodes': {
84
+ return {
85
+ content: [
86
+ {
87
+ type: 'text',
88
+ text: JSON.stringify(await knowledgeGraphManager.openNodes(args.names), null, 2),
89
+ },
90
+ ],
91
+ };
92
+ }
93
+ case 'get_entity_history': {
94
+ try {
95
+ const history = await knowledgeGraphManager.getEntityHistory(args.entityName);
96
+ return { content: [{ type: 'text', text: JSON.stringify(history, null, 2) }] };
97
+ }
98
+ catch (error) {
99
+ const errorMessage = error instanceof Error ? error.message : String(error);
85
100
  return {
86
- content: [
87
- {
88
- type: 'text',
89
- text: JSON.stringify(await knowledgeGraphManager.openNodes(args.names), null, 2),
90
- },
91
- ],
101
+ content: [{ type: 'text', text: `Error retrieving entity history: ${errorMessage}` }],
92
102
  };
93
103
  }
94
- case 'get_entity_history': {
95
- try {
96
- const history = await knowledgeGraphManager.getEntityHistory(args.entityName);
97
- return { content: [{ type: 'text', text: JSON.stringify(history, null, 2) }] };
98
- }
99
- catch (error) {
100
- const errorMessage = error instanceof Error ? error.message : String(error);
101
- return {
102
- content: [{ type: 'text', text: `Error retrieving entity history: ${errorMessage}` }],
103
- };
104
- }
104
+ }
105
+ case 'get_relation_history': {
106
+ try {
107
+ const history = await knowledgeGraphManager.getRelationHistory(args.from, args.to, args.relationType);
108
+ return { content: [{ type: 'text', text: JSON.stringify(history, null, 2) }] };
109
+ }
110
+ catch (error) {
111
+ const errorMessage = error instanceof Error ? error.message : String(error);
112
+ return {
113
+ content: [{ type: 'text', text: `Error retrieving relation history: ${errorMessage}` }],
114
+ };
105
115
  }
106
- case 'get_relation_history': {
107
- try {
108
- const history = await knowledgeGraphManager.getRelationHistory(args.from, args.to, args.relationType);
109
- return { content: [{ type: 'text', text: JSON.stringify(history, null, 2) }] };
116
+ }
117
+ case 'get_graph_at_time': {
118
+ try {
119
+ const graph = await knowledgeGraphManager.getGraphAtTime(args.timestamp);
120
+ return { content: [{ type: 'text', text: JSON.stringify(graph, null, 2) }] };
121
+ }
122
+ catch (error) {
123
+ const errorMessage = error instanceof Error ? error.message : String(error);
124
+ return {
125
+ content: [{ type: 'text', text: `Error retrieving graph at time: ${errorMessage}` }],
126
+ };
127
+ }
128
+ }
129
+ case 'get_decayed_graph': {
130
+ try {
131
+ // Extract optional parameters if provided by client
132
+ const options = {};
133
+ if (args.reference_time) {
134
+ options.referenceTime = Number(args.reference_time);
110
135
  }
111
- catch (error) {
112
- const errorMessage = error instanceof Error ? error.message : String(error);
113
- return {
114
- content: [{ type: 'text', text: `Error retrieving relation history: ${errorMessage}` }],
115
- };
136
+ if (args.decay_factor) {
137
+ options.decayFactor = Number(args.decay_factor);
116
138
  }
139
+ // Pass options to getDecayedGraph if any are provided
140
+ const graph = Object.keys(options).length > 0
141
+ ? await knowledgeGraphManager.getDecayedGraph(options)
142
+ : await knowledgeGraphManager.getDecayedGraph();
143
+ return { content: [{ type: 'text', text: JSON.stringify(graph, null, 2) }] };
144
+ }
145
+ catch (error) {
146
+ const errorMessage = error instanceof Error ? error.message : String(error);
147
+ return {
148
+ content: [{ type: 'text', text: `Error retrieving decayed graph: ${errorMessage}` }],
149
+ };
150
+ }
151
+ }
152
+ case 'force_generate_embedding': {
153
+ // Validate arguments
154
+ if (!args.entity_name) {
155
+ throw new Error('Missing required parameter: entity_name');
117
156
  }
118
- case 'get_graph_at_time': {
119
- try {
120
- const graph = await knowledgeGraphManager.getGraphAtTime(args.timestamp);
121
- return { content: [{ type: 'text', text: JSON.stringify(graph, null, 2) }] };
157
+ try {
158
+ // First determine if the input looks like a UUID
159
+ const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
160
+ const isUUID = uuidPattern.test(String(args.entity_name));
161
+ // Try to get all entities first to locate the correct one
162
+ const allEntities = await knowledgeGraphManager.openNodes([]);
163
+ let entity = null;
164
+ if (allEntities?.entities && allEntities.entities.length > 0) {
165
+ // Try different methods to find the entity
166
+ // 1. Direct match by name
167
+ entity = allEntities.entities.find((e) => e.name === args.entity_name);
168
+ // 2. If not found and input is UUID, try matching by ID
169
+ if (!entity && isUUID) {
170
+ entity = allEntities.entities.find((e) => 'id' in e && e.id === args.entity_name);
171
+ }
122
172
  }
123
- catch (error) {
124
- const errorMessage = error instanceof Error ? error.message : String(error);
125
- return {
126
- content: [{ type: 'text', text: `Error retrieving graph at time: ${errorMessage}` }],
127
- };
173
+ // If still not found, try explicit lookup by name
174
+ if (!entity) {
175
+ const openedEntities = await knowledgeGraphManager.openNodes([String(args.entity_name)]);
176
+ if (openedEntities?.entities && openedEntities.entities.length > 0) {
177
+ entity = openedEntities.entities[0];
178
+ }
128
179
  }
129
- }
130
- case 'get_decayed_graph': {
131
- try {
132
- // Extract optional parameters if provided by client
133
- const options = {};
134
- if (args.reference_time) {
135
- options.referenceTime = Number(args.reference_time);
180
+ // If still not found, check if we can query by ID through the storage provider
181
+ if (!entity &&
182
+ isUUID &&
183
+ knowledgeGraphManager.storageProvider &&
184
+ typeof knowledgeGraphManager.storageProvider.getEntityById === 'function') {
185
+ try {
186
+ entity = await knowledgeGraphManager.storageProvider.getEntityById(args.entity_name);
136
187
  }
137
- if (args.decay_factor) {
138
- options.decayFactor = Number(args.decay_factor);
188
+ catch {
189
+ // Ignore lookup errors, we'll throw entity not found below
139
190
  }
140
- // Pass options to getDecayedGraph if any are provided
141
- const graph = Object.keys(options).length > 0
142
- ? await knowledgeGraphManager.getDecayedGraph(options)
143
- : await knowledgeGraphManager.getDecayedGraph();
144
- return { content: [{ type: 'text', text: JSON.stringify(graph, null, 2) }] };
145
191
  }
146
- catch (error) {
147
- const errorMessage = error instanceof Error ? error.message : String(error);
148
- return {
149
- content: [{ type: 'text', text: `Error retrieving decayed graph: ${errorMessage}` }],
150
- };
192
+ // Final check
193
+ if (!entity) {
194
+ throw new Error(`Entity not found: ${args.entity_name}`);
151
195
  }
152
- }
153
- case 'force_generate_embedding': {
154
- // Validate arguments
155
- if (!args.entity_name) {
156
- throw new Error('Missing required parameter: entity_name');
196
+ // Check if embedding service and job manager are available
197
+ if (!knowledgeGraphManager.embeddingJobManager) {
198
+ throw new Error('EmbeddingJobManager not initialized');
157
199
  }
158
- try {
159
- // First determine if the input looks like a UUID
160
- const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
161
- const isUUID = uuidPattern.test(String(args.entity_name));
162
- // Try to get all entities first to locate the correct one
163
- const allEntities = await knowledgeGraphManager.openNodes([]);
164
- let entity = null;
165
- if (allEntities?.entities && allEntities.entities.length > 0) {
166
- // Try different methods to find the entity
167
- // 1. Direct match by name
168
- entity = allEntities.entities.find((e) => e.name === args.entity_name);
169
- // 2. If not found and input is UUID, try matching by ID
170
- if (!entity && isUUID) {
171
- entity = allEntities.entities.find((e) => 'id' in e && e.id === args.entity_name);
172
- }
173
- }
174
- // If still not found, try explicit lookup by name
175
- if (!entity) {
176
- const openedEntities = await knowledgeGraphManager.openNodes([
177
- String(args.entity_name),
178
- ]);
179
- if (openedEntities?.entities && openedEntities.entities.length > 0) {
180
- entity = openedEntities.entities[0];
181
- }
182
- }
183
- // If still not found, check if we can query by ID through the storage provider
184
- if (!entity &&
185
- isUUID &&
186
- knowledgeGraphManager.storageProvider &&
187
- typeof knowledgeGraphManager.storageProvider.getEntityById === 'function') {
188
- try {
189
- entity = await knowledgeGraphManager.storageProvider.getEntityById(args.entity_name);
190
- }
191
- catch {
192
- // Ignore lookup errors, we'll throw entity not found below
193
- }
194
- }
195
- // Final check
196
- if (!entity) {
197
- throw new Error(`Entity not found: ${args.entity_name}`);
200
+ // Directly get the text for the entity
201
+ const embeddingText = knowledgeGraphManager.embeddingJobManager._prepareEntityText(entity);
202
+ // Generate embedding directly
203
+ const embeddingService = knowledgeGraphManager.embeddingJobManager.embeddingService;
204
+ if (!embeddingService) {
205
+ throw new Error('Embedding service not available');
206
+ }
207
+ const vector = await embeddingService.generateEmbedding(embeddingText);
208
+ // Store embedding directly
209
+ const embedding = {
210
+ vector,
211
+ model: embeddingService.getModelInfo().name,
212
+ lastUpdated: Date.now(),
213
+ };
214
+ // Store the embedding with both name and ID for redundancy
215
+ await knowledgeGraphManager.storageProvider.storeEntityVector(entity.name, embedding);
216
+ const entityId = entity.id;
217
+ if (entityId && typeof entityId === 'string') {
218
+ try {
219
+ await knowledgeGraphManager.storageProvider.storeEntityVector(entityId, embedding);
198
220
  }
199
- // Check if embedding service and job manager are available
200
- if (!knowledgeGraphManager.embeddingJobManager) {
201
- throw new Error('EmbeddingJobManager not initialized');
221
+ catch {
222
+ // Ignore ID storage errors if name storage succeeded
202
223
  }
203
- // Directly get the text for the entity
204
- const embeddingText = knowledgeGraphManager.embeddingJobManager._prepareEntityText(entity);
205
- // Generate embedding directly
206
- const embeddingService = knowledgeGraphManager.embeddingJobManager.embeddingService;
207
- if (!embeddingService) {
208
- throw new Error('Embedding service not available');
224
+ }
225
+ return {
226
+ content: [
227
+ {
228
+ type: 'text',
229
+ text: JSON.stringify({
230
+ success: true,
231
+ entity: entity.name,
232
+ entity_id: entity.id,
233
+ vector_length: vector.length,
234
+ model: embeddingService.getModelInfo().name,
235
+ }, null, 2),
236
+ },
237
+ ],
238
+ };
239
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
240
+ }
241
+ catch (error) {
242
+ return {
243
+ content: [{ type: 'text', text: `Failed to generate embedding: ${error.message}` }],
244
+ };
245
+ }
246
+ }
247
+ case 'semantic_search': {
248
+ try {
249
+ // Extract hybrid search configuration if provided
250
+ const hybridConfigRaw = args.hybrid_config;
251
+ const hybridConfig = hybridConfigRaw
252
+ ? {
253
+ vectorWeight: hybridConfigRaw.vector_weight,
254
+ graphWeight: hybridConfigRaw.graph_weight,
255
+ temporalWeight: hybridConfigRaw.temporal_weight,
256
+ connectionWeight: hybridConfigRaw.connection_weight,
257
+ enableScoreDebug: hybridConfigRaw.enable_score_debug,
258
+ referenceTime: hybridConfigRaw.reference_time,
259
+ temporalHalfLife: hybridConfigRaw.temporal_half_life,
209
260
  }
210
- const vector = await embeddingService.generateEmbedding(embeddingText);
211
- // Store embedding directly
212
- const embedding = {
213
- vector,
214
- model: embeddingService.getModelInfo().name,
215
- lastUpdated: Date.now(),
216
- };
217
- // Store the embedding with both name and ID for redundancy
218
- await knowledgeGraphManager.storageProvider.storeEntityVector(entity.name, embedding);
219
- const entityId = entity.id;
220
- if (entityId && typeof entityId === 'string') {
221
- try {
222
- await knowledgeGraphManager.storageProvider.storeEntityVector(entityId, embedding);
223
- }
224
- catch {
225
- // Ignore ID storage errors if name storage succeeded
226
- }
261
+ : undefined;
262
+ // Extract search options from args
263
+ const searchOptions = {
264
+ limit: args.limit || 10,
265
+ minSimilarity: args.min_similarity || 0.6,
266
+ entityTypes: args.entity_types || [],
267
+ hybridSearch: args.hybrid_search === undefined ? true : args.hybrid_search,
268
+ semanticWeight: args.semantic_weight || 0.6,
269
+ semanticSearch: true,
270
+ hybridConfig,
271
+ enableHybridRetrieval: args.enable_hybrid_retrieval !== false,
272
+ domain: args.domain,
273
+ includeNullDomain: args.include_null_domain,
274
+ };
275
+ // Call the search method with semantic search options
276
+ const results = await knowledgeGraphManager.search(String(args.query), searchOptions);
277
+ return { content: [{ type: 'text', text: JSON.stringify(results, null, 2) }] };
278
+ }
279
+ catch (error) {
280
+ const errorMessage = error instanceof Error ? error.message : String(error);
281
+ return {
282
+ content: [{ type: 'text', text: `Error performing semantic search: ${errorMessage}` }],
283
+ };
284
+ }
285
+ }
286
+ case 'get_entity_embedding': {
287
+ try {
288
+ // Check if entity exists
289
+ const entity = await knowledgeGraphManager.openNodes([String(args.entity_name)]);
290
+ if (!entity.entities || entity.entities.length === 0) {
291
+ return { content: [{ type: 'text', text: `Entity not found: ${args.entity_name}` }] };
292
+ }
293
+ // Access the embedding using appropriate interface
294
+ if (knowledgeGraphManager.storageProvider &&
295
+ typeof knowledgeGraphManager.storageProvider
296
+ .getEntityEmbedding === 'function') {
297
+ const embedding = await knowledgeGraphManager.storageProvider.getEntityEmbedding(String(args.entity_name));
298
+ if (!embedding) {
299
+ return {
300
+ content: [
301
+ { type: 'text', text: `No embedding found for entity: ${args.entity_name}` },
302
+ ],
303
+ };
227
304
  }
228
305
  return {
229
306
  content: [
230
307
  {
231
308
  type: 'text',
232
309
  text: JSON.stringify({
233
- success: true,
234
- entity: entity.name,
235
- entity_id: entity.id,
236
- vector_length: vector.length,
237
- model: embeddingService.getModelInfo().name,
310
+ entityName: args.entity_name,
311
+ embedding: embedding.vector,
312
+ model: embedding.model || 'unknown',
313
+ dimensions: embedding.vector ? embedding.vector.length : 0,
314
+ lastUpdated: embedding.lastUpdated || Date.now(),
238
315
  }, null, 2),
239
316
  },
240
317
  ],
241
318
  };
242
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
243
319
  }
244
- catch (error) {
320
+ else {
245
321
  return {
246
- content: [{ type: 'text', text: `Failed to generate embedding: ${error.message}` }],
322
+ content: [
323
+ {
324
+ type: 'text',
325
+ text: `Embedding retrieval not supported by this storage provider`,
326
+ },
327
+ ],
247
328
  };
248
329
  }
249
330
  }
250
- case 'semantic_search': {
251
- try {
252
- // Extract hybrid search configuration if provided
253
- const hybridConfigRaw = args.hybrid_config;
254
- const hybridConfig = hybridConfigRaw
255
- ? {
256
- vectorWeight: hybridConfigRaw.vector_weight,
257
- graphWeight: hybridConfigRaw.graph_weight,
258
- temporalWeight: hybridConfigRaw.temporal_weight,
259
- connectionWeight: hybridConfigRaw.connection_weight,
260
- enableScoreDebug: hybridConfigRaw.enable_score_debug,
261
- referenceTime: hybridConfigRaw.reference_time,
262
- temporalHalfLife: hybridConfigRaw.temporal_half_life,
263
- }
264
- : undefined;
265
- // Extract search options from args
266
- const searchOptions = {
267
- limit: args.limit || 10,
268
- minSimilarity: args.min_similarity || 0.6,
269
- entityTypes: args.entity_types || [],
270
- hybridSearch: args.hybrid_search === undefined ? true : args.hybrid_search,
271
- semanticWeight: args.semantic_weight || 0.6,
272
- semanticSearch: true,
273
- hybridConfig,
274
- enableHybridRetrieval: args.enable_hybrid_retrieval !== false,
275
- domain: args.domain,
276
- includeNullDomain: args.include_null_domain,
277
- };
278
- // Call the search method with semantic search options
279
- const results = await knowledgeGraphManager.search(String(args.query), searchOptions);
280
- return { content: [{ type: 'text', text: JSON.stringify(results, null, 2) }] };
281
- }
282
- catch (error) {
283
- const errorMessage = error instanceof Error ? error.message : String(error);
284
- return {
285
- content: [{ type: 'text', text: `Error performing semantic search: ${errorMessage}` }],
286
- };
287
- }
331
+ catch (error) {
332
+ const errorMessage = error instanceof Error ? error.message : String(error);
333
+ return {
334
+ content: [{ type: 'text', text: `Error retrieving entity embedding: ${errorMessage}` }],
335
+ };
288
336
  }
289
- case 'get_entity_embedding': {
290
- try {
291
- // Check if entity exists
292
- const entity = await knowledgeGraphManager.openNodes([String(args.entity_name)]);
293
- if (!entity.entities || entity.entities.length === 0) {
294
- return { content: [{ type: 'text', text: `Entity not found: ${args.entity_name}` }] };
295
- }
296
- // Access the embedding using appropriate interface
297
- if (knowledgeGraphManager.storageProvider &&
298
- typeof knowledgeGraphManager.storageProvider
299
- .getEntityEmbedding === 'function') {
300
- const embedding = await knowledgeGraphManager.storageProvider.getEntityEmbedding(String(args.entity_name));
301
- if (!embedding) {
302
- return {
303
- content: [
304
- { type: 'text', text: `No embedding found for entity: ${args.entity_name}` },
305
- ],
306
- };
337
+ }
338
+ case 'debug_embedding_config': {
339
+ // Diagnostic tool to check embedding configuration
340
+ try {
341
+ // Check for OpenAI API key
342
+ const hasOpenAIKey = !!process.env.OPENAI_API_KEY;
343
+ const embeddingModel = process.env.OPENAI_EMBEDDING_MODEL || 'text-embedding-3-small';
344
+ // Check if embedding job manager is initialized
345
+ const hasEmbeddingJobManager = !!knowledgeGraphManager.embeddingJobManager;
346
+ // Get storage provider info
347
+ const storageType = process.env.MEMORY_STORAGE_TYPE || 'neo4j';
348
+ const storageProvider = knowledgeGraphManager.storageProvider;
349
+ // Get Neo4j specific configuration
350
+ const neo4jInfo = {
351
+ uri: process.env.NEO4J_URI || 'default',
352
+ username: process.env.NEO4J_USERNAME ? 'configured' : 'not configured',
353
+ database: process.env.NEO4J_DATABASE || 'neo4j',
354
+ vectorIndex: process.env.NEO4J_VECTOR_INDEX || 'entity_embeddings',
355
+ vectorDimensions: process.env.NEO4J_VECTOR_DIMENSIONS || '1536',
356
+ similarityFunction: process.env.NEO4J_SIMILARITY_FUNCTION || 'cosine',
357
+ connectionStatus: 'unknown',
358
+ };
359
+ // Check if Neo4j connection manager is available
360
+ if (storageProvider && typeof storageProvider.getConnectionManager === 'function') {
361
+ try {
362
+ const connectionManager = storageProvider.getConnectionManager();
363
+ if (connectionManager) {
364
+ neo4jInfo.connectionStatus = 'available';
365
+ // Check if vector store is initialized
366
+ neo4jInfo.vectorStoreStatus = storageProvider.vectorStore
367
+ ? 'available'
368
+ : 'not initialized';
307
369
  }
308
- return {
309
- content: [
310
- {
311
- type: 'text',
312
- text: JSON.stringify({
313
- entityName: args.entity_name,
314
- embedding: embedding.vector,
315
- model: embedding.model || 'unknown',
316
- dimensions: embedding.vector ? embedding.vector.length : 0,
317
- lastUpdated: embedding.lastUpdated || Date.now(),
318
- }, null, 2),
319
- },
320
- ],
321
- };
322
370
  }
323
- else {
324
- return {
325
- content: [
326
- {
327
- type: 'text',
328
- text: `Embedding retrieval not supported by this storage provider`,
329
- },
330
- ],
331
- };
371
+ catch (error) {
372
+ const errorMessage = error instanceof Error ? error.message : String(error);
373
+ neo4jInfo.connectionStatus = `error: ${errorMessage}`;
332
374
  }
333
375
  }
334
- catch (error) {
335
- const errorMessage = error instanceof Error ? error.message : String(error);
336
- return {
337
- content: [{ type: 'text', text: `Error retrieving entity embedding: ${errorMessage}` }],
338
- };
339
- }
340
- }
341
- case 'debug_embedding_config': {
342
- // Diagnostic tool to check embedding configuration
343
- try {
344
- // Check for OpenAI API key
345
- const hasOpenAIKey = !!process.env.OPENAI_API_KEY;
346
- const embeddingModel = process.env.OPENAI_EMBEDDING_MODEL || 'text-embedding-3-small';
347
- // Check if embedding job manager is initialized
348
- const hasEmbeddingJobManager = !!knowledgeGraphManager.embeddingJobManager;
349
- // Get storage provider info
350
- const storageType = process.env.MEMORY_STORAGE_TYPE || 'neo4j';
351
- const storageProvider = knowledgeGraphManager.storageProvider;
352
- // Get Neo4j specific configuration
353
- const neo4jInfo = {
354
- uri: process.env.NEO4J_URI || 'default',
355
- username: process.env.NEO4J_USERNAME ? 'configured' : 'not configured',
356
- database: process.env.NEO4J_DATABASE || 'neo4j',
357
- vectorIndex: process.env.NEO4J_VECTOR_INDEX || 'entity_embeddings',
358
- vectorDimensions: process.env.NEO4J_VECTOR_DIMENSIONS || '1536',
359
- similarityFunction: process.env.NEO4J_SIMILARITY_FUNCTION || 'cosine',
360
- connectionStatus: 'unknown',
361
- };
362
- // Check if Neo4j connection manager is available
363
- if (storageProvider && typeof storageProvider.getConnectionManager === 'function') {
364
- try {
365
- const connectionManager = storageProvider.getConnectionManager();
366
- if (connectionManager) {
367
- neo4jInfo.connectionStatus = 'available';
368
- // Check if vector store is initialized
369
- neo4jInfo.vectorStoreStatus = storageProvider.vectorStore
370
- ? 'available'
371
- : 'not initialized';
372
- }
373
- }
374
- catch (error) {
375
- const errorMessage = error instanceof Error ? error.message : String(error);
376
- neo4jInfo.connectionStatus = `error: ${errorMessage}`;
377
- }
376
+ // Count entities with embeddings via Neo4j vector store
377
+ let entitiesWithEmbeddings = 0;
378
+ if (storageProvider?.countEntitiesWithEmbeddings) {
379
+ try {
380
+ entitiesWithEmbeddings = await storageProvider.countEntitiesWithEmbeddings();
378
381
  }
379
- // Count entities with embeddings via Neo4j vector store
380
- let entitiesWithEmbeddings = 0;
381
- if (storageProvider?.countEntitiesWithEmbeddings) {
382
- try {
383
- entitiesWithEmbeddings = await storageProvider.countEntitiesWithEmbeddings();
384
- }
385
- catch (error) {
386
- logger.error('Error checking embeddings count', error);
387
- }
388
- }
389
- // Get embedding service information
390
- let embeddingServiceInfo = null;
391
- if (hasEmbeddingJobManager &&
392
- knowledgeGraphManager.embeddingJobManager.embeddingService) {
393
- try {
394
- embeddingServiceInfo = knowledgeGraphManager.embeddingJobManager.embeddingService.getModelInfo();
395
- }
396
- catch (error) {
397
- const errorMessage = error instanceof Error ? error.message : String(error);
398
- logger.error(`Error getting embedding service info: ${errorMessage}`);
399
- }
382
+ catch (error) {
383
+ logger.error('Error checking embeddings count', error);
400
384
  }
401
- // Get embedding service provider info if available
402
- let embeddingProviderInfo = null;
403
- if (storageProvider?.embeddingService) {
404
- try {
405
- embeddingProviderInfo = storageProvider.embeddingService.getProviderInfo();
406
- }
407
- catch (error) {
408
- const errorMessage = error instanceof Error ? error.message : String(error);
409
- logger.error(`Error getting embedding provider info: ${errorMessage}`);
410
- }
385
+ }
386
+ // Get embedding service information
387
+ let embeddingServiceInfo = null;
388
+ if (hasEmbeddingJobManager && knowledgeGraphManager.embeddingJobManager.embeddingService) {
389
+ try {
390
+ embeddingServiceInfo = knowledgeGraphManager.embeddingJobManager.embeddingService.getModelInfo();
411
391
  }
412
- // Check pending embedding jobs if available
413
- let pendingJobs = 0;
414
- if (hasEmbeddingJobManager && knowledgeGraphManager.embeddingJobManager.getPendingJobs) {
415
- try {
416
- pendingJobs = knowledgeGraphManager.embeddingJobManager.getPendingJobs().length;
417
- }
418
- catch (error) {
419
- const errorMessage = error instanceof Error ? error.message : String(error);
420
- logger.error(`Error getting pending jobs: ${errorMessage}`);
421
- }
392
+ catch (error) {
393
+ const errorMessage = error instanceof Error ? error.message : String(error);
394
+ logger.error(`Error getting embedding service info: ${errorMessage}`);
422
395
  }
423
- // Return diagnostic information with proper formatting
424
- const diagnosticInfo = {
425
- storage_type: storageType,
426
- openai_api_key_present: hasOpenAIKey,
427
- embedding_model: embeddingModel,
428
- embedding_job_manager_initialized: hasEmbeddingJobManager,
429
- embedding_service_initialized: !!embeddingProviderInfo,
430
- embedding_service_info: embeddingServiceInfo,
431
- embedding_provider_info: embeddingProviderInfo,
432
- neo4j_config: neo4jInfo,
433
- entities_with_embeddings: entitiesWithEmbeddings,
434
- pending_embedding_jobs: pendingJobs,
435
- environment_variables: {
436
- DEBUG: process.env.DEBUG === 'true',
437
- NODE_ENV: process.env.NODE_ENV,
438
- MEMORY_STORAGE_TYPE: process.env.MEMORY_STORAGE_TYPE || 'neo4j',
439
- },
440
- };
441
- return {
442
- content: [
443
- {
444
- type: 'text',
445
- text: JSON.stringify(diagnosticInfo, null, 2),
446
- },
447
- ],
448
- };
449
396
  }
450
- catch (error) {
451
- const errorMessage = error instanceof Error ? error.message : String(error);
452
- const errorStack = error instanceof Error ? error.stack : undefined;
453
- logger.error(`Error in debug_embedding_config: ${errorMessage}`);
454
- return {
455
- content: [
456
- {
457
- type: 'text',
458
- text: JSON.stringify({
459
- error: errorMessage,
460
- stack: errorStack,
461
- }, null, 2),
462
- },
463
- ],
464
- };
397
+ // Get embedding service provider info if available
398
+ let embeddingProviderInfo = null;
399
+ if (storageProvider?.embeddingService) {
400
+ try {
401
+ embeddingProviderInfo = storageProvider.embeddingService.getProviderInfo();
402
+ }
403
+ catch (error) {
404
+ const errorMessage = error instanceof Error ? error.message : String(error);
405
+ logger.error(`Error getting embedding provider info: ${errorMessage}`);
406
+ }
465
407
  }
466
- }
467
- case 'diagnose_vector_search': {
468
- return knowledgeGraphManager.storageProvider &&
469
- typeof knowledgeGraphManager.storageProvider
470
- .diagnoseVectorSearch === 'function'
471
- ? {
472
- content: [
473
- {
474
- type: 'text',
475
- text: JSON.stringify(await knowledgeGraphManager.storageProvider.diagnoseVectorSearch()),
476
- },
477
- ],
408
+ // Check pending embedding jobs if available
409
+ let pendingJobs = 0;
410
+ if (hasEmbeddingJobManager && knowledgeGraphManager.embeddingJobManager.getPendingJobs) {
411
+ try {
412
+ pendingJobs = knowledgeGraphManager.embeddingJobManager.getPendingJobs().length;
478
413
  }
479
- : {
480
- content: [
481
- {
482
- type: 'text',
483
- text: JSON.stringify({
484
- error: 'Diagnostic method not available',
485
- storageType: knowledgeGraphManager.storageProvider
486
- ? knowledgeGraphManager.storageProvider.constructor.name
487
- : 'unknown',
488
- }, null, 2),
489
- },
490
- ],
491
- };
492
- }
493
- case 'create_entities_batch': {
494
- return await toolHandlers.handleCreateEntitiesBatch(args, knowledgeGraphManager);
495
- }
496
- case 'create_relations_batch': {
497
- return await toolHandlers.handleCreateRelationsBatch(args, knowledgeGraphManager);
498
- }
499
- case 'add_observations_batch': {
500
- return await toolHandlers.handleAddObservationsBatch(args, knowledgeGraphManager);
501
- }
502
- case 'update_entities_batch': {
503
- return await toolHandlers.handleUpdateEntitiesBatch(args, knowledgeGraphManager);
414
+ catch (error) {
415
+ const errorMessage = error instanceof Error ? error.message : String(error);
416
+ logger.error(`Error getting pending jobs: ${errorMessage}`);
417
+ }
418
+ }
419
+ // Return diagnostic information with proper formatting
420
+ const diagnosticInfo = {
421
+ storage_type: storageType,
422
+ openai_api_key_present: hasOpenAIKey,
423
+ embedding_model: embeddingModel,
424
+ embedding_job_manager_initialized: hasEmbeddingJobManager,
425
+ embedding_service_initialized: !!embeddingProviderInfo,
426
+ embedding_service_info: embeddingServiceInfo,
427
+ embedding_provider_info: embeddingProviderInfo,
428
+ neo4j_config: neo4jInfo,
429
+ entities_with_embeddings: entitiesWithEmbeddings,
430
+ pending_embedding_jobs: pendingJobs,
431
+ environment_variables: {
432
+ DEBUG: process.env.DEBUG === 'true',
433
+ NODE_ENV: process.env.NODE_ENV,
434
+ MEMORY_STORAGE_TYPE: process.env.MEMORY_STORAGE_TYPE || 'neo4j',
435
+ },
436
+ };
437
+ return {
438
+ content: [
439
+ {
440
+ type: 'text',
441
+ text: JSON.stringify(diagnosticInfo, null, 2),
442
+ },
443
+ ],
444
+ };
504
445
  }
505
- default: {
506
- throw new Error(`Unknown tool: ${name}`);
446
+ catch (error) {
447
+ const errorMessage = error instanceof Error ? error.message : String(error);
448
+ const errorStack = error instanceof Error ? error.stack : undefined;
449
+ logger.error(`Error in debug_embedding_config: ${errorMessage}`);
450
+ return {
451
+ content: [
452
+ {
453
+ type: 'text',
454
+ text: JSON.stringify({
455
+ error: errorMessage,
456
+ stack: errorStack,
457
+ }, null, 2),
458
+ },
459
+ ],
460
+ };
507
461
  }
508
462
  }
509
- }
510
- catch (error) {
511
- throw error;
463
+ case 'diagnose_vector_search': {
464
+ return knowledgeGraphManager.storageProvider &&
465
+ typeof knowledgeGraphManager.storageProvider
466
+ .diagnoseVectorSearch === 'function'
467
+ ? {
468
+ content: [
469
+ {
470
+ type: 'text',
471
+ text: JSON.stringify(await knowledgeGraphManager.storageProvider.diagnoseVectorSearch()),
472
+ },
473
+ ],
474
+ }
475
+ : {
476
+ content: [
477
+ {
478
+ type: 'text',
479
+ text: JSON.stringify({
480
+ error: 'Diagnostic method not available',
481
+ storageType: knowledgeGraphManager.storageProvider
482
+ ? knowledgeGraphManager.storageProvider.constructor.name
483
+ : 'unknown',
484
+ }, null, 2),
485
+ },
486
+ ],
487
+ };
488
+ }
489
+ case 'create_entities_batch': {
490
+ return await toolHandlers.handleCreateEntitiesBatch(args, knowledgeGraphManager);
491
+ }
492
+ case 'create_relations_batch': {
493
+ return await toolHandlers.handleCreateRelationsBatch(args, knowledgeGraphManager);
494
+ }
495
+ case 'add_observations_batch': {
496
+ return await toolHandlers.handleAddObservationsBatch(args, knowledgeGraphManager);
497
+ }
498
+ case 'update_entities_batch': {
499
+ return await toolHandlers.handleUpdateEntitiesBatch(args, knowledgeGraphManager);
500
+ }
501
+ default: {
502
+ throw new Error(`Unknown tool: ${name}`);
503
+ }
512
504
  }
513
505
  }
514
506
  //# sourceMappingURL=callToolHandler.js.map