@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,67 @@
|
|
|
1
|
+
import type { Graph, GraphNode, Job } from '../types/refs.js';
|
|
2
|
+
import { type GraphEngineMemoryResolutionRoot } from './resolveGraphEngineMemoryPaths.js';
|
|
3
|
+
export type ExecutionVariableBuckets = {
|
|
4
|
+
/** Job / graph run scope: model + runtime + legacy job envelope. */
|
|
5
|
+
jobVariables: Record<string, unknown>;
|
|
6
|
+
/** Task / node scope: `node.variables` + runtime override. */
|
|
7
|
+
taskVariables: Record<string, unknown>;
|
|
8
|
+
};
|
|
9
|
+
/** Reads the two variable buckets from live execution memory. */
|
|
10
|
+
export declare function readExecutionVariableBuckets(execution: Record<string, unknown>): ExecutionVariableBuckets;
|
|
11
|
+
/**
|
|
12
|
+
* Seeds job-scoped template variables on `executionMemory` (mirrors runtime like `input` / `inputs`).
|
|
13
|
+
*
|
|
14
|
+
* Graph and job scopes share one bucket:
|
|
15
|
+
* `execution.jobVariables` ← `model.variables` + `variables.__graphModel` + `job.jobVariables`
|
|
16
|
+
* + `runtime.jobVariables` + `runtime.variables` (later layers win).
|
|
17
|
+
*/
|
|
18
|
+
export declare function seedGraphVariableBucketsOnExecution(args: {
|
|
19
|
+
execution: Record<string, unknown>;
|
|
20
|
+
graph?: Graph;
|
|
21
|
+
job?: Job;
|
|
22
|
+
runtimeVariables?: Record<string, unknown>;
|
|
23
|
+
runtimeJobVariables?: Record<string, unknown>;
|
|
24
|
+
}): void;
|
|
25
|
+
/**
|
|
26
|
+
* Sets `execution.taskVariables` for the current node: `node.variables` + optional runtime override.
|
|
27
|
+
*/
|
|
28
|
+
export declare function mirrorTaskVariablesOnExecution(args: {
|
|
29
|
+
execution: Record<string, unknown>;
|
|
30
|
+
node?: GraphNode;
|
|
31
|
+
runtimeTaskVariables?: Record<string, unknown>;
|
|
32
|
+
}): void;
|
|
33
|
+
export declare function seedGraphVariableBucketsFromRuntime(args: {
|
|
34
|
+
execution: Record<string, unknown>;
|
|
35
|
+
graph: Graph;
|
|
36
|
+
runtime: {
|
|
37
|
+
variables?: Record<string, unknown>;
|
|
38
|
+
jobVariables?: Record<string, unknown>;
|
|
39
|
+
job?: Job;
|
|
40
|
+
};
|
|
41
|
+
job?: Job;
|
|
42
|
+
}): void;
|
|
43
|
+
/** Predicate / condition context: mirrored execution + job-scoped bucket. */
|
|
44
|
+
export declare function buildPredicateEvalContextForNode(args: {
|
|
45
|
+
executionMemory: Record<string, unknown>;
|
|
46
|
+
jobMemory?: unknown;
|
|
47
|
+
taskMemory?: unknown;
|
|
48
|
+
node?: GraphNode;
|
|
49
|
+
runtimeTaskVariables?: Record<string, unknown>;
|
|
50
|
+
}): {
|
|
51
|
+
executionMemory: Record<string, unknown>;
|
|
52
|
+
jobMemory?: unknown;
|
|
53
|
+
taskMemory?: unknown;
|
|
54
|
+
variables: Record<string, unknown>;
|
|
55
|
+
};
|
|
56
|
+
export declare function buildMemoryResolutionRootFromExecution(args: {
|
|
57
|
+
execution: Record<string, unknown>;
|
|
58
|
+
input: Record<string, unknown>;
|
|
59
|
+
inputs?: Record<string, unknown>;
|
|
60
|
+
jobMemory?: unknown;
|
|
61
|
+
taskMemory?: unknown;
|
|
62
|
+
xynthesized?: {
|
|
63
|
+
job: Record<string, unknown>;
|
|
64
|
+
task: Record<string, unknown>;
|
|
65
|
+
execution?: Record<string, unknown>;
|
|
66
|
+
};
|
|
67
|
+
}): GraphEngineMemoryResolutionRoot;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { EXELLIX_GRAPH_MODEL_VARIABLE_KEY, mergeGraphDocumentModel } from '../types/refs.js';
|
|
2
|
+
import { buildGraphEngineMemoryResolutionRoot, } from './resolveGraphEngineMemoryPaths.js';
|
|
3
|
+
function isPlainObject(v) {
|
|
4
|
+
return v != null && typeof v === 'object' && !Array.isArray(v);
|
|
5
|
+
}
|
|
6
|
+
/** Reads the two variable buckets from live execution memory. */
|
|
7
|
+
export function readExecutionVariableBuckets(execution) {
|
|
8
|
+
return {
|
|
9
|
+
jobVariables: isPlainObject(execution.jobVariables) ? { ...execution.jobVariables } : {},
|
|
10
|
+
taskVariables: isPlainObject(execution.taskVariables) ? { ...execution.taskVariables } : {},
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Seeds job-scoped template variables on `executionMemory` (mirrors runtime like `input` / `inputs`).
|
|
15
|
+
*
|
|
16
|
+
* Graph and job scopes share one bucket:
|
|
17
|
+
* `execution.jobVariables` ← `model.variables` + `variables.__graphModel` + `job.jobVariables`
|
|
18
|
+
* + `runtime.jobVariables` + `runtime.variables` (later layers win).
|
|
19
|
+
*/
|
|
20
|
+
export function seedGraphVariableBucketsOnExecution(args) {
|
|
21
|
+
const { execution, graph, job } = args;
|
|
22
|
+
const jobVars = {};
|
|
23
|
+
if (graph?.variables && typeof graph.variables === 'object') {
|
|
24
|
+
Object.assign(jobVars, graph.variables);
|
|
25
|
+
}
|
|
26
|
+
if (graph) {
|
|
27
|
+
const docModel = mergeGraphDocumentModel(graph);
|
|
28
|
+
if (Object.keys(docModel).length > 0) {
|
|
29
|
+
jobVars[EXELLIX_GRAPH_MODEL_VARIABLE_KEY] = docModel;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const legacyJob = job?.jobVariables;
|
|
33
|
+
if (legacyJob && typeof legacyJob === 'object') {
|
|
34
|
+
Object.assign(jobVars, legacyJob);
|
|
35
|
+
}
|
|
36
|
+
if (args.runtimeJobVariables) {
|
|
37
|
+
Object.assign(jobVars, args.runtimeJobVariables);
|
|
38
|
+
}
|
|
39
|
+
if (args.runtimeVariables) {
|
|
40
|
+
Object.assign(jobVars, args.runtimeVariables);
|
|
41
|
+
}
|
|
42
|
+
execution.jobVariables = jobVars;
|
|
43
|
+
delete execution.variables;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Sets `execution.taskVariables` for the current node: `node.variables` + optional runtime override.
|
|
47
|
+
*/
|
|
48
|
+
export function mirrorTaskVariablesOnExecution(args) {
|
|
49
|
+
const taskVars = {};
|
|
50
|
+
const node = args.node;
|
|
51
|
+
if (node?.variables && typeof node.variables === 'object') {
|
|
52
|
+
Object.assign(taskVars, node.variables);
|
|
53
|
+
}
|
|
54
|
+
if (args.runtimeTaskVariables) {
|
|
55
|
+
Object.assign(taskVars, args.runtimeTaskVariables);
|
|
56
|
+
}
|
|
57
|
+
args.execution.taskVariables = taskVars;
|
|
58
|
+
}
|
|
59
|
+
export function seedGraphVariableBucketsFromRuntime(args) {
|
|
60
|
+
seedGraphVariableBucketsOnExecution({
|
|
61
|
+
execution: args.execution,
|
|
62
|
+
graph: args.graph,
|
|
63
|
+
job: args.job ?? args.runtime.job,
|
|
64
|
+
runtimeVariables: args.runtime.variables,
|
|
65
|
+
runtimeJobVariables: args.runtime.jobVariables,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/** Predicate / condition context: mirrored execution + job-scoped bucket. */
|
|
69
|
+
export function buildPredicateEvalContextForNode(args) {
|
|
70
|
+
const executionMemory = { ...args.executionMemory };
|
|
71
|
+
mirrorTaskVariablesOnExecution({
|
|
72
|
+
execution: executionMemory,
|
|
73
|
+
node: args.node,
|
|
74
|
+
runtimeTaskVariables: args.runtimeTaskVariables,
|
|
75
|
+
});
|
|
76
|
+
const buckets = readExecutionVariableBuckets(executionMemory);
|
|
77
|
+
return {
|
|
78
|
+
executionMemory,
|
|
79
|
+
jobMemory: args.jobMemory,
|
|
80
|
+
taskMemory: args.taskMemory,
|
|
81
|
+
variables: buckets.jobVariables,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export function buildMemoryResolutionRootFromExecution(args) {
|
|
85
|
+
const buckets = readExecutionVariableBuckets(args.execution);
|
|
86
|
+
return buildGraphEngineMemoryResolutionRoot({
|
|
87
|
+
input: args.input,
|
|
88
|
+
inputs: args.inputs,
|
|
89
|
+
jobVariables: buckets.jobVariables,
|
|
90
|
+
taskVariables: buckets.taskVariables,
|
|
91
|
+
jobMemory: args.jobMemory,
|
|
92
|
+
taskMemory: args.taskMemory,
|
|
93
|
+
executionMemory: args.execution,
|
|
94
|
+
xynthesized: args.xynthesized,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type FinalizerErrorCode = 'GRAPH_FINALIZER_INVALID' | 'GRAPH_FINALIZER_UNREACHABLE' | 'GRAPH_FINALIZER_OUTPUT_INVALID' | 'GRAPH_FINALIZER_INPUT_MISSING' | 'GRAPH_FINALIZER_NODE_FAILED' | 'GRAPH_FINALIZER_SYNTHESIZE_NOT_IMPLEMENTED' | 'GRAPH_FINALIZER_SYNTHESIZE_FAILED';
|
|
2
|
+
export type FinalizerErrorPayload = {
|
|
3
|
+
code: FinalizerErrorCode;
|
|
4
|
+
message: string;
|
|
5
|
+
finalizerNodeId: string;
|
|
6
|
+
path?: string;
|
|
7
|
+
details?: Record<string, unknown>;
|
|
8
|
+
};
|
|
9
|
+
export declare function createFinalizerError(payload: FinalizerErrorPayload): Error & FinalizerErrorPayload;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function createFinalizerError(payload) {
|
|
2
|
+
const err = new Error(payload.message);
|
|
3
|
+
err.code = payload.code;
|
|
4
|
+
err.finalizerNodeId = payload.finalizerNodeId;
|
|
5
|
+
if (payload.path)
|
|
6
|
+
err.path = payload.path;
|
|
7
|
+
if (payload.details)
|
|
8
|
+
err.details = payload.details;
|
|
9
|
+
return err;
|
|
10
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { FinalizerInputBinding, FinalizerNode, Graph, SynthesizeFinalizerConfig } from '../../types/refs.js';
|
|
2
|
+
export declare function resolveFinalizerInputs(args: {
|
|
3
|
+
finalizerNodeId: string;
|
|
4
|
+
bindings: Record<string, FinalizerInputBinding>;
|
|
5
|
+
executionMemory: unknown;
|
|
6
|
+
outputsMemory?: unknown;
|
|
7
|
+
}): Record<string, unknown>;
|
|
8
|
+
export declare function executeSynthesizeFinalizer(args: {
|
|
9
|
+
finalizer: FinalizerNode;
|
|
10
|
+
config: SynthesizeFinalizerConfig;
|
|
11
|
+
executionMemory: unknown;
|
|
12
|
+
outputsMemory?: unknown;
|
|
13
|
+
runTask: (req: {
|
|
14
|
+
skillKey: string;
|
|
15
|
+
input?: any;
|
|
16
|
+
jobId?: string;
|
|
17
|
+
taskId?: string;
|
|
18
|
+
agentId?: string;
|
|
19
|
+
skillId?: string;
|
|
20
|
+
masterSkillId?: string;
|
|
21
|
+
}) => Promise<any>;
|
|
22
|
+
context: {
|
|
23
|
+
graphId: string;
|
|
24
|
+
jobId?: string;
|
|
25
|
+
taskId?: string;
|
|
26
|
+
agentId?: string;
|
|
27
|
+
};
|
|
28
|
+
}): Promise<{
|
|
29
|
+
parsed: any;
|
|
30
|
+
rawContent?: string;
|
|
31
|
+
diagnostics?: any;
|
|
32
|
+
}>;
|
|
33
|
+
export declare function executeDeterministicFinalizer(args: {
|
|
34
|
+
finalizer: FinalizerNode;
|
|
35
|
+
executionMemory: unknown;
|
|
36
|
+
outputsMemory?: unknown;
|
|
37
|
+
graph?: Graph;
|
|
38
|
+
}): {
|
|
39
|
+
parsed: any;
|
|
40
|
+
};
|
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
import { createFinalizerError } from './errors.js';
|
|
2
|
+
import { validateAgainstOutputSchema } from './schema.js';
|
|
3
|
+
function isPlainObject(v) {
|
|
4
|
+
return v != null && typeof v === 'object' && !Array.isArray(v);
|
|
5
|
+
}
|
|
6
|
+
/** Value written by graphenix when a task node fails (`{ failed: true, error, reason }`). */
|
|
7
|
+
function isNodeFailureMarker(v) {
|
|
8
|
+
if (!isPlainObject(v))
|
|
9
|
+
return false;
|
|
10
|
+
return v.failed === true && ('error' in v || 'reason' in v);
|
|
11
|
+
}
|
|
12
|
+
function getByDotPath(root, path) {
|
|
13
|
+
if (!path)
|
|
14
|
+
return root;
|
|
15
|
+
const parts = path.split('.').filter(Boolean);
|
|
16
|
+
let cur = root;
|
|
17
|
+
for (const p of parts) {
|
|
18
|
+
if (cur == null)
|
|
19
|
+
return undefined;
|
|
20
|
+
if (typeof cur !== 'object')
|
|
21
|
+
return undefined;
|
|
22
|
+
cur = cur[p];
|
|
23
|
+
}
|
|
24
|
+
return cur;
|
|
25
|
+
}
|
|
26
|
+
function asArrayNodes(graph) {
|
|
27
|
+
return Array.isArray(graph.nodes) ? graph.nodes : Object.values(graph.nodes ?? {});
|
|
28
|
+
}
|
|
29
|
+
function getNodeById(graph, nodeId) {
|
|
30
|
+
return asArrayNodes(graph).find((n) => String(n?.id) === String(nodeId));
|
|
31
|
+
}
|
|
32
|
+
export function resolveFinalizerInputs(args) {
|
|
33
|
+
const out = {};
|
|
34
|
+
for (const [name, b] of Object.entries(args.bindings ?? {})) {
|
|
35
|
+
if (b.type === 'literal') {
|
|
36
|
+
out[name] = b.value;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (b.type === 'executionMemoryPath') {
|
|
40
|
+
let v = getByDotPath(args.executionMemory, b.path);
|
|
41
|
+
if (isNodeFailureMarker(v)) {
|
|
42
|
+
if (b.optional === true) {
|
|
43
|
+
out[name] = null;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
throw createFinalizerError({
|
|
47
|
+
code: 'GRAPH_FINALIZER_NODE_FAILED',
|
|
48
|
+
message: `Finalizer input "${name}" points at a failed graph node (executionMemoryPath="${b.path}")`,
|
|
49
|
+
finalizerNodeId: args.finalizerNodeId,
|
|
50
|
+
path: `inputs.${name}`,
|
|
51
|
+
details: { binding: b, marker: v },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if ((v === undefined || v === null) && b.optional !== true) {
|
|
55
|
+
throw createFinalizerError({
|
|
56
|
+
code: 'GRAPH_FINALIZER_INPUT_MISSING',
|
|
57
|
+
message: `Finalizer input missing: "${name}" (executionMemoryPath="${b.path}")`,
|
|
58
|
+
finalizerNodeId: args.finalizerNodeId,
|
|
59
|
+
path: `inputs.${name}`,
|
|
60
|
+
details: { binding: b },
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
out[name] = v;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (b.type === 'outputsMemoryPath') {
|
|
67
|
+
let v = getByDotPath(args.outputsMemory, b.path);
|
|
68
|
+
if (isNodeFailureMarker(v)) {
|
|
69
|
+
if (b.optional === true) {
|
|
70
|
+
out[name] = null;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
throw createFinalizerError({
|
|
74
|
+
code: 'GRAPH_FINALIZER_NODE_FAILED',
|
|
75
|
+
message: `Finalizer input "${name}" points at a failed graph node (outputsMemoryPath="${b.path}")`,
|
|
76
|
+
finalizerNodeId: args.finalizerNodeId,
|
|
77
|
+
path: `inputs.${name}`,
|
|
78
|
+
details: { binding: b, marker: v },
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if ((v === undefined || v === null) && b.optional !== true) {
|
|
82
|
+
throw createFinalizerError({
|
|
83
|
+
code: 'GRAPH_FINALIZER_INPUT_MISSING',
|
|
84
|
+
message: `Finalizer input missing: "${name}" (outputsMemoryPath="${b.path}")`,
|
|
85
|
+
finalizerNodeId: args.finalizerNodeId,
|
|
86
|
+
path: `inputs.${name}`,
|
|
87
|
+
details: { binding: b },
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
out[name] = v;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
throw createFinalizerError({
|
|
94
|
+
code: 'GRAPH_FINALIZER_INVALID',
|
|
95
|
+
message: `Unsupported finalizer input binding type "${String(b.type)}"`,
|
|
96
|
+
finalizerNodeId: args.finalizerNodeId,
|
|
97
|
+
path: `inputs.${name}.type`,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return out;
|
|
101
|
+
}
|
|
102
|
+
function executeAggregate(finalizer, cfg, inputs) {
|
|
103
|
+
const out = {};
|
|
104
|
+
for (const [k, expr] of Object.entries(cfg.map ?? {})) {
|
|
105
|
+
if (expr.kind === 'literal')
|
|
106
|
+
out[k] = expr.value;
|
|
107
|
+
else if (expr.kind === 'input') {
|
|
108
|
+
if (!(expr.name in inputs)) {
|
|
109
|
+
throw createFinalizerError({
|
|
110
|
+
code: 'GRAPH_FINALIZER_INVALID',
|
|
111
|
+
message: `Aggregate finalizer map references missing input name "${expr.name}"`,
|
|
112
|
+
finalizerNodeId: String(finalizer.id),
|
|
113
|
+
path: `config.map.${k}`,
|
|
114
|
+
details: { mapKey: k, inputName: expr.name, availableInputs: Object.keys(inputs) },
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
out[k] = inputs[expr.name];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (cfg.omitUndefined) {
|
|
121
|
+
for (const [k, v] of Object.entries(out))
|
|
122
|
+
if (v === undefined)
|
|
123
|
+
delete out[k];
|
|
124
|
+
}
|
|
125
|
+
return out;
|
|
126
|
+
}
|
|
127
|
+
function executeAggregateQuestionDriven(args) {
|
|
128
|
+
const finalizerNodeId = String(args.finalizer.id);
|
|
129
|
+
const out = {};
|
|
130
|
+
if (args.cfg.contractVersion !== undefined)
|
|
131
|
+
out.contractVersion = args.cfg.contractVersion;
|
|
132
|
+
if (args.cfg.meta) {
|
|
133
|
+
const metaOut = {};
|
|
134
|
+
for (const [k, b] of Object.entries(args.cfg.meta)) {
|
|
135
|
+
const root = b.type === 'outputsMemoryPath' ? args.outputsMemory : args.executionMemory;
|
|
136
|
+
let v = getByDotPath(root, b.path);
|
|
137
|
+
if (isNodeFailureMarker(v)) {
|
|
138
|
+
if (b.optional === true) {
|
|
139
|
+
metaOut[k] = null;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
throw createFinalizerError({
|
|
143
|
+
code: 'GRAPH_FINALIZER_NODE_FAILED',
|
|
144
|
+
message: `Finalizer meta "${k}" points at a failed graph node (${b.type}="${b.path}")`,
|
|
145
|
+
finalizerNodeId,
|
|
146
|
+
path: `config.meta.${k}`,
|
|
147
|
+
details: { binding: b, marker: v },
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
if ((v === undefined || v === null) && b.optional !== true) {
|
|
151
|
+
throw createFinalizerError({
|
|
152
|
+
code: 'GRAPH_FINALIZER_INPUT_MISSING',
|
|
153
|
+
message: `Finalizer meta missing: "${k}" (${b.type}="${b.path}")`,
|
|
154
|
+
finalizerNodeId,
|
|
155
|
+
path: `config.meta.${k}`,
|
|
156
|
+
details: { binding: b },
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
metaOut[k] = v;
|
|
160
|
+
}
|
|
161
|
+
out.meta = metaOut;
|
|
162
|
+
}
|
|
163
|
+
for (const [outKey, spec] of Object.entries(args.cfg.items ?? {})) {
|
|
164
|
+
const nodeId = String(spec.nodeId);
|
|
165
|
+
const node = getNodeById(args.graph, nodeId);
|
|
166
|
+
if (!node) {
|
|
167
|
+
throw createFinalizerError({
|
|
168
|
+
code: 'GRAPH_FINALIZER_INVALID',
|
|
169
|
+
message: `question-driven finalizer references missing nodeId "${nodeId}"`,
|
|
170
|
+
finalizerNodeId,
|
|
171
|
+
path: `config.items.${outKey}.nodeId`,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const questionPath = spec.questionPath ?? 'inputs.question';
|
|
175
|
+
const question = getByDotPath(node, questionPath);
|
|
176
|
+
if (typeof question !== 'string' || question.length === 0) {
|
|
177
|
+
throw createFinalizerError({
|
|
178
|
+
code: 'GRAPH_FINALIZER_INVALID',
|
|
179
|
+
message: `question-driven finalizer could not read a non-empty question at ${questionPath} for node "${nodeId}"`,
|
|
180
|
+
finalizerNodeId,
|
|
181
|
+
path: `config.items.${outKey}.questionPath`,
|
|
182
|
+
details: { nodeId, questionPath, actual: question },
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
const defaultAnswerPath = node?.executionMapping?.path;
|
|
186
|
+
const answerPath = spec.answerPath ?? (typeof defaultAnswerPath === 'string' ? defaultAnswerPath : undefined);
|
|
187
|
+
if (!answerPath) {
|
|
188
|
+
throw createFinalizerError({
|
|
189
|
+
code: 'GRAPH_FINALIZER_INVALID',
|
|
190
|
+
message: `question-driven finalizer needs answerPath or node.executionMapping.path for node "${nodeId}"`,
|
|
191
|
+
finalizerNodeId,
|
|
192
|
+
path: `config.items.${outKey}.answerPath`,
|
|
193
|
+
details: { nodeId },
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
const answer = getByDotPath(args.executionMemory, answerPath);
|
|
197
|
+
if (isNodeFailureMarker(answer)) {
|
|
198
|
+
if (spec.optional === true) {
|
|
199
|
+
out[outKey] = { question, answer: null };
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
throw createFinalizerError({
|
|
203
|
+
code: 'GRAPH_FINALIZER_NODE_FAILED',
|
|
204
|
+
message: `question-driven item "${outKey}": answer unavailable (upstream node "${nodeId}" failed)`,
|
|
205
|
+
finalizerNodeId,
|
|
206
|
+
path: `config.items.${outKey}`,
|
|
207
|
+
details: { nodeId, answerPath },
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
out[outKey] = { question, answer };
|
|
211
|
+
}
|
|
212
|
+
return out;
|
|
213
|
+
}
|
|
214
|
+
function executeBundle(finalizer, cfg, inputs) {
|
|
215
|
+
const out = {};
|
|
216
|
+
for (const name of cfg.includeInputs ?? [])
|
|
217
|
+
out[name] = inputs[name];
|
|
218
|
+
return out;
|
|
219
|
+
}
|
|
220
|
+
function executeSelect(finalizer, cfg, inputs) {
|
|
221
|
+
const sel = cfg.selector;
|
|
222
|
+
if (sel.type === 'firstPresent') {
|
|
223
|
+
const order = Array.isArray(sel.order) && sel.order.length ? sel.order : Object.keys(inputs);
|
|
224
|
+
for (const k of order) {
|
|
225
|
+
const v = inputs[k];
|
|
226
|
+
if (v !== undefined && v !== null && !isNodeFailureMarker(v))
|
|
227
|
+
return v;
|
|
228
|
+
}
|
|
229
|
+
throw createFinalizerError({
|
|
230
|
+
code: 'GRAPH_FINALIZER_OUTPUT_INVALID',
|
|
231
|
+
message: `Select finalizer: no present inputs for firstPresent`,
|
|
232
|
+
finalizerNodeId: String(finalizer.id),
|
|
233
|
+
details: { order },
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
if (sel.type === 'byInputValue') {
|
|
237
|
+
const selectorInput = sel.selectorInput;
|
|
238
|
+
if (!selectorInput) {
|
|
239
|
+
throw createFinalizerError({
|
|
240
|
+
code: 'GRAPH_FINALIZER_INVALID',
|
|
241
|
+
message: `Select finalizer byInputValue requires selectorInput`,
|
|
242
|
+
finalizerNodeId: String(finalizer.id),
|
|
243
|
+
path: 'config.selector.selectorInput',
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
const v = inputs[selectorInput];
|
|
247
|
+
const key = typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean' ? String(v) : undefined;
|
|
248
|
+
const targetName = key != null ? sel.cases?.[key] : undefined;
|
|
249
|
+
if (!targetName) {
|
|
250
|
+
throw createFinalizerError({
|
|
251
|
+
code: 'GRAPH_FINALIZER_OUTPUT_INVALID',
|
|
252
|
+
message: `Select finalizer: no case match for selector value`,
|
|
253
|
+
finalizerNodeId: String(finalizer.id),
|
|
254
|
+
path: `inputs.${selectorInput}`,
|
|
255
|
+
details: { selectorValue: v, cases: sel.cases ?? {} },
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
return inputs[targetName];
|
|
259
|
+
}
|
|
260
|
+
throw createFinalizerError({
|
|
261
|
+
code: 'GRAPH_FINALIZER_INVALID',
|
|
262
|
+
message: `Unsupported select selector type "${String(sel.type)}"`,
|
|
263
|
+
finalizerNodeId: String(finalizer.id),
|
|
264
|
+
path: 'config.selector.type',
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
const EPISTEMIC_TAGS = ['CONFIRMED', 'INFERRED', 'ASSUMED', 'UNKNOWN'];
|
|
268
|
+
function collectEpistemicTags(value, found) {
|
|
269
|
+
if (value == null)
|
|
270
|
+
return;
|
|
271
|
+
if (typeof value === 'string' && EPISTEMIC_TAGS.includes(value)) {
|
|
272
|
+
found.add(value);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (Array.isArray(value)) {
|
|
276
|
+
for (const item of value)
|
|
277
|
+
collectEpistemicTags(item, found);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (typeof value === 'object') {
|
|
281
|
+
for (const v of Object.values(value)) {
|
|
282
|
+
collectEpistemicTags(v, found);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function executeReportSchema(args) {
|
|
287
|
+
const { cfg, executionMemory } = args;
|
|
288
|
+
const finalizerNodeId = String(args.finalizer.id);
|
|
289
|
+
const out = {};
|
|
290
|
+
for (const [key, spec] of Object.entries(cfg.sections ?? {})) {
|
|
291
|
+
let v = getByDotPath(executionMemory, spec.path);
|
|
292
|
+
if (isNodeFailureMarker(v)) {
|
|
293
|
+
if (spec.optional === true) {
|
|
294
|
+
out[key] = null;
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
throw createFinalizerError({
|
|
298
|
+
code: 'GRAPH_FINALIZER_NODE_FAILED',
|
|
299
|
+
message: `report-schema: section "${key}" points at a failed graph node (path="${spec.path}")`,
|
|
300
|
+
finalizerNodeId,
|
|
301
|
+
path: `config.sections.${key}`,
|
|
302
|
+
details: { spec, marker: v },
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
if ((v === undefined || v === null) && spec.optional !== true) {
|
|
306
|
+
throw createFinalizerError({
|
|
307
|
+
code: 'GRAPH_FINALIZER_INPUT_MISSING',
|
|
308
|
+
message: `report-schema: required section "${key}" not found at path "${spec.path}"`,
|
|
309
|
+
finalizerNodeId,
|
|
310
|
+
path: `config.sections.${key}`,
|
|
311
|
+
details: { spec },
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
out[key] = v ?? null;
|
|
315
|
+
}
|
|
316
|
+
if (cfg.collect_tags) {
|
|
317
|
+
const tags = new Set();
|
|
318
|
+
for (const v of Object.values(out))
|
|
319
|
+
collectEpistemicTags(v, tags);
|
|
320
|
+
out.collected_tags = Array.from(tags);
|
|
321
|
+
}
|
|
322
|
+
if (cfg.meta) {
|
|
323
|
+
for (const [k, v] of Object.entries(cfg.meta)) {
|
|
324
|
+
out[k] = v;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return out;
|
|
328
|
+
}
|
|
329
|
+
function validateSchemaOrThrow(finalizer, parsed) {
|
|
330
|
+
if (finalizer.outputSchema == null)
|
|
331
|
+
return;
|
|
332
|
+
const schema = finalizer.outputSchema;
|
|
333
|
+
const res = validateAgainstOutputSchema(parsed, schema);
|
|
334
|
+
if (!res.ok) {
|
|
335
|
+
throw createFinalizerError({
|
|
336
|
+
code: 'GRAPH_FINALIZER_OUTPUT_INVALID',
|
|
337
|
+
message: `Finalizer output did not match outputSchema`,
|
|
338
|
+
finalizerNodeId: String(finalizer.id),
|
|
339
|
+
details: { errors: res.errors },
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
export async function executeSynthesizeFinalizer(args) {
|
|
344
|
+
const finalizer = args.finalizer;
|
|
345
|
+
const finalizerNodeId = String(finalizer.id);
|
|
346
|
+
const inputs = resolveFinalizerInputs({
|
|
347
|
+
finalizerNodeId,
|
|
348
|
+
bindings: finalizer.inputs ?? {},
|
|
349
|
+
executionMemory: args.executionMemory,
|
|
350
|
+
outputsMemory: args.outputsMemory,
|
|
351
|
+
});
|
|
352
|
+
const req = {
|
|
353
|
+
skillKey: args.config.utilityKey,
|
|
354
|
+
jobId: args.context.jobId,
|
|
355
|
+
taskId: args.context.taskId,
|
|
356
|
+
agentId: args.context.agentId,
|
|
357
|
+
skillId: finalizerNodeId,
|
|
358
|
+
masterSkillId: args.context.graphId,
|
|
359
|
+
input: {
|
|
360
|
+
templateId: args.config.templateId,
|
|
361
|
+
inputs,
|
|
362
|
+
...(args.config.outputContractId ? { outputContractId: args.config.outputContractId } : {}),
|
|
363
|
+
...(args.config.executionPolicy ? { executionPolicy: args.config.executionPolicy } : {}),
|
|
364
|
+
metadata: {
|
|
365
|
+
graphId: args.context.graphId,
|
|
366
|
+
finalizerNodeId,
|
|
367
|
+
...(args.context.jobId ? { jobId: args.context.jobId } : {}),
|
|
368
|
+
...(args.context.taskId ? { taskId: args.context.taskId } : {}),
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
};
|
|
372
|
+
let res;
|
|
373
|
+
try {
|
|
374
|
+
res = await args.runTask(req);
|
|
375
|
+
}
|
|
376
|
+
catch (e) {
|
|
377
|
+
throw createFinalizerError({
|
|
378
|
+
code: 'GRAPH_FINALIZER_SYNTHESIZE_FAILED',
|
|
379
|
+
message: e?.message ?? 'Synthesize finalizer runTask failed',
|
|
380
|
+
finalizerNodeId,
|
|
381
|
+
details: { error: e },
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
if (!res || res.ok !== true) {
|
|
385
|
+
throw createFinalizerError({
|
|
386
|
+
code: 'GRAPH_FINALIZER_SYNTHESIZE_FAILED',
|
|
387
|
+
message: res?.error?.message ?? 'Synthesize finalizer failed',
|
|
388
|
+
finalizerNodeId,
|
|
389
|
+
details: { error: res?.error, response: res },
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
const parsed = res.parsed;
|
|
393
|
+
if (parsed === undefined) {
|
|
394
|
+
throw createFinalizerError({
|
|
395
|
+
code: 'GRAPH_FINALIZER_SYNTHESIZE_FAILED',
|
|
396
|
+
message: 'Synthesize finalizer returned no parsed output',
|
|
397
|
+
finalizerNodeId,
|
|
398
|
+
details: { response: res },
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
validateSchemaOrThrow(finalizer, parsed);
|
|
402
|
+
return { parsed, rawContent: res.rawContent, diagnostics: res.diagnostics };
|
|
403
|
+
}
|
|
404
|
+
export function executeDeterministicFinalizer(args) {
|
|
405
|
+
const finalizer = args.finalizer;
|
|
406
|
+
const finalizerNodeId = String(finalizer.id);
|
|
407
|
+
const inputs = resolveFinalizerInputs({
|
|
408
|
+
finalizerNodeId,
|
|
409
|
+
bindings: finalizer.inputs ?? {},
|
|
410
|
+
executionMemory: args.executionMemory,
|
|
411
|
+
outputsMemory: args.outputsMemory,
|
|
412
|
+
});
|
|
413
|
+
const ft = finalizer.finalizerType;
|
|
414
|
+
const cfg = finalizer.config;
|
|
415
|
+
let parsed;
|
|
416
|
+
if (ft === 'aggregate') {
|
|
417
|
+
if (cfg?.strategy === 'question-driven') {
|
|
418
|
+
if (!args.graph) {
|
|
419
|
+
throw createFinalizerError({
|
|
420
|
+
code: 'GRAPH_FINALIZER_INVALID',
|
|
421
|
+
message: `question-driven aggregate finalizer requires graph context`,
|
|
422
|
+
finalizerNodeId,
|
|
423
|
+
path: 'config.strategy',
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
parsed = executeAggregateQuestionDriven({
|
|
427
|
+
finalizer,
|
|
428
|
+
cfg: cfg,
|
|
429
|
+
executionMemory: args.executionMemory,
|
|
430
|
+
outputsMemory: args.outputsMemory,
|
|
431
|
+
graph: args.graph,
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
else if (cfg?.strategy === 'report-schema') {
|
|
435
|
+
parsed = executeReportSchema({
|
|
436
|
+
finalizer,
|
|
437
|
+
cfg: cfg,
|
|
438
|
+
executionMemory: args.executionMemory,
|
|
439
|
+
outputsMemory: args.outputsMemory,
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
parsed = executeAggregate(finalizer, cfg, inputs);
|
|
444
|
+
}
|
|
445
|
+
validateSchemaOrThrow(finalizer, parsed);
|
|
446
|
+
return { parsed };
|
|
447
|
+
}
|
|
448
|
+
if (ft === 'bundle') {
|
|
449
|
+
parsed = executeBundle(finalizer, cfg, inputs);
|
|
450
|
+
validateSchemaOrThrow(finalizer, parsed);
|
|
451
|
+
return { parsed };
|
|
452
|
+
}
|
|
453
|
+
if (ft === 'select') {
|
|
454
|
+
parsed = executeSelect(finalizer, cfg, inputs);
|
|
455
|
+
validateSchemaOrThrow(finalizer, parsed);
|
|
456
|
+
return { parsed };
|
|
457
|
+
}
|
|
458
|
+
if (ft === 'synthesize') {
|
|
459
|
+
throw createFinalizerError({
|
|
460
|
+
code: 'GRAPH_FINALIZER_SYNTHESIZE_NOT_IMPLEMENTED',
|
|
461
|
+
message: `Synthesize finalizer requires AI-backed execution`,
|
|
462
|
+
finalizerNodeId,
|
|
463
|
+
details: { config: cfg },
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
throw createFinalizerError({
|
|
467
|
+
code: 'GRAPH_FINALIZER_INVALID',
|
|
468
|
+
message: `Unsupported finalizerType "${String(ft)}"`,
|
|
469
|
+
finalizerNodeId,
|
|
470
|
+
});
|
|
471
|
+
}
|