@exellix/graph-engine 6.0.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 (202) hide show
  1. package/.env.example +3 -0
  2. package/CHANGELOG.md +208 -0
  3. package/README.md +827 -0
  4. package/dist/src/errors/ExellixGraphError.d.ts +38 -0
  5. package/dist/src/errors/ExellixGraphError.js +21 -0
  6. package/dist/src/errors/exellixGraphErrorCodes.d.ts +31 -0
  7. package/dist/src/errors/exellixGraphErrorCodes.js +32 -0
  8. package/dist/src/index.d.ts +100 -0
  9. package/dist/src/index.js +75 -0
  10. package/dist/src/inspection/contractInspection.d.ts +21 -0
  11. package/dist/src/inspection/contractInspection.js +526 -0
  12. package/dist/src/inspection/contractTypes.d.ts +137 -0
  13. package/dist/src/inspection/contractTypes.js +1 -0
  14. package/dist/src/inspection/controlInspection.d.ts +22 -0
  15. package/dist/src/inspection/controlInspection.js +130 -0
  16. package/dist/src/inspection/graphInspection.d.ts +51 -0
  17. package/dist/src/inspection/graphInspection.js +467 -0
  18. package/dist/src/inspection/index.d.ts +21 -0
  19. package/dist/src/inspection/index.js +17 -0
  20. package/dist/src/inspection/nodeInspection.d.ts +42 -0
  21. package/dist/src/inspection/nodeInspection.js +474 -0
  22. package/dist/src/inspection/types.d.ts +321 -0
  23. package/dist/src/inspection/types.js +14 -0
  24. package/dist/src/inspection/validateAiTasksNodeExtensions.d.ts +12 -0
  25. package/dist/src/inspection/validateAiTasksNodeExtensions.js +119 -0
  26. package/dist/src/inspection/validateCatalogPlanning.d.ts +21 -0
  27. package/dist/src/inspection/validateCatalogPlanning.js +187 -0
  28. package/dist/src/integrations/ActivityTrackerIntegration.d.ts +86 -0
  29. package/dist/src/integrations/ActivityTrackerIntegration.js +134 -0
  30. package/dist/src/integrations/ActivixGraphRunIntegration.d.ts +34 -0
  31. package/dist/src/integrations/ActivixGraphRunIntegration.js +338 -0
  32. package/dist/src/integrations/ActivixNodeActivityIntegration.d.ts +33 -0
  33. package/dist/src/integrations/ActivixNodeActivityIntegration.js +220 -0
  34. package/dist/src/integrations/cataloxGraphCatalog.d.ts +21 -0
  35. package/dist/src/integrations/cataloxGraphCatalog.js +30 -0
  36. package/dist/src/integrations/createActivixExellixIntegration.d.ts +14 -0
  37. package/dist/src/integrations/createActivixExellixIntegration.js +16 -0
  38. package/dist/src/integrations/createActivixFromEnv.d.ts +31 -0
  39. package/dist/src/integrations/createActivixFromEnv.js +53 -0
  40. package/dist/src/loaders/FileGraphLoader.d.ts +23 -0
  41. package/dist/src/loaders/FileGraphLoader.js +31 -0
  42. package/dist/src/playground/PlaygroundReporter.d.ts +40 -0
  43. package/dist/src/playground/PlaygroundReporter.js +480 -0
  44. package/dist/src/playground/index.d.ts +1 -0
  45. package/dist/src/playground/index.js +1 -0
  46. package/dist/src/runtime/ExellixGraphRuntime.d.ts +263 -0
  47. package/dist/src/runtime/ExellixGraphRuntime.js +1716 -0
  48. package/dist/src/runtime/GraphEngine.d.ts +33 -0
  49. package/dist/src/runtime/GraphEngine.js +4 -0
  50. package/dist/src/runtime/aiTasksObservability.d.ts +6 -0
  51. package/dist/src/runtime/aiTasksObservability.js +37 -0
  52. package/dist/src/runtime/aiTasksStrategyPhases.d.ts +46 -0
  53. package/dist/src/runtime/aiTasksStrategyPhases.js +93 -0
  54. package/dist/src/runtime/applyAiTaskProfileWebScopingToNarrix.d.ts +17 -0
  55. package/dist/src/runtime/applyAiTaskProfileWebScopingToNarrix.js +46 -0
  56. package/dist/src/runtime/buildAiTasksRunTaskRequest.d.ts +67 -0
  57. package/dist/src/runtime/buildAiTasksRunTaskRequest.js +164 -0
  58. package/dist/src/runtime/buildRunLog.d.ts +27 -0
  59. package/dist/src/runtime/buildRunLog.js +234 -0
  60. package/dist/src/runtime/buildRunTaskTaskConfigurationForward.d.ts +9 -0
  61. package/dist/src/runtime/buildRunTaskTaskConfigurationForward.js +80 -0
  62. package/dist/src/runtime/buildTaskNodeJobContext.d.ts +11 -0
  63. package/dist/src/runtime/buildTaskNodeJobContext.js +30 -0
  64. package/dist/src/runtime/canonicalModelUsed.d.ts +6 -0
  65. package/dist/src/runtime/canonicalModelUsed.js +36 -0
  66. package/dist/src/runtime/contextualScope.d.ts +7 -0
  67. package/dist/src/runtime/contextualScope.js +121 -0
  68. package/dist/src/runtime/dataFiltersEvaluation.d.ts +60 -0
  69. package/dist/src/runtime/dataFiltersEvaluation.js +169 -0
  70. package/dist/src/runtime/deepMerge.d.ts +5 -0
  71. package/dist/src/runtime/deepMerge.js +22 -0
  72. package/dist/src/runtime/events.d.ts +92 -0
  73. package/dist/src/runtime/events.js +122 -0
  74. package/dist/src/runtime/executionMatrixHost.d.ts +98 -0
  75. package/dist/src/runtime/executionMatrixHost.js +134 -0
  76. package/dist/src/runtime/executionVariableBuckets.d.ts +67 -0
  77. package/dist/src/runtime/executionVariableBuckets.js +96 -0
  78. package/dist/src/runtime/finalizers/errors.d.ts +9 -0
  79. package/dist/src/runtime/finalizers/errors.js +10 -0
  80. package/dist/src/runtime/finalizers/executeFinalizer.d.ts +40 -0
  81. package/dist/src/runtime/finalizers/executeFinalizer.js +471 -0
  82. package/dist/src/runtime/finalizers/schema.d.ts +18 -0
  83. package/dist/src/runtime/finalizers/schema.js +63 -0
  84. package/dist/src/runtime/finalizers/validateFinalizer.d.ts +16 -0
  85. package/dist/src/runtime/finalizers/validateFinalizer.js +534 -0
  86. package/dist/src/runtime/graphDocumentFingerprint.d.ts +8 -0
  87. package/dist/src/runtime/graphDocumentFingerprint.js +21 -0
  88. package/dist/src/runtime/graphEngineMemoryPaths.d.ts +12 -0
  89. package/dist/src/runtime/graphEngineMemoryPaths.js +55 -0
  90. package/dist/src/runtime/graphResponseMapping.d.ts +23 -0
  91. package/dist/src/runtime/graphResponseMapping.js +156 -0
  92. package/dist/src/runtime/graphResponseMigration.d.ts +7 -0
  93. package/dist/src/runtime/graphResponseMigration.js +44 -0
  94. package/dist/src/runtime/graphRunExecutionSeed.d.ts +29 -0
  95. package/dist/src/runtime/graphRunExecutionSeed.js +61 -0
  96. package/dist/src/runtime/graphRunIdentity.d.ts +7 -0
  97. package/dist/src/runtime/graphRunIdentity.js +18 -0
  98. package/dist/src/runtime/localSkills/deterministicRule.d.ts +137 -0
  99. package/dist/src/runtime/localSkills/deterministicRule.js +196 -0
  100. package/dist/src/runtime/localSkills/index.d.ts +12 -0
  101. package/dist/src/runtime/localSkills/index.js +14 -0
  102. package/dist/src/runtime/localSkills/memorixItemToScopedOutput.d.ts +7 -0
  103. package/dist/src/runtime/localSkills/memorixItemToScopedOutput.js +104 -0
  104. package/dist/src/runtime/localSkills/memorixRuntime.d.ts +9 -0
  105. package/dist/src/runtime/localSkills/memorixRuntime.js +70 -0
  106. package/dist/src/runtime/localSkills/memorixScopedConfig.d.ts +16 -0
  107. package/dist/src/runtime/localSkills/memorixScopedConfig.js +18 -0
  108. package/dist/src/runtime/localSkills/scopedAnswerAssembler.d.ts +23 -0
  109. package/dist/src/runtime/localSkills/scopedAnswerAssembler.js +35 -0
  110. package/dist/src/runtime/localSkills/scopedAnswerFields.d.ts +12 -0
  111. package/dist/src/runtime/localSkills/scopedAnswerFields.js +66 -0
  112. package/dist/src/runtime/localSkills/scopedAnswerWriter.d.ts +32 -0
  113. package/dist/src/runtime/localSkills/scopedAnswerWriter.js +156 -0
  114. package/dist/src/runtime/localSkills/scopedDataReader.d.ts +47 -0
  115. package/dist/src/runtime/localSkills/scopedDataReader.js +89 -0
  116. package/dist/src/runtime/localSkills/utils.d.ts +12 -0
  117. package/dist/src/runtime/localSkills/utils.js +39 -0
  118. package/dist/src/runtime/materializeStructuredRunTaskInput.d.ts +9 -0
  119. package/dist/src/runtime/materializeStructuredRunTaskInput.js +34 -0
  120. package/dist/src/runtime/memory.d.ts +51 -0
  121. package/dist/src/runtime/memory.js +250 -0
  122. package/dist/src/runtime/mergeExellixGraphRuntimeInvocation.d.ts +18 -0
  123. package/dist/src/runtime/mergeExellixGraphRuntimeInvocation.js +32 -0
  124. package/dist/src/runtime/modelConfigSelection.d.ts +7 -0
  125. package/dist/src/runtime/modelConfigSelection.js +37 -0
  126. package/dist/src/runtime/narrixIngestEnv.d.ts +9 -0
  127. package/dist/src/runtime/narrixIngestEnv.js +18 -0
  128. package/dist/src/runtime/pathExpr.d.ts +36 -0
  129. package/dist/src/runtime/pathExpr.js +131 -0
  130. package/dist/src/runtime/predicates.d.ts +14 -0
  131. package/dist/src/runtime/predicates.js +86 -0
  132. package/dist/src/runtime/readTaskNodeInputsConfig.d.ts +23 -0
  133. package/dist/src/runtime/readTaskNodeInputsConfig.js +27 -0
  134. package/dist/src/runtime/resolveExecutionPipelineForTaskNode.d.ts +11 -0
  135. package/dist/src/runtime/resolveExecutionPipelineForTaskNode.js +93 -0
  136. package/dist/src/runtime/resolveGraphEngineMemoryPaths.d.ts +63 -0
  137. package/dist/src/runtime/resolveGraphEngineMemoryPaths.js +213 -0
  138. package/dist/src/runtime/resolveModelConfigForNode.d.ts +20 -0
  139. package/dist/src/runtime/resolveModelConfigForNode.js +69 -0
  140. package/dist/src/runtime/resolveNarrixForTaskNode.d.ts +14 -0
  141. package/dist/src/runtime/resolveNarrixForTaskNode.js +19 -0
  142. package/dist/src/runtime/resolveTaskKey.d.ts +11 -0
  143. package/dist/src/runtime/resolveTaskKey.js +28 -0
  144. package/dist/src/runtime/resolveTaskNodeInputs.d.ts +25 -0
  145. package/dist/src/runtime/resolveTaskNodeInputs.js +140 -0
  146. package/dist/src/runtime/runTaskAugments.d.ts +17 -0
  147. package/dist/src/runtime/runTaskAugments.js +37 -0
  148. package/dist/src/runtime/runTaskResponse.d.ts +4 -0
  149. package/dist/src/runtime/runTaskResponse.js +13 -0
  150. package/dist/src/runtime/runtimeObjects.d.ts +85 -0
  151. package/dist/src/runtime/runtimeObjects.js +50 -0
  152. package/dist/src/runtime/smartInputPaths.d.ts +13 -0
  153. package/dist/src/runtime/smartInputPaths.js +38 -0
  154. package/dist/src/runtime/stepRetry.d.ts +21 -0
  155. package/dist/src/runtime/stepRetry.js +238 -0
  156. package/dist/src/runtime/synthesizedContextPipeline.d.ts +12 -0
  157. package/dist/src/runtime/synthesizedContextPipeline.js +28 -0
  158. package/dist/src/runtime/taskNodeConditionsEvaluation.d.ts +27 -0
  159. package/dist/src/runtime/taskNodeConditionsEvaluation.js +140 -0
  160. package/dist/src/runtime/taskNodeMainReadiness.d.ts +45 -0
  161. package/dist/src/runtime/taskNodeMainReadiness.js +164 -0
  162. package/dist/src/runtime/taskNodeRunTaskPreflight.d.ts +89 -0
  163. package/dist/src/runtime/taskNodeRunTaskPreflight.js +204 -0
  164. package/dist/src/runtime/validateCanonicalGraphDocument.d.ts +25 -0
  165. package/dist/src/runtime/validateCanonicalGraphDocument.js +567 -0
  166. package/dist/src/runtime/variables.d.ts +2 -0
  167. package/dist/src/runtime/variables.js +1 -0
  168. package/dist/src/runtime/withTimeout.d.ts +5 -0
  169. package/dist/src/runtime/withTimeout.js +20 -0
  170. package/dist/src/types/aiTaskProfile.d.ts +41 -0
  171. package/dist/src/types/aiTaskProfile.js +6 -0
  172. package/dist/src/types/aiTasksDerivedTypes.d.ts +5 -0
  173. package/dist/src/types/aiTasksDerivedTypes.js +1 -0
  174. package/dist/src/types/events.d.ts +23 -0
  175. package/dist/src/types/events.js +1 -0
  176. package/dist/src/types/job.d.ts +9 -0
  177. package/dist/src/types/job.js +1 -0
  178. package/dist/src/types/narrix.d.ts +60 -0
  179. package/dist/src/types/narrix.js +1 -0
  180. package/dist/src/types/options.d.ts +122 -0
  181. package/dist/src/types/options.js +1 -0
  182. package/dist/src/types/refs.d.ts +747 -0
  183. package/dist/src/types/refs.js +12 -0
  184. package/dist/src/types/results.d.ts +103 -0
  185. package/dist/src/types/results.js +1 -0
  186. package/dist/src/types/runLog.d.ts +72 -0
  187. package/dist/src/types/runLog.js +18 -0
  188. package/dist/src/types/taskNodeConfiguration.d.ts +95 -0
  189. package/dist/src/types/taskNodeConfiguration.js +3 -0
  190. package/dist/src/util/packageVersion.d.ts +2 -0
  191. package/dist/src/util/packageVersion.js +12 -0
  192. package/dist/testkit/RealTasksClient.d.ts +16 -0
  193. package/dist/testkit/RealTasksClient.js +143 -0
  194. package/dist/testkit/depGraphEngineFactory.d.ts +6 -0
  195. package/dist/testkit/depGraphEngineFactory.js +54 -0
  196. package/dist/testkit/exellixRuntimeObjects.d.ts +7 -0
  197. package/dist/testkit/exellixRuntimeObjects.js +25 -0
  198. package/dist/testkit/inMemoryGraphLoader.d.ts +6 -0
  199. package/dist/testkit/inMemoryGraphLoader.js +12 -0
  200. package/dist/testkit/index.d.ts +4 -0
  201. package/dist/testkit/index.js +4 -0
  202. package/package.json +70 -0
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Integration helper for @athenices/ai-activities-tracking
3
+ *
4
+ * This module provides a bridge between exellix-graphs events and ActivityTracker.
5
+ * It listens to graph and node execution events and forwards them to ActivityTracker.
6
+ *
7
+ * Usage:
8
+ * ```typescript
9
+ * import { ActivityTracker } from '@athenices/ai-activities-tracking';
10
+ * import { createActivityTrackerIntegration } from '@exellix/graph-engine/integrations';
11
+ *
12
+ * const tracker = new ActivityTracker({ // config });
13
+ * await tracker.init();
14
+ *
15
+ * const integration = createActivityTrackerIntegration(tracker);
16
+ *
17
+ * // Use integration.eventEmitter with createExellixGraphRuntime (5.x canonical API).
18
+ * const runtime = createExellixGraphRuntime({
19
+ * // ... graphLoader, tasksClient, engineFactory, ...
20
+ * eventEmitter: integration.eventEmitter,
21
+ * });
22
+ * ```
23
+ */
24
+ import { EventEmitter } from '../runtime/events.js';
25
+ /**
26
+ * ActivityTracker interface (type-only to avoid requiring the package at build time)
27
+ */
28
+ export interface ActivityTrackerLike {
29
+ logGraphStart(metadata: {
30
+ jobId: string;
31
+ taskId?: string;
32
+ graphId: string;
33
+ agentId?: string;
34
+ startTime: number;
35
+ graphDefinition?: any;
36
+ input?: any;
37
+ }): Promise<{
38
+ activityId?: string;
39
+ }>;
40
+ logGraphComplete(metadata: {
41
+ jobId: string;
42
+ taskId?: string;
43
+ graphId: string;
44
+ endTime: number;
45
+ status: 'completed';
46
+ output?: any;
47
+ nodesExecuted?: number;
48
+ finalMemory?: any;
49
+ }): Promise<void>;
50
+ logGraphFail(error: any, metadata: {
51
+ jobId: string;
52
+ taskId?: string;
53
+ graphId: string;
54
+ endTime: number;
55
+ finalMemory?: any;
56
+ }): Promise<void>;
57
+ logNodeStart(metadata: {
58
+ jobId: string;
59
+ taskId?: string;
60
+ graphId: string;
61
+ nodeId: string;
62
+ startTime: number;
63
+ skillKey?: string;
64
+ nodeDefinition?: any;
65
+ input?: any;
66
+ }): Promise<{
67
+ activityId?: string;
68
+ }>;
69
+ logNodeComplete(activityId: string, metadata: {
70
+ endTime: number;
71
+ status: 'completed';
72
+ output?: any;
73
+ memoryAfter?: any;
74
+ }): Promise<void>;
75
+ logNodeFail(activityId: string, error: any, metadata: {
76
+ endTime: number;
77
+ memoryAfter?: any;
78
+ }): Promise<void>;
79
+ }
80
+ /**
81
+ * Creates an event emitter that forwards events to ActivityTracker
82
+ */
83
+ export declare function createActivityTrackerIntegration(tracker: ActivityTrackerLike): {
84
+ eventEmitter: EventEmitter;
85
+ nodeActivityIds: Map<string, string>;
86
+ };
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Integration helper for @athenices/ai-activities-tracking
3
+ *
4
+ * This module provides a bridge between exellix-graphs events and ActivityTracker.
5
+ * It listens to graph and node execution events and forwards them to ActivityTracker.
6
+ *
7
+ * Usage:
8
+ * ```typescript
9
+ * import { ActivityTracker } from '@athenices/ai-activities-tracking';
10
+ * import { createActivityTrackerIntegration } from '@exellix/graph-engine/integrations';
11
+ *
12
+ * const tracker = new ActivityTracker({ // config });
13
+ * await tracker.init();
14
+ *
15
+ * const integration = createActivityTrackerIntegration(tracker);
16
+ *
17
+ * // Use integration.eventEmitter with createExellixGraphRuntime (5.x canonical API).
18
+ * const runtime = createExellixGraphRuntime({
19
+ * // ... graphLoader, tasksClient, engineFactory, ...
20
+ * eventEmitter: integration.eventEmitter,
21
+ * });
22
+ * ```
23
+ */
24
+ /**
25
+ * Creates an event emitter that forwards events to ActivityTracker
26
+ */
27
+ export function createActivityTrackerIntegration(tracker) {
28
+ // Store node activity IDs for updates (node:complete and node:fail update the same record)
29
+ // Use composite key: "graphId:nodeId" since nodeId might not be unique across graphs
30
+ const nodeActivityIds = new Map();
31
+ const eventEmitter = {
32
+ emit(event) {
33
+ // Handle events asynchronously to avoid blocking graph execution
34
+ setImmediate(async () => {
35
+ try {
36
+ if (event.type === 'graph:start') {
37
+ const graphEvent = event;
38
+ await tracker.logGraphStart({
39
+ jobId: graphEvent.jobId,
40
+ taskId: graphEvent.taskId,
41
+ graphId: graphEvent.graphId,
42
+ agentId: graphEvent.data?.agentId,
43
+ startTime: graphEvent.timestamp,
44
+ graphDefinition: graphEvent.data?.graphDefinition,
45
+ input: graphEvent.data?.input,
46
+ });
47
+ }
48
+ else if (event.type === 'graph:complete') {
49
+ const graphEvent = event;
50
+ await tracker.logGraphComplete({
51
+ jobId: graphEvent.jobId,
52
+ taskId: graphEvent.taskId,
53
+ graphId: graphEvent.graphId,
54
+ endTime: graphEvent.timestamp,
55
+ status: 'completed',
56
+ output: graphEvent.data?.output,
57
+ nodesExecuted: graphEvent.data?.nodesExecuted,
58
+ finalMemory: graphEvent.data?.finalMemory,
59
+ });
60
+ }
61
+ else if (event.type === 'graph:fail') {
62
+ const graphEvent = event;
63
+ await tracker.logGraphFail(graphEvent.data?.error, {
64
+ jobId: graphEvent.jobId,
65
+ taskId: graphEvent.taskId,
66
+ graphId: graphEvent.graphId,
67
+ endTime: graphEvent.timestamp,
68
+ finalMemory: graphEvent.data?.finalMemory,
69
+ });
70
+ }
71
+ else if (event.type === 'node:start') {
72
+ const nodeEvent = event;
73
+ const nodeActivity = await tracker.logNodeStart({
74
+ jobId: nodeEvent.jobId,
75
+ taskId: nodeEvent.taskId,
76
+ graphId: nodeEvent.graphId,
77
+ nodeId: nodeEvent.nodeId,
78
+ startTime: nodeEvent.timestamp,
79
+ skillKey: nodeEvent.skillKey,
80
+ nodeDefinition: nodeEvent.data?.nodeDefinition || nodeEvent.node,
81
+ input: nodeEvent.data?.input,
82
+ });
83
+ // Store activityId for later updates (when tracker returns one)
84
+ const nodeKey = `${nodeEvent.graphId}:${nodeEvent.nodeId}:${nodeEvent.taskId}`;
85
+ if (nodeActivity.activityId)
86
+ nodeActivityIds.set(nodeKey, nodeActivity.activityId);
87
+ }
88
+ else if (event.type === 'node:complete') {
89
+ const nodeEvent = event;
90
+ const nodeKey = `${nodeEvent.graphId}:${nodeEvent.nodeId}:${nodeEvent.taskId}`;
91
+ const activityId = nodeActivityIds.get(nodeKey);
92
+ if (activityId) {
93
+ await tracker.logNodeComplete(activityId, {
94
+ endTime: nodeEvent.timestamp,
95
+ status: 'completed',
96
+ output: nodeEvent.data?.output || nodeEvent.result,
97
+ memoryAfter: nodeEvent.data?.memoryAfter,
98
+ });
99
+ // Clean up after successful update
100
+ nodeActivityIds.delete(nodeKey);
101
+ }
102
+ else {
103
+ console.warn(`Node activity not found for graphId: ${nodeEvent.graphId}, nodeId: ${nodeEvent.nodeId}`);
104
+ }
105
+ }
106
+ else if (event.type === 'node:fail') {
107
+ const nodeEvent = event;
108
+ const nodeKey = `${nodeEvent.graphId}:${nodeEvent.nodeId}:${nodeEvent.taskId}`;
109
+ const activityId = nodeActivityIds.get(nodeKey);
110
+ if (activityId) {
111
+ await tracker.logNodeFail(activityId, nodeEvent.error || nodeEvent.data?.error, {
112
+ endTime: nodeEvent.timestamp,
113
+ memoryAfter: nodeEvent.data?.memoryAfter,
114
+ });
115
+ // Clean up after successful update
116
+ nodeActivityIds.delete(nodeKey);
117
+ }
118
+ else {
119
+ console.warn(`Node activity not found for graphId: ${nodeEvent.graphId}, nodeId: ${nodeEvent.nodeId}`);
120
+ }
121
+ }
122
+ }
123
+ catch (error) {
124
+ // Log error but don't throw - activity tracking failures should not break graph execution
125
+ console.error('Activity tracking error (non-fatal):', error);
126
+ }
127
+ });
128
+ },
129
+ };
130
+ return {
131
+ eventEmitter,
132
+ nodeActivityIds,
133
+ };
134
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Bridges exellix-graph graph lifecycle events to @x12i/activix.
3
+ *
4
+ * Listens for `graph:start`, `graph:complete`, and `graph:fail`.
5
+ */
6
+ import type { Activix } from '@x12i/activix';
7
+ import type { EventEmitter } from '../runtime/events.js';
8
+ export interface CreateActivixGraphRunIntegrationOptions {
9
+ /** Activix collection role (passed as `options.collection` to start/complete/fail). */
10
+ collection?: string;
11
+ /**
12
+ * When true, persist the full graph execution response object under `outer.output.data.response`
13
+ * (can be very large).
14
+ *
15
+ * Default: false (persist `outer.output.response` as finalOutput + keep structured node data under `outer.output.data`).
16
+ */
17
+ includeFullResponse?: boolean;
18
+ /**
19
+ * When true, persist memory snapshots under outer.memory.start/end (can be large).
20
+ * Default: false (persist summaries only).
21
+ */
22
+ includeMemorySnapshots?: boolean;
23
+ }
24
+ /**
25
+ * Returns an EventEmitter that persists graph lifecycle rows via Activix.
26
+ * Correlates start → complete/fail via an in-memory map keyed by `jobId:graphId:taskId`
27
+ * (host job id + graph id + engine-generated graph-run UUID).
28
+ *
29
+ * On `graph:start`, `outer.input` contains only bounded **`inputSummary`** / **`requestSummary`**
30
+ * (JSON-serializable); raw event input/request objects are not copied to Activix.
31
+ */
32
+ export declare function createActivixGraphRunIntegration(ax: Activix, options?: CreateActivixGraphRunIntegrationOptions): {
33
+ eventEmitter: EventEmitter;
34
+ };
@@ -0,0 +1,338 @@
1
+ function summarizeValueForRecord(value) {
2
+ if (value === null || value === undefined) {
3
+ return { shape: 'empty' };
4
+ }
5
+ if (typeof value === 'string') {
6
+ return { shape: 'string', length: value.length };
7
+ }
8
+ if (typeof value === 'object' && !Array.isArray(value)) {
9
+ const keys = Object.keys(value);
10
+ return { shape: 'object', keyCount: keys.length, keysSample: keys.slice(0, 40) };
11
+ }
12
+ if (Array.isArray(value)) {
13
+ return { shape: 'array', length: value.length };
14
+ }
15
+ return { shape: typeof value };
16
+ }
17
+ function getGraphNodeCount(graphDefinition) {
18
+ if (!graphDefinition)
19
+ return undefined;
20
+ if (Array.isArray(graphDefinition.nodes))
21
+ return graphDefinition.nodes.length;
22
+ if (graphDefinition.nodes && typeof graphDefinition.nodes === 'object') {
23
+ return Array.isArray(graphDefinition.nodes) ? graphDefinition.nodes.length : Object.values(graphDefinition.nodes).length;
24
+ }
25
+ return undefined;
26
+ }
27
+ function extractErrorMessage(error) {
28
+ if (error instanceof Error)
29
+ return error.message;
30
+ if (typeof error === 'string')
31
+ return error;
32
+ if (typeof error === 'object' && error) {
33
+ if ('message' in error)
34
+ return String(error.message ?? '');
35
+ if ('error' in error)
36
+ return extractErrorMessage(error.error);
37
+ }
38
+ return String(error ?? 'unknown error');
39
+ }
40
+ function isPlainObject(v) {
41
+ if (typeof v !== 'object' || v === null || Array.isArray(v))
42
+ return false;
43
+ const proto = Object.getPrototypeOf(v);
44
+ return proto === Object.prototype || proto === null;
45
+ }
46
+ /** Max nesting depth when summarizing arrays / nested structures for Activix. */
47
+ const ACTIVIX_SUMMARY_MAX_DEPTH = 4;
48
+ /** First N array elements get a bounded per-element summary. */
49
+ const ACTIVIX_ARRAY_SAMPLE_LEN = 3;
50
+ /** First N own keys on plain objects get shallow per-key summaries. */
51
+ const ACTIVIX_OBJECT_PREVIEW_KEY_COUNT = 20;
52
+ const ACTIVIX_STRING_PREVIEW_MAX = 64;
53
+ /**
54
+ * Bounded, JSON-serializable summary for `graph:start` Activix payloads.
55
+ * Aligns with {@link summarizeValueForRecord} for leaves; adds shallow previews and array samples.
56
+ * Does not copy functions, class instances, streams, or circular structures as raw values.
57
+ */
58
+ function summarizeForActivix(value, depth = 0, seen = new WeakSet()) {
59
+ if (depth > ACTIVIX_SUMMARY_MAX_DEPTH) {
60
+ return { shape: 'truncated', reason: 'maxDepth' };
61
+ }
62
+ if (value === null || value === undefined) {
63
+ return { shape: 'empty' };
64
+ }
65
+ const t = typeof value;
66
+ if (t === 'bigint') {
67
+ return { shape: 'bigint', hint: String(value).slice(0, 32) };
68
+ }
69
+ if (t === 'symbol') {
70
+ return { shape: 'symbol' };
71
+ }
72
+ if (t === 'function') {
73
+ const fn = value;
74
+ return { shape: 'function', name: fn.name || '' };
75
+ }
76
+ if (t === 'boolean' || t === 'number') {
77
+ return { shape: t, value: value };
78
+ }
79
+ if (t === 'string') {
80
+ const s = value;
81
+ return {
82
+ shape: 'string',
83
+ length: s.length,
84
+ preview: s.length <= ACTIVIX_STRING_PREVIEW_MAX ? s : `${s.slice(0, ACTIVIX_STRING_PREVIEW_MAX)}…`,
85
+ };
86
+ }
87
+ if (t !== 'object') {
88
+ return { shape: t };
89
+ }
90
+ const obj = value;
91
+ if (seen.has(obj)) {
92
+ return { shape: 'circular' };
93
+ }
94
+ if (value instanceof Date) {
95
+ return { shape: 'date', iso: value.toISOString() };
96
+ }
97
+ if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {
98
+ return { shape: 'buffer', length: value.length };
99
+ }
100
+ if (ArrayBuffer.isView(value) && !(value instanceof DataView)) {
101
+ const view = value;
102
+ return { shape: 'typedArray', ctor: value.constructor?.name ?? 'ArrayBufferView', byteLength: view.byteLength };
103
+ }
104
+ if (value instanceof Map) {
105
+ return { shape: 'map', size: value.size };
106
+ }
107
+ if (value instanceof Set) {
108
+ return { shape: 'set', size: value.size };
109
+ }
110
+ if (value instanceof RegExp) {
111
+ return { shape: 'regexp', source: value.source.slice(0, 80) };
112
+ }
113
+ const maybeThen = value.then;
114
+ if (typeof maybeThen === 'function') {
115
+ return { shape: 'promise' };
116
+ }
117
+ if (typeof value.pipe === 'function') {
118
+ return { shape: 'streamLike' };
119
+ }
120
+ if (Array.isArray(value)) {
121
+ seen.add(obj);
122
+ const len = value.length;
123
+ const sample = value.slice(0, ACTIVIX_ARRAY_SAMPLE_LEN).map((el) => summarizeForActivix(el, depth + 1, seen));
124
+ seen.delete(obj);
125
+ return { shape: 'array', length: len, sample };
126
+ }
127
+ if (isPlainObject(value)) {
128
+ seen.add(obj);
129
+ const keys = Object.keys(value);
130
+ const out = {
131
+ shape: 'object',
132
+ keyCount: keys.length,
133
+ keysSample: keys.slice(0, 40),
134
+ };
135
+ const preview = {};
136
+ for (let i = 0; i < Math.min(keys.length, ACTIVIX_OBJECT_PREVIEW_KEY_COUNT); i++) {
137
+ const k = keys[i];
138
+ const v = value[k];
139
+ if (v === null || v === undefined) {
140
+ preview[k] = { shape: 'empty' };
141
+ }
142
+ else if (typeof v === 'string') {
143
+ const str = v;
144
+ preview[k] = {
145
+ shape: 'string',
146
+ length: str.length,
147
+ preview: str.length <= 32 ? str : `${str.slice(0, 32)}…`,
148
+ };
149
+ }
150
+ else if (typeof v === 'number' || typeof v === 'boolean') {
151
+ preview[k] = { shape: typeof v, value: v };
152
+ }
153
+ else if (typeof v === 'bigint') {
154
+ preview[k] = { shape: 'bigint', hint: String(v).slice(0, 16) };
155
+ }
156
+ else {
157
+ preview[k] = summarizeForActivix(v, depth + 1, seen);
158
+ }
159
+ }
160
+ if (Object.keys(preview).length > 0) {
161
+ out.shallowPreview = preview;
162
+ }
163
+ seen.delete(obj);
164
+ return out;
165
+ }
166
+ return { shape: 'instance', ctor: value.constructor?.name ?? 'Object' };
167
+ }
168
+ /**
169
+ * Returns an EventEmitter that persists graph lifecycle rows via Activix.
170
+ * Correlates start → complete/fail via an in-memory map keyed by `jobId:graphId:taskId`
171
+ * (host job id + graph id + engine-generated graph-run UUID).
172
+ *
173
+ * On `graph:start`, `outer.input` contains only bounded **`inputSummary`** / **`requestSummary`**
174
+ * (JSON-serializable); raw event input/request objects are not copied to Activix.
175
+ */
176
+ export function createActivixGraphRunIntegration(ax, options) {
177
+ const collection = options?.collection;
178
+ const includeFullResponse = options?.includeFullResponse === true;
179
+ const includeMemorySnapshots = options?.includeMemorySnapshots === true;
180
+ const colOpts = collection ? { collection } : undefined;
181
+ const graphRecordIds = new Map();
182
+ let initPromise = null;
183
+ function ensureInit() {
184
+ if (!initPromise) {
185
+ initPromise = ax.init().catch((err) => {
186
+ initPromise = null;
187
+ throw err;
188
+ });
189
+ }
190
+ return initPromise;
191
+ }
192
+ const eventEmitter = {
193
+ emit(event) {
194
+ setImmediate(async () => {
195
+ try {
196
+ if (event.type === 'graph:start') {
197
+ await ensureInit();
198
+ const graphEvent = event;
199
+ const data = graphEvent.data;
200
+ const key = `${graphEvent.jobId}:${graphEvent.graphId}:${graphEvent.taskId}`;
201
+ const inputVariables = data?.input?.variables;
202
+ const inputVariableKeys = inputVariables ? Object.keys(inputVariables) : [];
203
+ const agentId = data?.agentId;
204
+ const jobType = data?.jobType;
205
+ const graphNodeCount = getGraphNodeCount(data?.graphDefinition);
206
+ // Activix v5+ correlation object is `runContext` and must include `sessionId`.
207
+ // This SDK does not have a separate session id today, so we align it to `jobId`.
208
+ const runContext = {
209
+ sessionId: graphEvent.jobId,
210
+ jobId: graphEvent.jobId,
211
+ taskId: graphEvent.taskId,
212
+ graphId: graphEvent.graphId,
213
+ agentId,
214
+ ...(jobType != null ? { jobType } : {}),
215
+ };
216
+ const outerMemoryStart = data?.memoryStart;
217
+ const outerMetadata = {
218
+ kind: 'exellix-graph-run',
219
+ jobId: graphEvent.jobId,
220
+ taskId: graphEvent.taskId,
221
+ graphId: graphEvent.graphId,
222
+ agentId,
223
+ ...(jobType != null ? { jobType } : {}),
224
+ graphNodeCount,
225
+ inputVariableKeys,
226
+ eventTimestamp: graphEvent.timestamp,
227
+ };
228
+ const base = {
229
+ kind: 'exellix-graph-run',
230
+ jobId: graphEvent.jobId,
231
+ taskId: graphEvent.taskId,
232
+ graphId: graphEvent.graphId,
233
+ agentId,
234
+ ...(jobType != null ? { jobType } : {}),
235
+ graphNodeCount,
236
+ inputVariableKeys,
237
+ eventTimestamp: graphEvent.timestamp,
238
+ runContext,
239
+ outer: {
240
+ input: {
241
+ inputSummary: summarizeForActivix(data?.input),
242
+ requestSummary: summarizeForActivix(data?.request),
243
+ },
244
+ output: undefined,
245
+ memory: {
246
+ ...(includeMemorySnapshots ? { start: outerMemoryStart } : {}),
247
+ },
248
+ metadata: outerMetadata,
249
+ },
250
+ };
251
+ const { recordId } = await ax.startRecord(base, colOpts);
252
+ graphRecordIds.set(key, recordId);
253
+ }
254
+ else if (event.type === 'graph:complete') {
255
+ await ensureInit();
256
+ const graphEvent = event;
257
+ const key = `${graphEvent.jobId}:${graphEvent.graphId}:${graphEvent.taskId}`;
258
+ const recordId = graphRecordIds.get(key);
259
+ if (!recordId)
260
+ return;
261
+ const data = graphEvent.data;
262
+ const outerResponse = data?.response;
263
+ const finalOutput = outerResponse?.finalOutput;
264
+ const finalOutputSummary = summarizeValueForRecord(finalOutput);
265
+ const responseSummary = summarizeValueForRecord(outerResponse);
266
+ const outerMemoryEnd = data?.finalMemory;
267
+ await ax.completeRecord(recordId, {
268
+ completedAt: graphEvent.timestamp,
269
+ nodesExecuted: data?.nodesExecuted,
270
+ outputSummary: finalOutputSummary,
271
+ outer: {
272
+ output: {
273
+ // Canonical business response: finalOutput only.
274
+ response: finalOutput,
275
+ finalOutputSummary,
276
+ // Keep rich execution details under `data` (not the canonical response).
277
+ data: {
278
+ responseSummary,
279
+ nodes: outerResponse?.nodes,
280
+ execution: outerResponse?.execution,
281
+ jobMemory: outerResponse?.jobMemory,
282
+ error: outerResponse?.error,
283
+ ...(includeFullResponse ? { response: outerResponse } : {}),
284
+ },
285
+ },
286
+ memory: {
287
+ ...(includeMemorySnapshots ? { end: outerMemoryEnd } : {}),
288
+ },
289
+ },
290
+ }, colOpts);
291
+ graphRecordIds.delete(key);
292
+ }
293
+ else if (event.type === 'graph:fail') {
294
+ await ensureInit();
295
+ const graphEvent = event;
296
+ const key = `${graphEvent.jobId}:${graphEvent.graphId}:${graphEvent.taskId}`;
297
+ const recordId = graphRecordIds.get(key);
298
+ if (!recordId)
299
+ return;
300
+ const data = graphEvent.data;
301
+ const errorMessage = extractErrorMessage(data?.error ?? graphEvent.data?.error);
302
+ const outerResponse = data?.response;
303
+ const finalOutput = outerResponse?.finalOutput;
304
+ const finalOutputSummary = summarizeValueForRecord(finalOutput);
305
+ const responseSummary = summarizeValueForRecord(outerResponse);
306
+ const outerMemoryEnd = data?.finalMemory;
307
+ await ax.failRecord(recordId, errorMessage, {
308
+ failedAt: graphEvent.timestamp,
309
+ outer: {
310
+ output: {
311
+ // Canonical business response (may be undefined on failure).
312
+ response: finalOutput,
313
+ finalOutputSummary,
314
+ data: {
315
+ responseSummary,
316
+ nodes: outerResponse?.nodes,
317
+ execution: outerResponse?.execution,
318
+ jobMemory: outerResponse?.jobMemory,
319
+ error: outerResponse?.error,
320
+ ...(includeFullResponse ? { response: outerResponse } : {}),
321
+ },
322
+ },
323
+ memory: {
324
+ ...(includeMemorySnapshots ? { end: outerMemoryEnd } : {}),
325
+ },
326
+ },
327
+ }, colOpts);
328
+ graphRecordIds.delete(key);
329
+ }
330
+ }
331
+ catch (error) {
332
+ console.error('Activix graph run activity error (non-fatal):', error);
333
+ }
334
+ });
335
+ },
336
+ };
337
+ return { eventEmitter };
338
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Bridges exellix-graph node execution events to @x12i/activix (start → complete / fail records).
3
+ *
4
+ * Listens for `node:start`, `node:complete`, and `node:fail` only. Graph-level events are ignored.
5
+ */
6
+ import type { Activix } from '@x12i/activix';
7
+ import type { EventEmitter } from '../runtime/events.js';
8
+ export interface CreateActivixNodeActivityIntegrationOptions {
9
+ /** Activix collection role (passed as `options.collection` to start/complete/fail). */
10
+ collection?: string;
11
+ /**
12
+ * When true, attach lightweight input hints (variable keys, execution keys from jobMemory) on start records.
13
+ */
14
+ includeInputSnapshot?: boolean;
15
+ /**
16
+ * When true, attempt to extract NARRIX triage outcome fields from `node:complete` output and persist them as `narrixSummary`.
17
+ *
18
+ * This is intentionally best-effort and schema-light: it only extracts fields that exist on the node output.
19
+ */
20
+ extractNarrixOutcome?: boolean;
21
+ }
22
+ /**
23
+ * Returns an EventEmitter that persists node lifecycle rows via Activix.
24
+ * Correlates start → complete/fail using `graphId:nodeId:taskId` (includes engine-generated graph-run `taskId`).
25
+ */
26
+ export declare function createActivixNodeActivityIntegration(ax: Activix, options?: CreateActivixNodeActivityIntegrationOptions): {
27
+ eventEmitter: EventEmitter;
28
+ /**
29
+ * In-flight record creation promises.
30
+ * We store promises so `node:complete` can await the `node:start` insert if it races.
31
+ */
32
+ nodeRecordIds: Map<string, Promise<string>>;
33
+ };