n8n-nodes-engram 0.2.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.
Files changed (154) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +334 -0
  3. package/dist/community/CommunityDetector.d.ts +11 -0
  4. package/dist/community/CommunityDetector.js +126 -0
  5. package/dist/community/CommunityDetector.js.map +1 -0
  6. package/dist/community/CommunitySummarizer.d.ts +8 -0
  7. package/dist/community/CommunitySummarizer.js +56 -0
  8. package/dist/community/CommunitySummarizer.js.map +1 -0
  9. package/dist/community/index.d.ts +2 -0
  10. package/dist/community/index.js +8 -0
  11. package/dist/community/index.js.map +1 -0
  12. package/dist/credentials/EngramExtractionApi.credentials.d.ts +8 -0
  13. package/dist/credentials/EngramExtractionApi.credentials.js +41 -0
  14. package/dist/credentials/EngramExtractionApi.credentials.js.map +1 -0
  15. package/dist/credentials/EngramNeo4jApi.credentials.d.ts +8 -0
  16. package/dist/credentials/EngramNeo4jApi.credentials.js +59 -0
  17. package/dist/credentials/EngramNeo4jApi.credentials.js.map +1 -0
  18. package/dist/descriptions.d.ts +4 -0
  19. package/dist/descriptions.js +41 -0
  20. package/dist/descriptions.js.map +1 -0
  21. package/dist/embeddings/EmbeddingService.d.ts +24 -0
  22. package/dist/embeddings/EmbeddingService.js +64 -0
  23. package/dist/embeddings/EmbeddingService.js.map +1 -0
  24. package/dist/embeddings/cosine.d.ts +1 -0
  25. package/dist/embeddings/cosine.js +21 -0
  26. package/dist/embeddings/cosine.js.map +1 -0
  27. package/dist/embeddings/index.d.ts +2 -0
  28. package/dist/embeddings/index.js +8 -0
  29. package/dist/embeddings/index.js.map +1 -0
  30. package/dist/extraction/ContradictionDetector.d.ts +11 -0
  31. package/dist/extraction/ContradictionDetector.js +35 -0
  32. package/dist/extraction/ContradictionDetector.js.map +1 -0
  33. package/dist/extraction/EntityDeduplicator.d.ts +17 -0
  34. package/dist/extraction/EntityDeduplicator.js +39 -0
  35. package/dist/extraction/EntityDeduplicator.js.map +1 -0
  36. package/dist/extraction/EntityExtractor.d.ts +11 -0
  37. package/dist/extraction/EntityExtractor.js +33 -0
  38. package/dist/extraction/EntityExtractor.js.map +1 -0
  39. package/dist/extraction/ExtractionPipeline.d.ts +24 -0
  40. package/dist/extraction/ExtractionPipeline.js +126 -0
  41. package/dist/extraction/ExtractionPipeline.js.map +1 -0
  42. package/dist/extraction/LlmClient.d.ts +36 -0
  43. package/dist/extraction/LlmClient.js +73 -0
  44. package/dist/extraction/LlmClient.js.map +1 -0
  45. package/dist/extraction/RelationshipExtractor.d.ts +12 -0
  46. package/dist/extraction/RelationshipExtractor.js +38 -0
  47. package/dist/extraction/RelationshipExtractor.js.map +1 -0
  48. package/dist/extraction/index.d.ts +6 -0
  49. package/dist/extraction/index.js +16 -0
  50. package/dist/extraction/index.js.map +1 -0
  51. package/dist/extraction/prompts.d.ts +16 -0
  52. package/dist/extraction/prompts.js +101 -0
  53. package/dist/extraction/prompts.js.map +1 -0
  54. package/dist/memory/EngramChatMemory.d.ts +42 -0
  55. package/dist/memory/EngramChatMemory.js +162 -0
  56. package/dist/memory/EngramChatMemory.js.map +1 -0
  57. package/dist/memory/EngramChatMessageHistory.d.ts +22 -0
  58. package/dist/memory/EngramChatMessageHistory.js +72 -0
  59. package/dist/memory/EngramChatMessageHistory.js.map +1 -0
  60. package/dist/memory/index.d.ts +2 -0
  61. package/dist/memory/index.js +8 -0
  62. package/dist/memory/index.js.map +1 -0
  63. package/dist/nodes/EngramAdmin/EngramAdmin.node.d.ts +5 -0
  64. package/dist/nodes/EngramAdmin/EngramAdmin.node.js +798 -0
  65. package/dist/nodes/EngramAdmin/EngramAdmin.node.js.map +1 -0
  66. package/dist/nodes/EngramAdmin/engram-admin.png +0 -0
  67. package/dist/nodes/EngramExplorer/EngramExplorer.node.d.ts +5 -0
  68. package/dist/nodes/EngramExplorer/EngramExplorer.node.js +932 -0
  69. package/dist/nodes/EngramExplorer/EngramExplorer.node.js.map +1 -0
  70. package/dist/nodes/EngramExplorer/engram-explorer.png +0 -0
  71. package/dist/nodes/EngramMemory/EngramMemory.node.d.ts +10 -0
  72. package/dist/nodes/EngramMemory/EngramMemory.node.js +462 -0
  73. package/dist/nodes/EngramMemory/EngramMemory.node.js.map +1 -0
  74. package/dist/nodes/EngramMemory/engram.png +0 -0
  75. package/dist/nodes/EngramTrigger/EngramTrigger.node.d.ts +5 -0
  76. package/dist/nodes/EngramTrigger/EngramTrigger.node.js +146 -0
  77. package/dist/nodes/EngramTrigger/EngramTrigger.node.js.map +1 -0
  78. package/dist/nodes/EngramTrigger/engram-trigger.png +0 -0
  79. package/dist/schemas/Community.schema.d.ts +656 -0
  80. package/dist/schemas/Community.schema.js +26 -0
  81. package/dist/schemas/Community.schema.js.map +1 -0
  82. package/dist/schemas/EntityEdge.schema.d.ts +86 -0
  83. package/dist/schemas/EntityEdge.schema.js +34 -0
  84. package/dist/schemas/EntityEdge.schema.js.map +1 -0
  85. package/dist/schemas/EntityNode.schema.d.ts +56 -0
  86. package/dist/schemas/EntityNode.schema.js +24 -0
  87. package/dist/schemas/EntityNode.schema.js.map +1 -0
  88. package/dist/schemas/EpisodicNode.schema.d.ts +53 -0
  89. package/dist/schemas/EpisodicNode.schema.js +23 -0
  90. package/dist/schemas/EpisodicNode.schema.js.map +1 -0
  91. package/dist/schemas/GraphData.schema.d.ts +220 -0
  92. package/dist/schemas/GraphData.schema.js +25 -0
  93. package/dist/schemas/GraphData.schema.js.map +1 -0
  94. package/dist/schemas/index.d.ts +5 -0
  95. package/dist/schemas/index.js +20 -0
  96. package/dist/schemas/index.js.map +1 -0
  97. package/dist/search/HybridSearchEngine.d.ts +31 -0
  98. package/dist/search/HybridSearchEngine.js +140 -0
  99. package/dist/search/HybridSearchEngine.js.map +1 -0
  100. package/dist/search/MinisearchProvider.d.ts +20 -0
  101. package/dist/search/MinisearchProvider.js +77 -0
  102. package/dist/search/MinisearchProvider.js.map +1 -0
  103. package/dist/search/TextSearchProvider.d.ts +20 -0
  104. package/dist/search/TextSearchProvider.js +3 -0
  105. package/dist/search/TextSearchProvider.js.map +1 -0
  106. package/dist/search/index.d.ts +3 -0
  107. package/dist/search/index.js +8 -0
  108. package/dist/search/index.js.map +1 -0
  109. package/dist/storage/GraphologyStorage.d.ts +42 -0
  110. package/dist/storage/GraphologyStorage.js +665 -0
  111. package/dist/storage/GraphologyStorage.js.map +1 -0
  112. package/dist/storage/IGraphStorage.d.ts +64 -0
  113. package/dist/storage/IGraphStorage.js +3 -0
  114. package/dist/storage/IGraphStorage.js.map +1 -0
  115. package/dist/storage/Neo4jStorage.d.ts +45 -0
  116. package/dist/storage/Neo4jStorage.js +949 -0
  117. package/dist/storage/Neo4jStorage.js.map +1 -0
  118. package/dist/storage/StorageFactory.d.ts +14 -0
  119. package/dist/storage/StorageFactory.js +26 -0
  120. package/dist/storage/StorageFactory.js.map +1 -0
  121. package/dist/storage/index.d.ts +3 -0
  122. package/dist/storage/index.js +8 -0
  123. package/dist/storage/index.js.map +1 -0
  124. package/dist/traversal/EpisodeTraverser.d.ts +10 -0
  125. package/dist/traversal/EpisodeTraverser.js +46 -0
  126. package/dist/traversal/EpisodeTraverser.js.map +1 -0
  127. package/dist/traversal/GraphTraverser.d.ts +24 -0
  128. package/dist/traversal/GraphTraverser.js +89 -0
  129. package/dist/traversal/GraphTraverser.js.map +1 -0
  130. package/dist/traversal/index.d.ts +2 -0
  131. package/dist/traversal/index.js +8 -0
  132. package/dist/traversal/index.js.map +1 -0
  133. package/dist/utils/descriptions.d.ts +6 -0
  134. package/dist/utils/descriptions.js +95 -0
  135. package/dist/utils/descriptions.js.map +1 -0
  136. package/dist/utils/helpers.d.ts +23 -0
  137. package/dist/utils/helpers.js +146 -0
  138. package/dist/utils/helpers.js.map +1 -0
  139. package/dist/utils/logWrapper.d.ts +26 -0
  140. package/dist/utils/logWrapper.js +300 -0
  141. package/dist/utils/logWrapper.js.map +1 -0
  142. package/dist/utils/sharedFields.d.ts +6 -0
  143. package/dist/utils/sharedFields.js +121 -0
  144. package/dist/utils/sharedFields.js.map +1 -0
  145. package/dist/utils/temporal.d.ts +22 -0
  146. package/dist/utils/temporal.js +44 -0
  147. package/dist/utils/temporal.js.map +1 -0
  148. package/dist/utils/tracing.d.ts +7 -0
  149. package/dist/utils/tracing.js +20 -0
  150. package/dist/utils/tracing.js.map +1 -0
  151. package/dist/utils/uuid.d.ts +2 -0
  152. package/dist/utils/uuid.js +13 -0
  153. package/dist/utils/uuid.js.map +1 -0
  154. package/package.json +108 -0
@@ -0,0 +1,932 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EngramExplorer = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ const StorageFactory_1 = require("../../storage/StorageFactory");
6
+ const HybridSearchEngine_1 = require("../../search/HybridSearchEngine");
7
+ const temporal_1 = require("../../utils/temporal");
8
+ const GraphTraverser_1 = require("../../traversal/GraphTraverser");
9
+ const EpisodeTraverser_1 = require("../../traversal/EpisodeTraverser");
10
+ class EngramExplorer {
11
+ constructor() {
12
+ this.description = {
13
+ displayName: 'Engram Explorer',
14
+ name: 'engramExplorer',
15
+ icon: 'file:engram-explorer.png',
16
+ group: ['transform'],
17
+ version: [1, 2],
18
+ description: 'Explore, create, update, and query the Engram knowledge graph',
19
+ defaults: {
20
+ name: 'Engram Explorer',
21
+ },
22
+ inputs: ["main"],
23
+ outputs: ["main"],
24
+ credentials: [
25
+ {
26
+ name: 'engramNeo4jApi',
27
+ required: false,
28
+ displayOptions: {
29
+ show: {
30
+ backend: ['neo4j'],
31
+ },
32
+ },
33
+ },
34
+ ],
35
+ properties: [
36
+ {
37
+ displayName: 'Backend',
38
+ name: 'backend',
39
+ type: 'options',
40
+ options: [
41
+ { name: 'Embedded (Graphology)', value: 'embedded' },
42
+ { name: 'Neo4j (Remote)', value: 'neo4j' },
43
+ ],
44
+ default: 'embedded',
45
+ },
46
+ {
47
+ displayName: 'Resource',
48
+ name: 'resource',
49
+ type: 'options',
50
+ noDataExpression: true,
51
+ options: [
52
+ { name: 'Entity', value: 'entity' },
53
+ { name: 'Relationship', value: 'relationship' },
54
+ { name: 'Episode', value: 'episode' },
55
+ { name: 'Traversal', value: 'traversal' },
56
+ ],
57
+ default: 'entity',
58
+ },
59
+ {
60
+ displayName: 'Operation',
61
+ name: 'operation',
62
+ type: 'options',
63
+ noDataExpression: true,
64
+ displayOptions: { show: { resource: ['entity'] } },
65
+ options: [
66
+ {
67
+ name: 'Create',
68
+ value: 'create',
69
+ description: 'Create a new entity',
70
+ action: 'Create an entity',
71
+ },
72
+ {
73
+ name: 'Delete',
74
+ value: 'delete',
75
+ description: 'Delete an entity by UUID',
76
+ action: 'Delete an entity',
77
+ },
78
+ {
79
+ name: 'Get',
80
+ value: 'get',
81
+ description: 'Get an entity by UUID',
82
+ action: 'Get an entity',
83
+ },
84
+ {
85
+ name: 'Get by Name',
86
+ value: 'getByName',
87
+ description: 'Get an entity by name',
88
+ action: 'Get an entity by name',
89
+ },
90
+ {
91
+ name: 'List',
92
+ value: 'list',
93
+ description: 'List entities in a group',
94
+ action: 'List entities',
95
+ },
96
+ {
97
+ name: 'Search',
98
+ value: 'search',
99
+ description: 'Search entities by text',
100
+ action: 'Search entities',
101
+ },
102
+ {
103
+ name: 'Update',
104
+ value: 'update',
105
+ description: 'Update an existing entity',
106
+ action: 'Update an entity',
107
+ },
108
+ ],
109
+ default: 'search',
110
+ },
111
+ {
112
+ displayName: 'Operation',
113
+ name: 'operation',
114
+ type: 'options',
115
+ noDataExpression: true,
116
+ displayOptions: { show: { resource: ['relationship'] } },
117
+ options: [
118
+ {
119
+ name: 'Create',
120
+ value: 'create',
121
+ description: 'Create a new relationship between entities',
122
+ action: 'Create a relationship',
123
+ },
124
+ {
125
+ name: 'Delete',
126
+ value: 'delete',
127
+ description: 'Delete a relationship by UUID',
128
+ action: 'Delete a relationship',
129
+ },
130
+ {
131
+ name: 'Get',
132
+ value: 'get',
133
+ description: 'Get a relationship by UUID',
134
+ action: 'Get a relationship',
135
+ },
136
+ {
137
+ name: 'Get Between',
138
+ value: 'getBetween',
139
+ description: 'Get relationships between two entities',
140
+ action: 'Get relationships between entities',
141
+ },
142
+ {
143
+ name: 'Get for Entity',
144
+ value: 'getForEntity',
145
+ description: 'Get all relationships for an entity',
146
+ action: 'Get relationships for entity',
147
+ },
148
+ {
149
+ name: 'Search',
150
+ value: 'search',
151
+ description: 'Search relationships by text',
152
+ action: 'Search relationships',
153
+ },
154
+ {
155
+ name: 'Update',
156
+ value: 'update',
157
+ description: 'Update an existing relationship',
158
+ action: 'Update a relationship',
159
+ },
160
+ ],
161
+ default: 'search',
162
+ },
163
+ {
164
+ displayName: 'Operation',
165
+ name: 'operation',
166
+ type: 'options',
167
+ noDataExpression: true,
168
+ displayOptions: { show: { resource: ['episode'] } },
169
+ options: [
170
+ {
171
+ name: 'Get',
172
+ value: 'get',
173
+ description: 'Get an episode by UUID',
174
+ action: 'Get an episode',
175
+ },
176
+ {
177
+ name: 'Get Count',
178
+ value: 'getCount',
179
+ description: 'Get episode count for a group',
180
+ action: 'Get episode count',
181
+ },
182
+ {
183
+ name: 'Get Recent',
184
+ value: 'getRecent',
185
+ description: 'Get recent episodes',
186
+ action: 'Get recent episodes',
187
+ },
188
+ ],
189
+ default: 'getRecent',
190
+ },
191
+ {
192
+ displayName: 'Operation',
193
+ name: 'operation',
194
+ type: 'options',
195
+ noDataExpression: true,
196
+ displayOptions: { show: { resource: ['traversal'] } },
197
+ options: [
198
+ {
199
+ name: 'BFS from Entity',
200
+ value: 'bfsFromEntity',
201
+ description: 'Breadth-first traversal from one or more seed entities',
202
+ action: 'BFS from entity',
203
+ },
204
+ {
205
+ name: 'BFS from Episodes',
206
+ value: 'bfsFromEpisodes',
207
+ description: 'Traverse from entities referenced in recent episodes',
208
+ action: 'BFS from episodes',
209
+ },
210
+ ],
211
+ default: 'bfsFromEntity',
212
+ },
213
+ {
214
+ displayName: 'Group ID',
215
+ name: 'groupId',
216
+ type: 'string',
217
+ default: '',
218
+ required: true,
219
+ description: 'The session/group identifier to scope the query',
220
+ displayOptions: {
221
+ show: {
222
+ operation: [
223
+ 'search',
224
+ 'getByName',
225
+ 'list',
226
+ 'getRecent',
227
+ 'getCount',
228
+ 'create',
229
+ 'bfsFromEpisodes',
230
+ ],
231
+ },
232
+ },
233
+ },
234
+ {
235
+ displayName: 'UUID',
236
+ name: 'uuid',
237
+ type: 'string',
238
+ default: '',
239
+ required: true,
240
+ displayOptions: {
241
+ show: {
242
+ operation: ['get', 'delete', 'getForEntity', 'update'],
243
+ },
244
+ },
245
+ description: 'The unique identifier of the entity, relationship, or episode',
246
+ },
247
+ {
248
+ displayName: 'Query',
249
+ name: 'query',
250
+ type: 'string',
251
+ default: '',
252
+ required: true,
253
+ displayOptions: {
254
+ show: { operation: ['search'] },
255
+ },
256
+ description: 'Search query text to find matching entities or relationships',
257
+ },
258
+ {
259
+ displayName: 'Entity Name',
260
+ name: 'entityName',
261
+ type: 'string',
262
+ default: '',
263
+ required: true,
264
+ displayOptions: {
265
+ show: {
266
+ resource: ['entity'],
267
+ operation: ['getByName', 'create'],
268
+ },
269
+ },
270
+ description: 'The name of the entity',
271
+ },
272
+ {
273
+ displayName: 'Name',
274
+ name: 'updateName',
275
+ type: 'string',
276
+ default: '',
277
+ displayOptions: {
278
+ show: {
279
+ resource: ['entity'],
280
+ operation: ['update'],
281
+ },
282
+ },
283
+ description: 'New name for the entity (leave empty to keep current)',
284
+ },
285
+ {
286
+ displayName: 'Entity Type',
287
+ name: 'entityType',
288
+ type: 'string',
289
+ default: '',
290
+ displayOptions: {
291
+ show: {
292
+ resource: ['entity'],
293
+ operation: ['create', 'update'],
294
+ },
295
+ },
296
+ placeholder: 'e.g. person, organization, location, concept',
297
+ description: 'The type/category of the entity',
298
+ },
299
+ {
300
+ displayName: 'Summary',
301
+ name: 'summary',
302
+ type: 'string',
303
+ typeOptions: { rows: 3 },
304
+ default: '',
305
+ displayOptions: {
306
+ show: {
307
+ resource: ['entity'],
308
+ operation: ['create', 'update'],
309
+ },
310
+ },
311
+ description: 'A text summary describing the entity',
312
+ },
313
+ {
314
+ displayName: 'Source Entity UUID',
315
+ name: 'sourceUuid',
316
+ type: 'string',
317
+ default: '',
318
+ required: true,
319
+ displayOptions: {
320
+ show: {
321
+ resource: ['relationship'],
322
+ operation: ['getBetween', 'create'],
323
+ },
324
+ },
325
+ description: 'UUID of the source entity',
326
+ },
327
+ {
328
+ displayName: 'Target Entity UUID',
329
+ name: 'targetUuid',
330
+ type: 'string',
331
+ default: '',
332
+ required: true,
333
+ displayOptions: {
334
+ show: {
335
+ resource: ['relationship'],
336
+ operation: ['getBetween', 'create'],
337
+ },
338
+ },
339
+ description: 'UUID of the target entity',
340
+ },
341
+ {
342
+ displayName: 'Relationship Name',
343
+ name: 'relationshipName',
344
+ type: 'string',
345
+ default: '',
346
+ displayOptions: {
347
+ show: {
348
+ resource: ['relationship'],
349
+ operation: ['create', 'update'],
350
+ },
351
+ },
352
+ placeholder: 'e.g. WORKS_AT, KNOWS, LIVES_IN',
353
+ description: 'The name/type of the relationship (auto-uppercased)',
354
+ },
355
+ {
356
+ displayName: 'Fact',
357
+ name: 'fact',
358
+ type: 'string',
359
+ typeOptions: { rows: 3 },
360
+ default: '',
361
+ required: true,
362
+ displayOptions: {
363
+ show: {
364
+ resource: ['relationship'],
365
+ operation: ['create'],
366
+ },
367
+ },
368
+ description: 'The factual statement this relationship represents',
369
+ },
370
+ {
371
+ displayName: 'Fact',
372
+ name: 'factUpdate',
373
+ type: 'string',
374
+ typeOptions: { rows: 3 },
375
+ default: '',
376
+ displayOptions: {
377
+ show: {
378
+ resource: ['relationship'],
379
+ operation: ['update'],
380
+ },
381
+ },
382
+ description: 'Updated factual statement (leave empty to keep current)',
383
+ },
384
+ {
385
+ displayName: 'Valid At',
386
+ name: 'validAt',
387
+ type: 'string',
388
+ default: '',
389
+ displayOptions: {
390
+ show: {
391
+ resource: ['relationship'],
392
+ operation: ['create'],
393
+ },
394
+ },
395
+ placeholder: '2026-01-31T12:00:00.000Z',
396
+ description: 'When this fact became true (ISO datetime). Defaults to now.',
397
+ },
398
+ {
399
+ displayName: 'Expired At',
400
+ name: 'expiredAt',
401
+ type: 'string',
402
+ default: '',
403
+ displayOptions: {
404
+ show: {
405
+ resource: ['relationship'],
406
+ operation: ['update'],
407
+ },
408
+ },
409
+ placeholder: '2026-01-31T12:00:00.000Z',
410
+ description: 'Set to mark this relationship as expired/superseded',
411
+ },
412
+ {
413
+ displayName: 'Invalid At',
414
+ name: 'invalidAt',
415
+ type: 'string',
416
+ default: '',
417
+ displayOptions: {
418
+ show: {
419
+ resource: ['relationship'],
420
+ operation: ['update'],
421
+ },
422
+ },
423
+ placeholder: '2026-01-31T12:00:00.000Z',
424
+ description: 'When this fact stopped being true',
425
+ },
426
+ {
427
+ displayName: 'Attributes',
428
+ name: 'attributes',
429
+ type: 'json',
430
+ default: '{}',
431
+ displayOptions: {
432
+ show: {
433
+ operation: ['create', 'update'],
434
+ },
435
+ },
436
+ description: 'Additional key-value attributes as JSON object',
437
+ },
438
+ {
439
+ displayName: 'Limit',
440
+ name: 'limit',
441
+ type: 'number',
442
+ default: 10,
443
+ typeOptions: {
444
+ minValue: 1,
445
+ maxValue: 100,
446
+ },
447
+ displayOptions: {
448
+ show: { operation: ['search', 'list', 'getRecent'] },
449
+ },
450
+ description: 'Maximum number of results to return',
451
+ },
452
+ {
453
+ displayName: 'Min Relevance Score',
454
+ name: 'minRelevanceScore',
455
+ type: 'number',
456
+ default: 0,
457
+ typeOptions: {
458
+ minValue: 0,
459
+ maxValue: 1,
460
+ numberStepSize: 0.1,
461
+ },
462
+ displayOptions: {
463
+ show: { operation: ['search'] },
464
+ },
465
+ description: 'Minimum relevance score (0-1) for results. Higher values return only more relevant matches.',
466
+ },
467
+ {
468
+ displayName: 'Seed Entity UUIDs',
469
+ name: 'seedUuids',
470
+ type: 'string',
471
+ default: '',
472
+ required: true,
473
+ displayOptions: {
474
+ show: {
475
+ resource: ['traversal'],
476
+ operation: ['bfsFromEntity'],
477
+ },
478
+ },
479
+ placeholder: 'uuid1, uuid2',
480
+ description: 'Comma-separated UUIDs of seed entities to start traversal from',
481
+ },
482
+ {
483
+ displayName: 'Max Hops',
484
+ name: 'maxHops',
485
+ type: 'number',
486
+ default: 2,
487
+ typeOptions: {
488
+ minValue: 1,
489
+ maxValue: 10,
490
+ },
491
+ displayOptions: {
492
+ show: {
493
+ resource: ['traversal'],
494
+ },
495
+ },
496
+ description: 'Maximum BFS depth (number of hops from seed entities)',
497
+ },
498
+ {
499
+ displayName: 'Max Entities',
500
+ name: 'maxEntities',
501
+ type: 'number',
502
+ default: 50,
503
+ typeOptions: {
504
+ minValue: 1,
505
+ maxValue: 500,
506
+ },
507
+ displayOptions: {
508
+ show: {
509
+ resource: ['traversal'],
510
+ },
511
+ },
512
+ description: 'Maximum number of entities to return',
513
+ },
514
+ {
515
+ displayName: 'Include Expired Edges',
516
+ name: 'includeExpiredEdges',
517
+ type: 'boolean',
518
+ default: false,
519
+ displayOptions: {
520
+ show: {
521
+ resource: ['traversal'],
522
+ },
523
+ },
524
+ description: 'Whether to include expired/superseded edges in traversal',
525
+ },
526
+ {
527
+ displayName: 'Episode Count',
528
+ name: 'episodeCount',
529
+ type: 'number',
530
+ default: 5,
531
+ typeOptions: {
532
+ minValue: 1,
533
+ maxValue: 50,
534
+ },
535
+ displayOptions: {
536
+ show: {
537
+ resource: ['traversal'],
538
+ operation: ['bfsFromEpisodes'],
539
+ },
540
+ },
541
+ description: 'Number of recent episodes to start traversal from',
542
+ },
543
+ ],
544
+ };
545
+ }
546
+ async execute() {
547
+ var _a;
548
+ const items = this.getInputData();
549
+ const backend = this.getNodeParameter('backend', 0, 'embedded');
550
+ const resource = this.getNodeParameter('resource', 0);
551
+ const operation = this.getNodeParameter('operation', 0);
552
+ let storage;
553
+ if (backend === 'neo4j') {
554
+ const credentials = await this.getCredentials('engramNeo4jApi');
555
+ storage = (0, StorageFactory_1.createStorage)({
556
+ backend: 'neo4j',
557
+ uri: credentials.uri,
558
+ username: credentials.username,
559
+ password: credentials.password,
560
+ database: credentials.database,
561
+ });
562
+ }
563
+ else {
564
+ const workflowId = (_a = this.getWorkflow().id) !== null && _a !== void 0 ? _a : 'default';
565
+ storage = (0, StorageFactory_1.createStorage)({
566
+ backend: 'embedded',
567
+ persistPath: `engram-data/${workflowId}-engram.json`,
568
+ });
569
+ }
570
+ await storage.initialize();
571
+ const returnData = [];
572
+ const ctx = this;
573
+ try {
574
+ for (let i = 0; i < items.length; i++) {
575
+ try {
576
+ if (resource === 'entity') {
577
+ await executeEntityOperation(ctx, storage, operation, i, returnData);
578
+ }
579
+ else if (resource === 'relationship') {
580
+ await executeRelationshipOperation(ctx, storage, operation, i, returnData);
581
+ }
582
+ else if (resource === 'episode') {
583
+ await executeEpisodeOperation(ctx, storage, operation, i, returnData);
584
+ }
585
+ else if (resource === 'traversal') {
586
+ await executeTraversalOperation(ctx, storage, operation, i, returnData);
587
+ }
588
+ }
589
+ catch (error) {
590
+ if (error instanceof n8n_workflow_1.NodeOperationError)
591
+ throw error;
592
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), `Engram Explorer error: ${error.message}`, { itemIndex: i });
593
+ }
594
+ }
595
+ }
596
+ finally {
597
+ if (backend === 'neo4j') {
598
+ await storage.close();
599
+ }
600
+ }
601
+ return [returnData.length > 0 ? returnData : [{ json: {} }]];
602
+ }
603
+ }
604
+ exports.EngramExplorer = EngramExplorer;
605
+ async function executeEntityOperation(ctx, storage, operation, i, returnData) {
606
+ if (operation === 'create') {
607
+ const groupId = ctx.getNodeParameter('groupId', i);
608
+ const name = ctx.getNodeParameter('entityName', i);
609
+ const entityType = ctx.getNodeParameter('entityType', i, '');
610
+ const summary = ctx.getNodeParameter('summary', i, '');
611
+ const attributesRaw = ctx.getNodeParameter('attributes', i, '{}');
612
+ if (!name) {
613
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'Entity Name is required', { itemIndex: i });
614
+ }
615
+ if (!groupId) {
616
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'Group ID is required', { itemIndex: i });
617
+ }
618
+ const attributes = parseAttributes(attributesRaw);
619
+ const entity = await storage.addEntity({
620
+ name,
621
+ group_id: groupId,
622
+ entity_type: entityType || 'unknown',
623
+ summary: summary || '',
624
+ attributes,
625
+ });
626
+ returnData.push({ json: entity });
627
+ }
628
+ else if (operation === 'update') {
629
+ const uuid = ctx.getNodeParameter('uuid', i);
630
+ if (!uuid) {
631
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'UUID is required', { itemIndex: i });
632
+ }
633
+ const updateName = ctx.getNodeParameter('updateName', i, '');
634
+ const entityType = ctx.getNodeParameter('entityType', i, '');
635
+ const summary = ctx.getNodeParameter('summary', i, '');
636
+ const attributesRaw = ctx.getNodeParameter('attributes', i, '{}');
637
+ const updates = {};
638
+ if (updateName)
639
+ updates.name = updateName;
640
+ if (entityType)
641
+ updates.entity_type = entityType;
642
+ if (summary)
643
+ updates.summary = summary;
644
+ const attributes = parseAttributes(attributesRaw);
645
+ if (Object.keys(attributes).length > 0)
646
+ updates.attributes = attributes;
647
+ const entity = await storage.updateEntity(uuid, updates);
648
+ returnData.push({ json: entity });
649
+ }
650
+ else if (operation === 'search') {
651
+ const groupId = ctx.getNodeParameter('groupId', i);
652
+ const query = ctx.getNodeParameter('query', i);
653
+ const limit = ctx.getNodeParameter('limit', i);
654
+ const minScore = ctx.getNodeParameter('minRelevanceScore', i, 0);
655
+ if (!query) {
656
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'Query is required', { itemIndex: i });
657
+ }
658
+ const searchEngine = new HybridSearchEngine_1.HybridSearchEngine(storage);
659
+ const results = await searchEngine.searchEntities(query, groupId, {
660
+ limit,
661
+ min_score: minScore,
662
+ });
663
+ for (const r of results) {
664
+ returnData.push({ json: { ...r.entity, _score: r.score } });
665
+ }
666
+ }
667
+ else if (operation === 'get') {
668
+ const uuid = ctx.getNodeParameter('uuid', i);
669
+ if (!uuid) {
670
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'UUID is required', { itemIndex: i });
671
+ }
672
+ const entity = await storage.getEntity(uuid);
673
+ if (entity)
674
+ returnData.push({ json: entity });
675
+ }
676
+ else if (operation === 'getByName') {
677
+ const groupId = ctx.getNodeParameter('groupId', i);
678
+ const name = ctx.getNodeParameter('entityName', i);
679
+ if (!name) {
680
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'Entity Name is required', { itemIndex: i });
681
+ }
682
+ const entity = await storage.getEntityByName(name, groupId);
683
+ if (entity)
684
+ returnData.push({ json: entity });
685
+ }
686
+ else if (operation === 'list') {
687
+ const groupId = ctx.getNodeParameter('groupId', i);
688
+ const limit = ctx.getNodeParameter('limit', i);
689
+ const entities = await storage.listEntities(groupId, { limit });
690
+ for (const e of entities) {
691
+ returnData.push({ json: e });
692
+ }
693
+ }
694
+ else if (operation === 'delete') {
695
+ const uuid = ctx.getNodeParameter('uuid', i);
696
+ if (!uuid) {
697
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'UUID is required', { itemIndex: i });
698
+ }
699
+ await storage.deleteEntity(uuid);
700
+ returnData.push({ json: { success: true, deleted: uuid } });
701
+ }
702
+ }
703
+ async function executeRelationshipOperation(ctx, storage, operation, i, returnData) {
704
+ if (operation === 'create') {
705
+ const groupId = ctx.getNodeParameter('groupId', i);
706
+ const sourceUuid = ctx.getNodeParameter('sourceUuid', i);
707
+ const targetUuid = ctx.getNodeParameter('targetUuid', i);
708
+ const name = ctx.getNodeParameter('relationshipName', i, '');
709
+ const fact = ctx.getNodeParameter('fact', i);
710
+ const validAt = ctx.getNodeParameter('validAt', i, '');
711
+ const attributesRaw = ctx.getNodeParameter('attributes', i, '{}');
712
+ if (!groupId || !sourceUuid || !targetUuid || !fact) {
713
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'Group ID, Source UUID, Target UUID, and Fact are all required', { itemIndex: i });
714
+ }
715
+ const attributes = parseAttributes(attributesRaw);
716
+ const edgeName = name ? name.toUpperCase().replace(/\s+/g, '_') : 'RELATES_TO';
717
+ const edge = await storage.addEdge({
718
+ group_id: groupId,
719
+ source_node_uuid: sourceUuid,
720
+ target_node_uuid: targetUuid,
721
+ name: edgeName,
722
+ fact,
723
+ valid_at: validAt || (0, temporal_1.nowIso)(),
724
+ attributes,
725
+ });
726
+ returnData.push({ json: edge });
727
+ }
728
+ else if (operation === 'get') {
729
+ const uuid = ctx.getNodeParameter('uuid', i);
730
+ if (!uuid) {
731
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'UUID is required', { itemIndex: i });
732
+ }
733
+ const edge = await storage.getEdge(uuid);
734
+ if (edge)
735
+ returnData.push({ json: edge });
736
+ }
737
+ else if (operation === 'update') {
738
+ const uuid = ctx.getNodeParameter('uuid', i);
739
+ if (!uuid) {
740
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'UUID is required', { itemIndex: i });
741
+ }
742
+ const name = ctx.getNodeParameter('relationshipName', i, '');
743
+ const fact = ctx.getNodeParameter('factUpdate', i, '');
744
+ const expiredAt = ctx.getNodeParameter('expiredAt', i, '');
745
+ const invalidAt = ctx.getNodeParameter('invalidAt', i, '');
746
+ const attributesRaw = ctx.getNodeParameter('attributes', i, '{}');
747
+ const updates = {};
748
+ if (name)
749
+ updates.name = name.toUpperCase().replace(/\s+/g, '_');
750
+ if (fact)
751
+ updates.fact = fact;
752
+ if (expiredAt)
753
+ updates.expired_at = expiredAt;
754
+ if (invalidAt)
755
+ updates.invalid_at = invalidAt;
756
+ const attributes = parseAttributes(attributesRaw);
757
+ if (Object.keys(attributes).length > 0)
758
+ updates.attributes = attributes;
759
+ const edge = await storage.updateEdge(uuid, updates);
760
+ returnData.push({ json: edge });
761
+ }
762
+ else if (operation === 'search') {
763
+ const groupId = ctx.getNodeParameter('groupId', i);
764
+ const query = ctx.getNodeParameter('query', i);
765
+ const limit = ctx.getNodeParameter('limit', i);
766
+ const minScore = ctx.getNodeParameter('minRelevanceScore', i, 0);
767
+ if (!query) {
768
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'Query is required', { itemIndex: i });
769
+ }
770
+ const searchEngine = new HybridSearchEngine_1.HybridSearchEngine(storage);
771
+ const results = await searchEngine.searchEdges(query, groupId, {
772
+ limit,
773
+ min_score: minScore,
774
+ });
775
+ for (const r of results) {
776
+ returnData.push({
777
+ json: {
778
+ ...r.edge,
779
+ _score: r.score,
780
+ _source: r.sourceEntity.name,
781
+ _target: r.targetEntity.name,
782
+ },
783
+ });
784
+ }
785
+ }
786
+ else if (operation === 'getForEntity') {
787
+ const uuid = ctx.getNodeParameter('uuid', i);
788
+ if (!uuid) {
789
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'UUID is required', { itemIndex: i });
790
+ }
791
+ const edges = await storage.getEdgesForEntity(uuid);
792
+ for (const e of edges) {
793
+ returnData.push({ json: e });
794
+ }
795
+ }
796
+ else if (operation === 'getBetween') {
797
+ const sourceUuid = ctx.getNodeParameter('sourceUuid', i);
798
+ const targetUuid = ctx.getNodeParameter('targetUuid', i);
799
+ if (!sourceUuid || !targetUuid) {
800
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'Both Source UUID and Target UUID are required', {
801
+ itemIndex: i,
802
+ });
803
+ }
804
+ const edges = await storage.getEdgesBetween(sourceUuid, targetUuid);
805
+ for (const e of edges) {
806
+ returnData.push({ json: e });
807
+ }
808
+ }
809
+ else if (operation === 'delete') {
810
+ const uuid = ctx.getNodeParameter('uuid', i);
811
+ if (!uuid) {
812
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'UUID is required', { itemIndex: i });
813
+ }
814
+ await storage.deleteEdge(uuid);
815
+ returnData.push({ json: { success: true, deleted: uuid } });
816
+ }
817
+ }
818
+ async function executeEpisodeOperation(ctx, storage, operation, i, returnData) {
819
+ if (operation === 'get') {
820
+ const uuid = ctx.getNodeParameter('uuid', i);
821
+ if (!uuid) {
822
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'UUID is required', { itemIndex: i });
823
+ }
824
+ const episode = await storage.getEpisode(uuid);
825
+ if (episode)
826
+ returnData.push({ json: episode });
827
+ }
828
+ else if (operation === 'getRecent') {
829
+ const groupId = ctx.getNodeParameter('groupId', i);
830
+ const limit = ctx.getNodeParameter('limit', i);
831
+ const episodes = await storage.getRecentEpisodes(groupId, limit);
832
+ for (const ep of episodes) {
833
+ returnData.push({ json: ep });
834
+ }
835
+ }
836
+ else if (operation === 'getCount') {
837
+ const groupId = ctx.getNodeParameter('groupId', i);
838
+ const count = await storage.getEpisodeCount(groupId);
839
+ returnData.push({ json: { group_id: groupId, episode_count: count } });
840
+ }
841
+ }
842
+ async function executeTraversalOperation(ctx, storage, operation, i, returnData) {
843
+ if (operation === 'bfsFromEntity') {
844
+ const seedUuidsRaw = ctx.getNodeParameter('seedUuids', i);
845
+ const seedUuids = seedUuidsRaw
846
+ .split(',')
847
+ .map((s) => s.trim())
848
+ .filter(Boolean);
849
+ if (seedUuids.length === 0) {
850
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'At least one Seed Entity UUID is required', {
851
+ itemIndex: i,
852
+ });
853
+ }
854
+ const maxHops = ctx.getNodeParameter('maxHops', i, 2);
855
+ const maxEntities = ctx.getNodeParameter('maxEntities', i, 50);
856
+ const includeExpiredEdges = ctx.getNodeParameter('includeExpiredEdges', i, false);
857
+ const traverser = new GraphTraverser_1.GraphTraverser();
858
+ const result = await traverser.traverse(storage, seedUuids, {
859
+ maxHops,
860
+ maxEntities,
861
+ includeExpiredEdges,
862
+ });
863
+ returnData.push({
864
+ json: {
865
+ entity_count: result.entities.length,
866
+ edge_count: result.edges.length,
867
+ total_hops: result.total_hops,
868
+ seed_entities: result.seed_entities,
869
+ context: result.context,
870
+ entities: result.entities,
871
+ edges: result.edges,
872
+ paths: result.paths.map((p) => {
873
+ var _a, _b;
874
+ return ({
875
+ entity_uuid: p.entity.uuid,
876
+ entity_name: p.entity.name,
877
+ hop: p.hop,
878
+ via_edge_uuid: (_b = (_a = p.via_edge) === null || _a === void 0 ? void 0 : _a.uuid) !== null && _b !== void 0 ? _b : null,
879
+ });
880
+ }),
881
+ },
882
+ });
883
+ }
884
+ else if (operation === 'bfsFromEpisodes') {
885
+ const groupId = ctx.getNodeParameter('groupId', i);
886
+ if (!groupId) {
887
+ throw new n8n_workflow_1.NodeOperationError(ctx.getNode(), 'Group ID is required', { itemIndex: i });
888
+ }
889
+ const maxHops = ctx.getNodeParameter('maxHops', i, 2);
890
+ const maxEntities = ctx.getNodeParameter('maxEntities', i, 50);
891
+ const includeExpiredEdges = ctx.getNodeParameter('includeExpiredEdges', i, false);
892
+ const episodeCount = ctx.getNodeParameter('episodeCount', i, 5);
893
+ const traverser = new EpisodeTraverser_1.EpisodeTraverser();
894
+ const result = await traverser.traverseFromRecentEpisodes(storage, groupId, {
895
+ maxHops,
896
+ maxEntities,
897
+ includeExpiredEdges,
898
+ episodeCount,
899
+ });
900
+ returnData.push({
901
+ json: {
902
+ entity_count: result.entities.length,
903
+ edge_count: result.edges.length,
904
+ total_hops: result.total_hops,
905
+ seed_entities: result.seed_entities,
906
+ context: result.context,
907
+ entities: result.entities,
908
+ edges: result.edges,
909
+ paths: result.paths.map((p) => {
910
+ var _a, _b;
911
+ return ({
912
+ entity_uuid: p.entity.uuid,
913
+ entity_name: p.entity.name,
914
+ hop: p.hop,
915
+ via_edge_uuid: (_b = (_a = p.via_edge) === null || _a === void 0 ? void 0 : _a.uuid) !== null && _b !== void 0 ? _b : null,
916
+ });
917
+ }),
918
+ },
919
+ });
920
+ }
921
+ }
922
+ function parseAttributes(raw) {
923
+ if (typeof raw === 'object' && raw !== null)
924
+ return raw;
925
+ try {
926
+ return JSON.parse(raw || '{}');
927
+ }
928
+ catch {
929
+ return {};
930
+ }
931
+ }
932
+ //# sourceMappingURL=EngramExplorer.node.js.map