@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.
- package/.env.example +3 -0
- package/CHANGELOG.md +208 -0
- package/README.md +827 -0
- package/dist/src/errors/ExellixGraphError.d.ts +38 -0
- package/dist/src/errors/ExellixGraphError.js +21 -0
- package/dist/src/errors/exellixGraphErrorCodes.d.ts +31 -0
- package/dist/src/errors/exellixGraphErrorCodes.js +32 -0
- package/dist/src/index.d.ts +100 -0
- package/dist/src/index.js +75 -0
- package/dist/src/inspection/contractInspection.d.ts +21 -0
- package/dist/src/inspection/contractInspection.js +526 -0
- package/dist/src/inspection/contractTypes.d.ts +137 -0
- package/dist/src/inspection/contractTypes.js +1 -0
- package/dist/src/inspection/controlInspection.d.ts +22 -0
- package/dist/src/inspection/controlInspection.js +130 -0
- package/dist/src/inspection/graphInspection.d.ts +51 -0
- package/dist/src/inspection/graphInspection.js +467 -0
- package/dist/src/inspection/index.d.ts +21 -0
- package/dist/src/inspection/index.js +17 -0
- package/dist/src/inspection/nodeInspection.d.ts +42 -0
- package/dist/src/inspection/nodeInspection.js +474 -0
- package/dist/src/inspection/types.d.ts +321 -0
- package/dist/src/inspection/types.js +14 -0
- package/dist/src/inspection/validateAiTasksNodeExtensions.d.ts +12 -0
- package/dist/src/inspection/validateAiTasksNodeExtensions.js +119 -0
- package/dist/src/inspection/validateCatalogPlanning.d.ts +21 -0
- package/dist/src/inspection/validateCatalogPlanning.js +187 -0
- package/dist/src/integrations/ActivityTrackerIntegration.d.ts +86 -0
- package/dist/src/integrations/ActivityTrackerIntegration.js +134 -0
- package/dist/src/integrations/ActivixGraphRunIntegration.d.ts +34 -0
- package/dist/src/integrations/ActivixGraphRunIntegration.js +338 -0
- package/dist/src/integrations/ActivixNodeActivityIntegration.d.ts +33 -0
- package/dist/src/integrations/ActivixNodeActivityIntegration.js +220 -0
- package/dist/src/integrations/cataloxGraphCatalog.d.ts +21 -0
- package/dist/src/integrations/cataloxGraphCatalog.js +30 -0
- package/dist/src/integrations/createActivixExellixIntegration.d.ts +14 -0
- package/dist/src/integrations/createActivixExellixIntegration.js +16 -0
- package/dist/src/integrations/createActivixFromEnv.d.ts +31 -0
- package/dist/src/integrations/createActivixFromEnv.js +53 -0
- package/dist/src/loaders/FileGraphLoader.d.ts +23 -0
- package/dist/src/loaders/FileGraphLoader.js +31 -0
- package/dist/src/playground/PlaygroundReporter.d.ts +40 -0
- package/dist/src/playground/PlaygroundReporter.js +480 -0
- package/dist/src/playground/index.d.ts +1 -0
- package/dist/src/playground/index.js +1 -0
- package/dist/src/runtime/ExellixGraphRuntime.d.ts +263 -0
- package/dist/src/runtime/ExellixGraphRuntime.js +1716 -0
- package/dist/src/runtime/GraphEngine.d.ts +33 -0
- package/dist/src/runtime/GraphEngine.js +4 -0
- package/dist/src/runtime/aiTasksObservability.d.ts +6 -0
- package/dist/src/runtime/aiTasksObservability.js +37 -0
- package/dist/src/runtime/aiTasksStrategyPhases.d.ts +46 -0
- package/dist/src/runtime/aiTasksStrategyPhases.js +93 -0
- package/dist/src/runtime/applyAiTaskProfileWebScopingToNarrix.d.ts +17 -0
- package/dist/src/runtime/applyAiTaskProfileWebScopingToNarrix.js +46 -0
- package/dist/src/runtime/buildAiTasksRunTaskRequest.d.ts +67 -0
- package/dist/src/runtime/buildAiTasksRunTaskRequest.js +164 -0
- package/dist/src/runtime/buildRunLog.d.ts +27 -0
- package/dist/src/runtime/buildRunLog.js +234 -0
- package/dist/src/runtime/buildRunTaskTaskConfigurationForward.d.ts +9 -0
- package/dist/src/runtime/buildRunTaskTaskConfigurationForward.js +80 -0
- package/dist/src/runtime/buildTaskNodeJobContext.d.ts +11 -0
- package/dist/src/runtime/buildTaskNodeJobContext.js +30 -0
- package/dist/src/runtime/canonicalModelUsed.d.ts +6 -0
- package/dist/src/runtime/canonicalModelUsed.js +36 -0
- package/dist/src/runtime/contextualScope.d.ts +7 -0
- package/dist/src/runtime/contextualScope.js +121 -0
- package/dist/src/runtime/dataFiltersEvaluation.d.ts +60 -0
- package/dist/src/runtime/dataFiltersEvaluation.js +169 -0
- package/dist/src/runtime/deepMerge.d.ts +5 -0
- package/dist/src/runtime/deepMerge.js +22 -0
- package/dist/src/runtime/events.d.ts +92 -0
- package/dist/src/runtime/events.js +122 -0
- package/dist/src/runtime/executionMatrixHost.d.ts +98 -0
- package/dist/src/runtime/executionMatrixHost.js +134 -0
- package/dist/src/runtime/executionVariableBuckets.d.ts +67 -0
- package/dist/src/runtime/executionVariableBuckets.js +96 -0
- package/dist/src/runtime/finalizers/errors.d.ts +9 -0
- package/dist/src/runtime/finalizers/errors.js +10 -0
- package/dist/src/runtime/finalizers/executeFinalizer.d.ts +40 -0
- package/dist/src/runtime/finalizers/executeFinalizer.js +471 -0
- package/dist/src/runtime/finalizers/schema.d.ts +18 -0
- package/dist/src/runtime/finalizers/schema.js +63 -0
- package/dist/src/runtime/finalizers/validateFinalizer.d.ts +16 -0
- package/dist/src/runtime/finalizers/validateFinalizer.js +534 -0
- package/dist/src/runtime/graphDocumentFingerprint.d.ts +8 -0
- package/dist/src/runtime/graphDocumentFingerprint.js +21 -0
- package/dist/src/runtime/graphEngineMemoryPaths.d.ts +12 -0
- package/dist/src/runtime/graphEngineMemoryPaths.js +55 -0
- package/dist/src/runtime/graphResponseMapping.d.ts +23 -0
- package/dist/src/runtime/graphResponseMapping.js +156 -0
- package/dist/src/runtime/graphResponseMigration.d.ts +7 -0
- package/dist/src/runtime/graphResponseMigration.js +44 -0
- package/dist/src/runtime/graphRunExecutionSeed.d.ts +29 -0
- package/dist/src/runtime/graphRunExecutionSeed.js +61 -0
- package/dist/src/runtime/graphRunIdentity.d.ts +7 -0
- package/dist/src/runtime/graphRunIdentity.js +18 -0
- package/dist/src/runtime/localSkills/deterministicRule.d.ts +137 -0
- package/dist/src/runtime/localSkills/deterministicRule.js +196 -0
- package/dist/src/runtime/localSkills/index.d.ts +12 -0
- package/dist/src/runtime/localSkills/index.js +14 -0
- package/dist/src/runtime/localSkills/memorixItemToScopedOutput.d.ts +7 -0
- package/dist/src/runtime/localSkills/memorixItemToScopedOutput.js +104 -0
- package/dist/src/runtime/localSkills/memorixRuntime.d.ts +9 -0
- package/dist/src/runtime/localSkills/memorixRuntime.js +70 -0
- package/dist/src/runtime/localSkills/memorixScopedConfig.d.ts +16 -0
- package/dist/src/runtime/localSkills/memorixScopedConfig.js +18 -0
- package/dist/src/runtime/localSkills/scopedAnswerAssembler.d.ts +23 -0
- package/dist/src/runtime/localSkills/scopedAnswerAssembler.js +35 -0
- package/dist/src/runtime/localSkills/scopedAnswerFields.d.ts +12 -0
- package/dist/src/runtime/localSkills/scopedAnswerFields.js +66 -0
- package/dist/src/runtime/localSkills/scopedAnswerWriter.d.ts +32 -0
- package/dist/src/runtime/localSkills/scopedAnswerWriter.js +156 -0
- package/dist/src/runtime/localSkills/scopedDataReader.d.ts +47 -0
- package/dist/src/runtime/localSkills/scopedDataReader.js +89 -0
- package/dist/src/runtime/localSkills/utils.d.ts +12 -0
- package/dist/src/runtime/localSkills/utils.js +39 -0
- package/dist/src/runtime/materializeStructuredRunTaskInput.d.ts +9 -0
- package/dist/src/runtime/materializeStructuredRunTaskInput.js +34 -0
- package/dist/src/runtime/memory.d.ts +51 -0
- package/dist/src/runtime/memory.js +250 -0
- package/dist/src/runtime/mergeExellixGraphRuntimeInvocation.d.ts +18 -0
- package/dist/src/runtime/mergeExellixGraphRuntimeInvocation.js +32 -0
- package/dist/src/runtime/modelConfigSelection.d.ts +7 -0
- package/dist/src/runtime/modelConfigSelection.js +37 -0
- package/dist/src/runtime/narrixIngestEnv.d.ts +9 -0
- package/dist/src/runtime/narrixIngestEnv.js +18 -0
- package/dist/src/runtime/pathExpr.d.ts +36 -0
- package/dist/src/runtime/pathExpr.js +131 -0
- package/dist/src/runtime/predicates.d.ts +14 -0
- package/dist/src/runtime/predicates.js +86 -0
- package/dist/src/runtime/readTaskNodeInputsConfig.d.ts +23 -0
- package/dist/src/runtime/readTaskNodeInputsConfig.js +27 -0
- package/dist/src/runtime/resolveExecutionPipelineForTaskNode.d.ts +11 -0
- package/dist/src/runtime/resolveExecutionPipelineForTaskNode.js +93 -0
- package/dist/src/runtime/resolveGraphEngineMemoryPaths.d.ts +63 -0
- package/dist/src/runtime/resolveGraphEngineMemoryPaths.js +213 -0
- package/dist/src/runtime/resolveModelConfigForNode.d.ts +20 -0
- package/dist/src/runtime/resolveModelConfigForNode.js +69 -0
- package/dist/src/runtime/resolveNarrixForTaskNode.d.ts +14 -0
- package/dist/src/runtime/resolveNarrixForTaskNode.js +19 -0
- package/dist/src/runtime/resolveTaskKey.d.ts +11 -0
- package/dist/src/runtime/resolveTaskKey.js +28 -0
- package/dist/src/runtime/resolveTaskNodeInputs.d.ts +25 -0
- package/dist/src/runtime/resolveTaskNodeInputs.js +140 -0
- package/dist/src/runtime/runTaskAugments.d.ts +17 -0
- package/dist/src/runtime/runTaskAugments.js +37 -0
- package/dist/src/runtime/runTaskResponse.d.ts +4 -0
- package/dist/src/runtime/runTaskResponse.js +13 -0
- package/dist/src/runtime/runtimeObjects.d.ts +85 -0
- package/dist/src/runtime/runtimeObjects.js +50 -0
- package/dist/src/runtime/smartInputPaths.d.ts +13 -0
- package/dist/src/runtime/smartInputPaths.js +38 -0
- package/dist/src/runtime/stepRetry.d.ts +21 -0
- package/dist/src/runtime/stepRetry.js +238 -0
- package/dist/src/runtime/synthesizedContextPipeline.d.ts +12 -0
- package/dist/src/runtime/synthesizedContextPipeline.js +28 -0
- package/dist/src/runtime/taskNodeConditionsEvaluation.d.ts +27 -0
- package/dist/src/runtime/taskNodeConditionsEvaluation.js +140 -0
- package/dist/src/runtime/taskNodeMainReadiness.d.ts +45 -0
- package/dist/src/runtime/taskNodeMainReadiness.js +164 -0
- package/dist/src/runtime/taskNodeRunTaskPreflight.d.ts +89 -0
- package/dist/src/runtime/taskNodeRunTaskPreflight.js +204 -0
- package/dist/src/runtime/validateCanonicalGraphDocument.d.ts +25 -0
- package/dist/src/runtime/validateCanonicalGraphDocument.js +567 -0
- package/dist/src/runtime/variables.d.ts +2 -0
- package/dist/src/runtime/variables.js +1 -0
- package/dist/src/runtime/withTimeout.d.ts +5 -0
- package/dist/src/runtime/withTimeout.js +20 -0
- package/dist/src/types/aiTaskProfile.d.ts +41 -0
- package/dist/src/types/aiTaskProfile.js +6 -0
- package/dist/src/types/aiTasksDerivedTypes.d.ts +5 -0
- package/dist/src/types/aiTasksDerivedTypes.js +1 -0
- package/dist/src/types/events.d.ts +23 -0
- package/dist/src/types/events.js +1 -0
- package/dist/src/types/job.d.ts +9 -0
- package/dist/src/types/job.js +1 -0
- package/dist/src/types/narrix.d.ts +60 -0
- package/dist/src/types/narrix.js +1 -0
- package/dist/src/types/options.d.ts +122 -0
- package/dist/src/types/options.js +1 -0
- package/dist/src/types/refs.d.ts +747 -0
- package/dist/src/types/refs.js +12 -0
- package/dist/src/types/results.d.ts +103 -0
- package/dist/src/types/results.js +1 -0
- package/dist/src/types/runLog.d.ts +72 -0
- package/dist/src/types/runLog.js +18 -0
- package/dist/src/types/taskNodeConfiguration.d.ts +95 -0
- package/dist/src/types/taskNodeConfiguration.js +3 -0
- package/dist/src/util/packageVersion.d.ts +2 -0
- package/dist/src/util/packageVersion.js +12 -0
- package/dist/testkit/RealTasksClient.d.ts +16 -0
- package/dist/testkit/RealTasksClient.js +143 -0
- package/dist/testkit/depGraphEngineFactory.d.ts +6 -0
- package/dist/testkit/depGraphEngineFactory.js +54 -0
- package/dist/testkit/exellixRuntimeObjects.d.ts +7 -0
- package/dist/testkit/exellixRuntimeObjects.js +25 -0
- package/dist/testkit/inMemoryGraphLoader.d.ts +6 -0
- package/dist/testkit/inMemoryGraphLoader.js +12 -0
- package/dist/testkit/index.d.ts +4 -0
- package/dist/testkit/index.js +4 -0
- package/package.json +70 -0
|
@@ -0,0 +1,220 @@
|
|
|
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
|
+
function summarizeValueForRecord(value) {
|
|
7
|
+
if (value === null || value === undefined) {
|
|
8
|
+
return { shape: 'empty' };
|
|
9
|
+
}
|
|
10
|
+
if (typeof value === 'string') {
|
|
11
|
+
return { shape: 'string', length: value.length };
|
|
12
|
+
}
|
|
13
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
14
|
+
const keys = Object.keys(value);
|
|
15
|
+
return { shape: 'object', keyCount: keys.length, keysSample: keys.slice(0, 40) };
|
|
16
|
+
}
|
|
17
|
+
if (Array.isArray(value)) {
|
|
18
|
+
return { shape: 'array', length: value.length };
|
|
19
|
+
}
|
|
20
|
+
return { shape: typeof value };
|
|
21
|
+
}
|
|
22
|
+
function isPlainObject(v) {
|
|
23
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Returns an EventEmitter that persists node lifecycle rows via Activix.
|
|
27
|
+
* Correlates start → complete/fail using `graphId:nodeId:taskId` (includes engine-generated graph-run `taskId`).
|
|
28
|
+
*/
|
|
29
|
+
export function createActivixNodeActivityIntegration(ax, options) {
|
|
30
|
+
const collection = options?.collection;
|
|
31
|
+
const includeInputSnapshot = options?.includeInputSnapshot === true;
|
|
32
|
+
const extractNarrixOutcome = options?.extractNarrixOutcome === true;
|
|
33
|
+
const colOpts = collection ? { collection } : undefined;
|
|
34
|
+
const nodeRecordIds = new Map();
|
|
35
|
+
let initPromise = null;
|
|
36
|
+
function ensureInit() {
|
|
37
|
+
if (!initPromise) {
|
|
38
|
+
initPromise = ax.init().catch((err) => {
|
|
39
|
+
initPromise = null;
|
|
40
|
+
throw err;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return initPromise;
|
|
44
|
+
}
|
|
45
|
+
const eventEmitter = {
|
|
46
|
+
emit(event) {
|
|
47
|
+
setImmediate(async () => {
|
|
48
|
+
try {
|
|
49
|
+
if (event.type === 'node:start') {
|
|
50
|
+
const nodeEvent = event;
|
|
51
|
+
const input = nodeEvent.data?.input;
|
|
52
|
+
const jobType = nodeEvent.data != null && typeof nodeEvent.data === 'object' && 'jobType' in nodeEvent.data
|
|
53
|
+
? nodeEvent.data.jobType
|
|
54
|
+
: undefined;
|
|
55
|
+
// Activix v5+ correlation object is `runContext` and must include `sessionId`.
|
|
56
|
+
// This SDK does not have a separate session id today, so we align it to `jobId`.
|
|
57
|
+
const runContext = {
|
|
58
|
+
sessionId: nodeEvent.jobId,
|
|
59
|
+
jobId: nodeEvent.jobId,
|
|
60
|
+
taskId: nodeEvent.taskId,
|
|
61
|
+
graphId: nodeEvent.graphId,
|
|
62
|
+
nodeId: nodeEvent.nodeId,
|
|
63
|
+
skillKey: nodeEvent.skillKey,
|
|
64
|
+
...(jobType != null ? { jobType } : {}),
|
|
65
|
+
};
|
|
66
|
+
const outerInput = isPlainObject(input) ? input : {};
|
|
67
|
+
const outerRequest = nodeEvent.data?.input?.request;
|
|
68
|
+
const outerMemoryStart = nodeEvent.data?.input?.memoryStart;
|
|
69
|
+
const outerMetadata = {
|
|
70
|
+
kind: 'exellix-graph-node',
|
|
71
|
+
jobId: nodeEvent.jobId,
|
|
72
|
+
taskId: nodeEvent.taskId,
|
|
73
|
+
graphId: nodeEvent.graphId,
|
|
74
|
+
nodeId: nodeEvent.nodeId,
|
|
75
|
+
skillKey: nodeEvent.skillKey,
|
|
76
|
+
...(jobType != null ? { jobType } : {}),
|
|
77
|
+
eventTimestamp: nodeEvent.timestamp,
|
|
78
|
+
};
|
|
79
|
+
const base = {
|
|
80
|
+
kind: 'exellix-graph-node',
|
|
81
|
+
jobId: nodeEvent.jobId,
|
|
82
|
+
taskId: nodeEvent.taskId,
|
|
83
|
+
graphId: nodeEvent.graphId,
|
|
84
|
+
nodeId: nodeEvent.nodeId,
|
|
85
|
+
skillKey: nodeEvent.skillKey,
|
|
86
|
+
...(jobType != null ? { jobType } : {}),
|
|
87
|
+
eventTimestamp: nodeEvent.timestamp,
|
|
88
|
+
runContext,
|
|
89
|
+
outer: {
|
|
90
|
+
input: {
|
|
91
|
+
...outerInput,
|
|
92
|
+
request: outerRequest,
|
|
93
|
+
},
|
|
94
|
+
output: undefined,
|
|
95
|
+
memory: {
|
|
96
|
+
start: outerMemoryStart,
|
|
97
|
+
},
|
|
98
|
+
metadata: outerMetadata,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
if (includeInputSnapshot && input && typeof input === 'object') {
|
|
102
|
+
const vars = input.variables;
|
|
103
|
+
if (vars && typeof vars === 'object') {
|
|
104
|
+
base.inputVariableKeys = Object.keys(vars);
|
|
105
|
+
if (isPlainObject(base.outer?.metadata)) {
|
|
106
|
+
base.outer.metadata.inputVariableKeys = base.inputVariableKeys;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const jm = input.jobMemory;
|
|
110
|
+
const ex = jm?.execution;
|
|
111
|
+
if (ex != null && typeof ex === 'object') {
|
|
112
|
+
base.executionKeys = Object.keys(ex);
|
|
113
|
+
if (isPlainObject(base.outer?.metadata)) {
|
|
114
|
+
base.outer.metadata.executionKeys = base.executionKeys;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const key = `${nodeEvent.graphId}:${nodeEvent.nodeId}:${nodeEvent.taskId}`;
|
|
119
|
+
// Start the record insert immediately (promise inserted into the map synchronously),
|
|
120
|
+
// but defer actual DB work until `ax.init()` is ready.
|
|
121
|
+
const recordPromise = (async () => {
|
|
122
|
+
await ensureInit();
|
|
123
|
+
const { recordId } = await ax.startRecord(base, colOpts);
|
|
124
|
+
return recordId;
|
|
125
|
+
})();
|
|
126
|
+
nodeRecordIds.set(key, recordPromise);
|
|
127
|
+
await recordPromise;
|
|
128
|
+
}
|
|
129
|
+
else if (event.type === 'node:complete') {
|
|
130
|
+
const nodeEvent = event;
|
|
131
|
+
const key = `${nodeEvent.graphId}:${nodeEvent.nodeId}:${nodeEvent.taskId}`;
|
|
132
|
+
const recordPromise = nodeRecordIds.get(key);
|
|
133
|
+
if (!recordPromise) {
|
|
134
|
+
console.warn(`Activix node activity: no start record for graphId=${nodeEvent.graphId} nodeId=${nodeEvent.nodeId}`);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const output = nodeEvent.data?.output ?? nodeEvent.result;
|
|
138
|
+
const { narrixSummary } = extractNarrixOutcome ? extractNarrixSummary(nodeEvent) : { narrixSummary: undefined };
|
|
139
|
+
const outputSummary = summarizeValueForRecord(output);
|
|
140
|
+
const outerResponse = nodeEvent.data?.response;
|
|
141
|
+
const outerMemoryEnd = nodeEvent.data?.memoryAfter;
|
|
142
|
+
const recordId = await recordPromise;
|
|
143
|
+
await ax.completeRecord(recordId, {
|
|
144
|
+
completedAt: nodeEvent.timestamp,
|
|
145
|
+
outputSummary,
|
|
146
|
+
...(narrixSummary ? { narrixSummary } : {}),
|
|
147
|
+
outer: {
|
|
148
|
+
output: {
|
|
149
|
+
response: outerResponse,
|
|
150
|
+
},
|
|
151
|
+
memory: {
|
|
152
|
+
end: outerMemoryEnd,
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
}, colOpts);
|
|
156
|
+
nodeRecordIds.delete(key);
|
|
157
|
+
}
|
|
158
|
+
else if (event.type === 'node:fail') {
|
|
159
|
+
const nodeEvent = event;
|
|
160
|
+
const key = `${nodeEvent.graphId}:${nodeEvent.nodeId}:${nodeEvent.taskId}`;
|
|
161
|
+
const recordPromise = nodeRecordIds.get(key);
|
|
162
|
+
if (!recordPromise) {
|
|
163
|
+
console.warn(`Activix node activity: no start record for graphId=${nodeEvent.graphId} nodeId=${nodeEvent.nodeId}`);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const err = nodeEvent.error ?? nodeEvent.data?.error;
|
|
167
|
+
const message = err instanceof Error
|
|
168
|
+
? err.message
|
|
169
|
+
: typeof err === 'object' && err && 'message' in err
|
|
170
|
+
? String(err.message)
|
|
171
|
+
: String(err ?? 'unknown error');
|
|
172
|
+
const outerResponse = nodeEvent.data?.response;
|
|
173
|
+
const outerMemoryEnd = nodeEvent.data?.memoryAfter;
|
|
174
|
+
const recordId = await recordPromise;
|
|
175
|
+
await ax.failRecord(recordId, message, {
|
|
176
|
+
failedAt: nodeEvent.timestamp,
|
|
177
|
+
outer: {
|
|
178
|
+
output: {
|
|
179
|
+
response: outerResponse,
|
|
180
|
+
},
|
|
181
|
+
memory: {
|
|
182
|
+
end: outerMemoryEnd,
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
}, colOpts);
|
|
186
|
+
nodeRecordIds.delete(key);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
console.error('Activix node activity error (non-fatal):', error);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
return { eventEmitter, nodeRecordIds };
|
|
196
|
+
}
|
|
197
|
+
function extractNarrixSummary(nodeEvent) {
|
|
198
|
+
const node = nodeEvent.node;
|
|
199
|
+
const output = nodeEvent.data?.output ?? nodeEvent.result;
|
|
200
|
+
const questionId = node?.taskConfiguration?.narrix?.questionId;
|
|
201
|
+
const datasetId = nodeEvent.data?.memoryAfter?.jobMemory?.execution?.input?.metadata?.datasetId;
|
|
202
|
+
if (output == null || typeof output !== 'object') {
|
|
203
|
+
return { narrixSummary: undefined };
|
|
204
|
+
}
|
|
205
|
+
const outObj = output;
|
|
206
|
+
const hasShortAnswer = 'shortAnswer' in outObj;
|
|
207
|
+
const hasEvidence = 'evidence' in outObj;
|
|
208
|
+
const hasFullAnswer = 'fullAnswer' in outObj;
|
|
209
|
+
if (!hasShortAnswer && !hasFullAnswer && !hasEvidence) {
|
|
210
|
+
return { narrixSummary: undefined };
|
|
211
|
+
}
|
|
212
|
+
const narrixSummary = {
|
|
213
|
+
...(datasetId ? { datasetId } : {}),
|
|
214
|
+
...(questionId ? { questionId } : {}),
|
|
215
|
+
...(outObj.shortAnswer !== undefined ? { shortAnswer: outObj.shortAnswer } : {}),
|
|
216
|
+
...(outObj.fullAnswer !== undefined ? { fullAnswer: outObj.fullAnswer } : {}),
|
|
217
|
+
...(outObj.evidence !== undefined ? { evidence: outObj.evidence } : {}),
|
|
218
|
+
};
|
|
219
|
+
return { narrixSummary };
|
|
220
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Catalox, CataloxContext } from '@x12i/catalox';
|
|
2
|
+
import type { Graph } from '../types/refs.js';
|
|
3
|
+
/**
|
|
4
|
+
* Issue from {@link validateGraphPlanningCatalogDescriptorsInCatalox}.
|
|
5
|
+
*/
|
|
6
|
+
export type GraphCatalogValidationIssue = {
|
|
7
|
+
code: 'descriptor_missing';
|
|
8
|
+
message: string;
|
|
9
|
+
catalogId?: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* For each planning `catalogId` referenced on the graph (scoped-question + discovery-definition),
|
|
13
|
+
* checks that a Catalox catalog descriptor exists for the tenant `ctx.appId`.
|
|
14
|
+
*
|
|
15
|
+
* Callers supply a {@link Catalox} instance (for example from their own Firebase / env wiring
|
|
16
|
+
* or via helpers re-exported from `@exellix/ai-tasks`).
|
|
17
|
+
*/
|
|
18
|
+
export declare function validateGraphPlanningCatalogDescriptorsInCatalox(graph: Graph, catalox: Catalox, ctx: CataloxContext): Promise<{
|
|
19
|
+
ok: boolean;
|
|
20
|
+
issues: GraphCatalogValidationIssue[];
|
|
21
|
+
}>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { getGraphCatalogs } from '../inspection/graphInspection.js';
|
|
2
|
+
import { assertCanonicalGraphDocument } from '../runtime/validateCanonicalGraphDocument.js';
|
|
3
|
+
/**
|
|
4
|
+
* For each planning `catalogId` referenced on the graph (scoped-question + discovery-definition),
|
|
5
|
+
* checks that a Catalox catalog descriptor exists for the tenant `ctx.appId`.
|
|
6
|
+
*
|
|
7
|
+
* Callers supply a {@link Catalox} instance (for example from their own Firebase / env wiring
|
|
8
|
+
* or via helpers re-exported from `@exellix/ai-tasks`).
|
|
9
|
+
*/
|
|
10
|
+
export async function validateGraphPlanningCatalogDescriptorsInCatalox(graph, catalox, ctx) {
|
|
11
|
+
assertCanonicalGraphDocument(graph, { graphId: graph?.id });
|
|
12
|
+
const cats = getGraphCatalogs(graph);
|
|
13
|
+
const ids = new Set();
|
|
14
|
+
for (const id of cats.scopedQuestionCatalogIds)
|
|
15
|
+
ids.add(id);
|
|
16
|
+
for (const id of cats.discoveryDefinitionCatalogIds)
|
|
17
|
+
ids.add(id);
|
|
18
|
+
const issues = [];
|
|
19
|
+
for (const catalogId of ids) {
|
|
20
|
+
const desc = await catalox.getCatalogDescriptor(ctx, catalogId);
|
|
21
|
+
if (desc == null) {
|
|
22
|
+
issues.push({
|
|
23
|
+
code: 'descriptor_missing',
|
|
24
|
+
message: `No Catalox catalog descriptor for catalogId "${catalogId}" (appId=${String(ctx.appId ?? '')})`,
|
|
25
|
+
catalogId,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return { ok: issues.length === 0, issues };
|
|
30
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Activix } from '@x12i/activix';
|
|
2
|
+
import type { EventEmitter } from '../runtime/events.js';
|
|
3
|
+
import { type CreateActivixNodeActivityIntegrationOptions } from './ActivixNodeActivityIntegration.js';
|
|
4
|
+
import { type CreateActivixGraphRunIntegrationOptions } from './ActivixGraphRunIntegration.js';
|
|
5
|
+
export interface CreateActivixExellixIntegrationOptions {
|
|
6
|
+
activixNodeActivity?: CreateActivixNodeActivityIntegrationOptions;
|
|
7
|
+
activixGraphRun?: CreateActivixGraphRunIntegrationOptions;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Combines node + graph lifecycle persistence into a single `eventEmitter`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createActivixExellixIntegration(ax: Activix, options?: CreateActivixExellixIntegrationOptions): {
|
|
13
|
+
eventEmitter: EventEmitter | undefined;
|
|
14
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { composeEventEmitters } from '../runtime/events.js';
|
|
2
|
+
import { createActivixNodeActivityIntegration, } from './ActivixNodeActivityIntegration.js';
|
|
3
|
+
import { createActivixGraphRunIntegration, } from './ActivixGraphRunIntegration.js';
|
|
4
|
+
/**
|
|
5
|
+
* Combines node + graph lifecycle persistence into a single `eventEmitter`.
|
|
6
|
+
*/
|
|
7
|
+
export function createActivixExellixIntegration(ax, options) {
|
|
8
|
+
const node = options?.activixNodeActivity
|
|
9
|
+
? createActivixNodeActivityIntegration(ax, options.activixNodeActivity)
|
|
10
|
+
: undefined;
|
|
11
|
+
const graph = options?.activixGraphRun
|
|
12
|
+
? createActivixGraphRunIntegration(ax, options.activixGraphRun)
|
|
13
|
+
: undefined;
|
|
14
|
+
const eventEmitter = composeEventEmitters(node?.eventEmitter, graph?.eventEmitter);
|
|
15
|
+
return { eventEmitter };
|
|
16
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Activix } from '@x12i/activix';
|
|
2
|
+
export interface CreateActivixFromEnvOptions {
|
|
3
|
+
/** When true, throws if required env vars are missing. Defaults to true. */
|
|
4
|
+
strict?: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* MongoDB collection names for exellix-graph Activix streams. Must match the `collection` option passed to
|
|
8
|
+
* `createActivixGraphRunIntegration` / `createActivixNodeActivityIntegration` (Activix resolves by **name**, not an abstract role).
|
|
9
|
+
*
|
|
10
|
+
* Override with `ACTIVIX_GRAPH_RUNS_COLLECTION` / `ACTIVIX_NODE_ACTIVITY_COLLECTION`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveActivixExellixCollectionNamesFromEnv(): {
|
|
13
|
+
graphRuns: string;
|
|
14
|
+
nodeActivity: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Creates a configured Activix instance from env.
|
|
18
|
+
*
|
|
19
|
+
* Uses:
|
|
20
|
+
* - `MONGO_URI` (or `MONGO_LOGS_URI`) for connection
|
|
21
|
+
* - Database selection is handled by Activix/environment resolution.
|
|
22
|
+
*
|
|
23
|
+
* Collections: two named streams (defaults `exellix-graph-runs`, `exellix-node-activity`). Use
|
|
24
|
+
* {@link resolveActivixExellixCollectionNamesFromEnv} when wiring integrations so names stay aligned.
|
|
25
|
+
*
|
|
26
|
+
* Activix 7+ multi-collection mode requires `defaultCollection`. We set it to the node-activity stream
|
|
27
|
+
* so node-activity integrations (and runtimes from `createExellixGraphRuntime`) that omit `collection`
|
|
28
|
+
* still land on the intended stream; graph-run integrations should pass `collection` explicitly when
|
|
29
|
+
* using both streams.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createActivixFromEnv(options?: CreateActivixFromEnvOptions): Activix;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Activix } from '@x12i/activix';
|
|
2
|
+
function requiredEnv(name, strict) {
|
|
3
|
+
const v = process.env[name];
|
|
4
|
+
if (v && v.trim().length > 0)
|
|
5
|
+
return v;
|
|
6
|
+
if (strict)
|
|
7
|
+
throw new Error(`Missing required env var: ${name}`);
|
|
8
|
+
return '';
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* MongoDB collection names for exellix-graph Activix streams. Must match the `collection` option passed to
|
|
12
|
+
* `createActivixGraphRunIntegration` / `createActivixNodeActivityIntegration` (Activix resolves by **name**, not an abstract role).
|
|
13
|
+
*
|
|
14
|
+
* Override with `ACTIVIX_GRAPH_RUNS_COLLECTION` / `ACTIVIX_NODE_ACTIVITY_COLLECTION`.
|
|
15
|
+
*/
|
|
16
|
+
export function resolveActivixExellixCollectionNamesFromEnv() {
|
|
17
|
+
const g = process.env.ACTIVIX_GRAPH_RUNS_COLLECTION?.trim();
|
|
18
|
+
const n = process.env.ACTIVIX_NODE_ACTIVITY_COLLECTION?.trim();
|
|
19
|
+
return {
|
|
20
|
+
graphRuns: g && g.length > 0 ? g : 'exellix-graph-runs',
|
|
21
|
+
nodeActivity: n && n.length > 0 ? n : 'exellix-node-activity',
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Creates a configured Activix instance from env.
|
|
26
|
+
*
|
|
27
|
+
* Uses:
|
|
28
|
+
* - `MONGO_URI` (or `MONGO_LOGS_URI`) for connection
|
|
29
|
+
* - Database selection is handled by Activix/environment resolution.
|
|
30
|
+
*
|
|
31
|
+
* Collections: two named streams (defaults `exellix-graph-runs`, `exellix-node-activity`). Use
|
|
32
|
+
* {@link resolveActivixExellixCollectionNamesFromEnv} when wiring integrations so names stay aligned.
|
|
33
|
+
*
|
|
34
|
+
* Activix 7+ multi-collection mode requires `defaultCollection`. We set it to the node-activity stream
|
|
35
|
+
* so node-activity integrations (and runtimes from `createExellixGraphRuntime`) that omit `collection`
|
|
36
|
+
* still land on the intended stream; graph-run integrations should pass `collection` explicitly when
|
|
37
|
+
* using both streams.
|
|
38
|
+
*/
|
|
39
|
+
export function createActivixFromEnv(options) {
|
|
40
|
+
const strict = options?.strict !== false;
|
|
41
|
+
const mongoUri = process.env.MONGO_LOGS_URI && process.env.MONGO_LOGS_URI.trim().length > 0
|
|
42
|
+
? process.env.MONGO_LOGS_URI
|
|
43
|
+
: requiredEnv('MONGO_URI', strict);
|
|
44
|
+
const { graphRuns: graphRunsCollection, nodeActivity: nodeActivityCollection } = resolveActivixExellixCollectionNamesFromEnv();
|
|
45
|
+
return new Activix({
|
|
46
|
+
mongoUri,
|
|
47
|
+
defaultCollection: nodeActivityCollection,
|
|
48
|
+
collections: [
|
|
49
|
+
{ name: graphRunsCollection },
|
|
50
|
+
{ name: nodeActivityCollection },
|
|
51
|
+
],
|
|
52
|
+
});
|
|
53
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph loader that loads graph JSON from the filesystem.
|
|
3
|
+
* Use for loading NARRIX triage graphs from a graphs/ directory.
|
|
4
|
+
*/
|
|
5
|
+
import type { Graph } from '../types/refs.js';
|
|
6
|
+
import type { GraphLoader as RuntimeGraphLoader } from '../runtime/ExellixGraphRuntime.js';
|
|
7
|
+
export interface FileGraphLoaderOptions {
|
|
8
|
+
/** Base directory for graph JSON files (default: process.cwd() + '/graphs') */
|
|
9
|
+
baseDir?: string;
|
|
10
|
+
/** Optional map of graphId -> relative path from baseDir (default: graphId + '.json') */
|
|
11
|
+
graphIdToPath?: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Loads a graph by graphId from the filesystem.
|
|
15
|
+
* - If graphIdToPath[graphId] is set, uses that path relative to baseDir.
|
|
16
|
+
* - Otherwise resolves to baseDir/graphId.json.
|
|
17
|
+
*/
|
|
18
|
+
export declare class FileGraphLoader implements RuntimeGraphLoader {
|
|
19
|
+
private baseDir;
|
|
20
|
+
private graphIdToPath;
|
|
21
|
+
constructor(options?: FileGraphLoaderOptions);
|
|
22
|
+
loadGraph(graphId: string): Promise<Graph>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph loader that loads graph JSON from the filesystem.
|
|
3
|
+
* Use for loading NARRIX triage graphs from a graphs/ directory.
|
|
4
|
+
*/
|
|
5
|
+
import { readFile } from 'node:fs/promises';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
/**
|
|
8
|
+
* Loads a graph by graphId from the filesystem.
|
|
9
|
+
* - If graphIdToPath[graphId] is set, uses that path relative to baseDir.
|
|
10
|
+
* - Otherwise resolves to baseDir/graphId.json.
|
|
11
|
+
*/
|
|
12
|
+
export class FileGraphLoader {
|
|
13
|
+
baseDir;
|
|
14
|
+
graphIdToPath;
|
|
15
|
+
constructor(options = {}) {
|
|
16
|
+
this.baseDir =
|
|
17
|
+
options.baseDir ??
|
|
18
|
+
path.join(process.cwd(), 'graphs');
|
|
19
|
+
this.graphIdToPath = options.graphIdToPath ?? {};
|
|
20
|
+
}
|
|
21
|
+
async loadGraph(graphId) {
|
|
22
|
+
const relativePath = this.graphIdToPath[graphId] ?? `${graphId}.json`;
|
|
23
|
+
const fullPath = path.resolve(this.baseDir, relativePath);
|
|
24
|
+
const raw = await readFile(fullPath, 'utf-8');
|
|
25
|
+
const graph = JSON.parse(raw);
|
|
26
|
+
if (graph.id !== graphId && !this.graphIdToPath[graphId]) {
|
|
27
|
+
graph.id = graphId;
|
|
28
|
+
}
|
|
29
|
+
return graph;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playground reporter: collects execution steps and in-memory debug artifacts
|
|
3
|
+
* for full visibility (graph start, plan rounds, node request/response/outputMapping, graph end).
|
|
4
|
+
*
|
|
5
|
+
* Each reporter instance corresponds to ONE graph execution.
|
|
6
|
+
* It never writes to the filesystem; callers can inspect artifacts via getArtifacts/getDebugSnapshot.
|
|
7
|
+
*/
|
|
8
|
+
export interface CreatePlaygroundReporterOptions {
|
|
9
|
+
/** Short run id for report header (e.g. folder name) */
|
|
10
|
+
runId?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface PlaygroundReporter {
|
|
13
|
+
step(name: string, data?: Record<string, unknown>): void;
|
|
14
|
+
getSteps(): PlaygroundStep[];
|
|
15
|
+
getArtifacts(): PlaygroundDebugArtifact[];
|
|
16
|
+
getDebugSnapshot(): PlaygroundDebugSnapshot;
|
|
17
|
+
getMarkdown(): string;
|
|
18
|
+
}
|
|
19
|
+
export interface PlaygroundStep {
|
|
20
|
+
name: string;
|
|
21
|
+
data?: Record<string, unknown>;
|
|
22
|
+
ts: number;
|
|
23
|
+
}
|
|
24
|
+
export type PlaygroundDebugArtifactKind = 'request' | 'response';
|
|
25
|
+
export interface PlaygroundDebugArtifact {
|
|
26
|
+
/** Stable in-memory identifier for UI/debug lookup. This is not a file path. */
|
|
27
|
+
artifactId: string;
|
|
28
|
+
kind: PlaygroundDebugArtifactKind;
|
|
29
|
+
nodeId: string;
|
|
30
|
+
stepNumber?: number;
|
|
31
|
+
payload: unknown;
|
|
32
|
+
ts: number;
|
|
33
|
+
}
|
|
34
|
+
export interface PlaygroundDebugSnapshot {
|
|
35
|
+
runId?: string;
|
|
36
|
+
steps: PlaygroundStep[];
|
|
37
|
+
artifacts: PlaygroundDebugArtifact[];
|
|
38
|
+
markdown: string;
|
|
39
|
+
}
|
|
40
|
+
export declare function createPlaygroundReporter(options?: CreatePlaygroundReporterOptions): PlaygroundReporter;
|