@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,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Allowed memory-path roots for smartInput.paths and taskConfiguration.aiTaskProfile.inputSynthesis.sources.
|
|
3
|
+
* `input` and `inputs` are distinct roots (see `.docs/CR-input-and-inputs-dual-root.md`).
|
|
4
|
+
*/
|
|
5
|
+
export const GRAPH_ENGINE_MEMORY_PATH_ROOTS = [
|
|
6
|
+
'input',
|
|
7
|
+
'inputs',
|
|
8
|
+
'variables',
|
|
9
|
+
'jobVariables',
|
|
10
|
+
'taskVariables',
|
|
11
|
+
'jobMemory',
|
|
12
|
+
'taskMemory',
|
|
13
|
+
'executionMemory',
|
|
14
|
+
'xynthesized.job',
|
|
15
|
+
'xynthesized.task',
|
|
16
|
+
'xynthesized.execution',
|
|
17
|
+
];
|
|
18
|
+
const ALLOWED_ROOTS = GRAPH_ENGINE_MEMORY_PATH_ROOTS;
|
|
19
|
+
const MEMORY_ROOTS_LONGEST_FIRST = [...ALLOWED_ROOTS].sort((a, b) => b.length - a.length);
|
|
20
|
+
/** Splits a path into allowlisted root + dot tail (longest root wins, e.g. `inputs` before `input`). */
|
|
21
|
+
export function splitGraphEngineMemoryPath(path) {
|
|
22
|
+
const p = typeof path === 'string' ? path.trim() : '';
|
|
23
|
+
if (!p)
|
|
24
|
+
return { root: '', tail: '' };
|
|
25
|
+
for (const root of MEMORY_ROOTS_LONGEST_FIRST) {
|
|
26
|
+
if (p === root)
|
|
27
|
+
return { root, tail: '' };
|
|
28
|
+
if (p.startsWith(`${root}.`))
|
|
29
|
+
return { root, tail: p.slice(root.length + 1) };
|
|
30
|
+
}
|
|
31
|
+
return { root: p, tail: '' };
|
|
32
|
+
}
|
|
33
|
+
function isAllowedGraphEngineMemoryPathForRoot(path) {
|
|
34
|
+
const p = path.trim();
|
|
35
|
+
if (!p)
|
|
36
|
+
return false;
|
|
37
|
+
for (const root of ALLOWED_ROOTS) {
|
|
38
|
+
if (p === root || p.startsWith(`${root}.`))
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
export function isAllowedGraphEngineMemoryPath(path) {
|
|
44
|
+
return isAllowedGraphEngineMemoryPathForRoot(path);
|
|
45
|
+
}
|
|
46
|
+
export function graphEngineMemoryPathValidationMessage(path) {
|
|
47
|
+
const raw = typeof path === 'string' ? path.trim() : String(path);
|
|
48
|
+
if (!raw)
|
|
49
|
+
return 'disallowed or empty path ""';
|
|
50
|
+
const { root } = splitGraphEngineMemoryPath(raw);
|
|
51
|
+
if (root && !ALLOWED_ROOTS.includes(root)) {
|
|
52
|
+
return `disallowed path "${raw}" — root must be one of: ${ALLOWED_ROOTS.join(', ')}`;
|
|
53
|
+
}
|
|
54
|
+
return `disallowed or empty path "${raw}"`;
|
|
55
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Graph, GraphResponseDefinition } from '../types/refs.js';
|
|
2
|
+
declare const GRAPH_RESPONSE_MAPPING_ERROR_CODE = "GRAPH_RESPONSE_MAPPING_INVALID";
|
|
3
|
+
export type GraphResponseMappingContext = {
|
|
4
|
+
graph: Graph;
|
|
5
|
+
executionMemory: unknown;
|
|
6
|
+
outputsMemory?: unknown;
|
|
7
|
+
selectedFinalOutput?: unknown;
|
|
8
|
+
outputsByNodeId?: Record<string, unknown>;
|
|
9
|
+
stepsResponses?: unknown[];
|
|
10
|
+
};
|
|
11
|
+
export type GraphResponseMappingError = Error & {
|
|
12
|
+
code: typeof GRAPH_RESPONSE_MAPPING_ERROR_CODE;
|
|
13
|
+
path?: string;
|
|
14
|
+
details?: Record<string, unknown>;
|
|
15
|
+
};
|
|
16
|
+
export declare function assertGraphResponseDefinition(response: unknown): asserts response is GraphResponseDefinition;
|
|
17
|
+
export declare function applyGraphResponseDefinition(args: {
|
|
18
|
+
response: GraphResponseDefinition;
|
|
19
|
+
context: GraphResponseMappingContext;
|
|
20
|
+
}): unknown;
|
|
21
|
+
/** @deprecated Use applyGraphResponseDefinition with root-level graph.response. */
|
|
22
|
+
export declare const applyGraphResponseMapping: typeof applyGraphResponseDefinition;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { selectByPath } from './pathExpr.js';
|
|
2
|
+
import { isNodeInputsConfigSelectorType, readTaskNodeModelInputSurface, } from './readTaskNodeInputsConfig.js';
|
|
3
|
+
const GRAPH_RESPONSE_MAPPING_ERROR_CODE = 'GRAPH_RESPONSE_MAPPING_INVALID';
|
|
4
|
+
const OMIT = Symbol('graphResponseMapping.omit');
|
|
5
|
+
const FORBIDDEN_GRAPH_RESPONSE_KEYS = [
|
|
6
|
+
'version',
|
|
7
|
+
'target',
|
|
8
|
+
'primaryResponsePaths',
|
|
9
|
+
'debugResponsePaths',
|
|
10
|
+
'notableExecutionPaths',
|
|
11
|
+
'mappingPreset',
|
|
12
|
+
];
|
|
13
|
+
function createGraphResponseMappingError(message, path, details) {
|
|
14
|
+
const err = new Error(message);
|
|
15
|
+
err.code = GRAPH_RESPONSE_MAPPING_ERROR_CODE;
|
|
16
|
+
if (path)
|
|
17
|
+
err.path = path;
|
|
18
|
+
if (details)
|
|
19
|
+
err.details = details;
|
|
20
|
+
return err;
|
|
21
|
+
}
|
|
22
|
+
function isPlainObject(v) {
|
|
23
|
+
return v != null && typeof v === 'object' && !Array.isArray(v);
|
|
24
|
+
}
|
|
25
|
+
function isSupportedSelector(v) {
|
|
26
|
+
if (!isPlainObject(v) || typeof v.type !== 'string')
|
|
27
|
+
return false;
|
|
28
|
+
return (v.type === 'outputsMemoryPath' ||
|
|
29
|
+
v.type === 'executionMemoryPath' ||
|
|
30
|
+
v.type === 'executionPath' ||
|
|
31
|
+
v.type === 'nodeMetadata' ||
|
|
32
|
+
v.type === 'nodeInputsConfig' ||
|
|
33
|
+
v.type === 'nodeInputs' ||
|
|
34
|
+
v.type === 'literal' ||
|
|
35
|
+
v.type === 'firstPresent');
|
|
36
|
+
}
|
|
37
|
+
function getGraphNodes(graph) {
|
|
38
|
+
return Array.isArray(graph.nodes)
|
|
39
|
+
? graph.nodes
|
|
40
|
+
: Object.values(graph.nodes ?? {});
|
|
41
|
+
}
|
|
42
|
+
function getNodeById(graph, nodeId) {
|
|
43
|
+
return getGraphNodes(graph).find((node) => String(node?.id) === nodeId);
|
|
44
|
+
}
|
|
45
|
+
function assertNonEmptyString(value, path, label) {
|
|
46
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
47
|
+
throw createGraphResponseMappingError(`${label} must be a non-empty string.`, path, { actual: value });
|
|
48
|
+
}
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
export function assertGraphResponseDefinition(response) {
|
|
52
|
+
if (!isPlainObject(response)) {
|
|
53
|
+
throw createGraphResponseMappingError('graph.response must be a plain object.', 'graph.response');
|
|
54
|
+
}
|
|
55
|
+
for (const key of FORBIDDEN_GRAPH_RESPONSE_KEYS) {
|
|
56
|
+
if (key in response) {
|
|
57
|
+
throw createGraphResponseMappingError(`graph.response.${key} is not part of the root response contract.`, `graph.response.${key}`, { key });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (response.missing !== undefined && response.missing !== 'omit' && response.missing !== 'null') {
|
|
61
|
+
throw createGraphResponseMappingError('graph.response.missing must be "omit" or "null" when provided.', 'graph.response.missing', { actual: response.missing });
|
|
62
|
+
}
|
|
63
|
+
if (!('shape' in response)) {
|
|
64
|
+
throw createGraphResponseMappingError('graph.response.shape is required.', 'graph.response.shape');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function materializeMissing(missing) {
|
|
68
|
+
return missing === 'null' ? null : OMIT;
|
|
69
|
+
}
|
|
70
|
+
function presentOrMissing(value, missing) {
|
|
71
|
+
return value === undefined || value === null ? materializeMissing(missing) : value;
|
|
72
|
+
}
|
|
73
|
+
function resolveSelector(selector, context, path, missing) {
|
|
74
|
+
if (selector.type === 'literal') {
|
|
75
|
+
if (!Object.prototype.hasOwnProperty.call(selector, 'value')) {
|
|
76
|
+
throw createGraphResponseMappingError('literal selector requires a value field.', `${path}.value`);
|
|
77
|
+
}
|
|
78
|
+
return selector.value;
|
|
79
|
+
}
|
|
80
|
+
if (selector.type === 'outputsMemoryPath') {
|
|
81
|
+
const sourcePath = assertNonEmptyString(selector.path, `${path}.path`, `${selector.type}.path`);
|
|
82
|
+
return presentOrMissing(selectByPath(context.outputsMemory, sourcePath), missing);
|
|
83
|
+
}
|
|
84
|
+
if (selector.type === 'executionMemoryPath' || selector.type === 'executionPath') {
|
|
85
|
+
const sourcePath = assertNonEmptyString(selector.path, `${path}.path`, `${selector.type}.path`);
|
|
86
|
+
return presentOrMissing(selectByPath(context.executionMemory, sourcePath), missing);
|
|
87
|
+
}
|
|
88
|
+
if (selector.type === 'nodeMetadata') {
|
|
89
|
+
const nodeId = assertNonEmptyString(selector.nodeId, `${path}.nodeId`, `${selector.type}.nodeId`);
|
|
90
|
+
const sourcePath = assertNonEmptyString(selector.path, `${path}.path`, `${selector.type}.path`);
|
|
91
|
+
const node = getNodeById(context.graph, nodeId);
|
|
92
|
+
if (!node) {
|
|
93
|
+
throw createGraphResponseMappingError(`${selector.type} selector references missing nodeId "${nodeId}".`, `${path}.nodeId`, { nodeId });
|
|
94
|
+
}
|
|
95
|
+
return presentOrMissing(selectByPath(node.metadata, sourcePath), missing);
|
|
96
|
+
}
|
|
97
|
+
if (isNodeInputsConfigSelectorType(selector.type)) {
|
|
98
|
+
const inputSelector = selector;
|
|
99
|
+
const nodeId = assertNonEmptyString(inputSelector.nodeId, `${path}.nodeId`, `${selector.type}.nodeId`);
|
|
100
|
+
const sourcePath = assertNonEmptyString(inputSelector.path, `${path}.path`, `${selector.type}.path`);
|
|
101
|
+
const node = getNodeById(context.graph, nodeId);
|
|
102
|
+
if (!node) {
|
|
103
|
+
throw createGraphResponseMappingError(`${selector.type} selector references missing nodeId "${nodeId}".`, `${path}.nodeId`, { nodeId });
|
|
104
|
+
}
|
|
105
|
+
const root = readTaskNodeModelInputSurface(node);
|
|
106
|
+
return presentOrMissing(selectByPath(root, sourcePath), missing);
|
|
107
|
+
}
|
|
108
|
+
if (selector.type === 'firstPresent') {
|
|
109
|
+
if (!Array.isArray(selector.sources) || selector.sources.length === 0) {
|
|
110
|
+
throw createGraphResponseMappingError('firstPresent selector requires a non-empty sources array.', `${path}.sources`);
|
|
111
|
+
}
|
|
112
|
+
for (let i = 0; i < selector.sources.length; i++) {
|
|
113
|
+
const source = selector.sources[i];
|
|
114
|
+
if (!isSupportedSelector(source)) {
|
|
115
|
+
throw createGraphResponseMappingError('firstPresent.sources entries must be graph response mapping selectors.', `${path}.sources.${i}`);
|
|
116
|
+
}
|
|
117
|
+
const value = resolveSelector(source, context, `${path}.sources.${i}`, 'omit');
|
|
118
|
+
if (value !== OMIT && value !== null)
|
|
119
|
+
return value;
|
|
120
|
+
}
|
|
121
|
+
return materializeMissing(missing);
|
|
122
|
+
}
|
|
123
|
+
throw createGraphResponseMappingError(`Unsupported graph response mapping selector type "${String(selector.type)}".`, `${path}.type`);
|
|
124
|
+
}
|
|
125
|
+
function resolveShape(shape, context, path, missing) {
|
|
126
|
+
if (isSupportedSelector(shape)) {
|
|
127
|
+
return resolveSelector(shape, context, path, missing);
|
|
128
|
+
}
|
|
129
|
+
if (Array.isArray(shape)) {
|
|
130
|
+
const out = [];
|
|
131
|
+
for (let i = 0; i < shape.length; i++) {
|
|
132
|
+
const value = resolveShape(shape[i], context, `${path}.${i}`, missing);
|
|
133
|
+
if (value !== OMIT)
|
|
134
|
+
out.push(value);
|
|
135
|
+
}
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
if (isPlainObject(shape)) {
|
|
139
|
+
const out = {};
|
|
140
|
+
for (const [key, valueShape] of Object.entries(shape)) {
|
|
141
|
+
const value = resolveShape(valueShape, context, `${path}.${key}`, missing);
|
|
142
|
+
if (value !== OMIT)
|
|
143
|
+
out[key] = value;
|
|
144
|
+
}
|
|
145
|
+
return out;
|
|
146
|
+
}
|
|
147
|
+
return shape;
|
|
148
|
+
}
|
|
149
|
+
export function applyGraphResponseDefinition(args) {
|
|
150
|
+
assertGraphResponseDefinition(args.response);
|
|
151
|
+
const missing = args.response.missing ?? 'omit';
|
|
152
|
+
const mapped = resolveShape(args.response.shape, args.context, 'graph.response.shape', missing);
|
|
153
|
+
return mapped === OMIT ? undefined : mapped;
|
|
154
|
+
}
|
|
155
|
+
/** @deprecated Use applyGraphResponseDefinition with root-level graph.response. */
|
|
156
|
+
export const applyGraphResponseMapping = applyGraphResponseDefinition;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { GraphModelObject } from '../types/refs.js';
|
|
2
|
+
export type MigrateGraphResponseResult<T> = {
|
|
3
|
+
graph: T;
|
|
4
|
+
migrated: boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare function migrateLegacyGraphResponseDefinition<T extends object>(graph: T): MigrateGraphResponseResult<T>;
|
|
7
|
+
export declare function migrateLegacyGraphResponse<T extends GraphModelObject | object>(graph: T): MigrateGraphResponseResult<T>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const LEGACY_RESPONSE_DROP_KEYS = new Set([
|
|
2
|
+
'version',
|
|
3
|
+
'target',
|
|
4
|
+
'primaryResponsePaths',
|
|
5
|
+
'debugResponsePaths',
|
|
6
|
+
'notableExecutionPaths',
|
|
7
|
+
'mappingPreset',
|
|
8
|
+
]);
|
|
9
|
+
function isPlainObject(value) {
|
|
10
|
+
return value != null && typeof value === 'object' && !Array.isArray(value);
|
|
11
|
+
}
|
|
12
|
+
function cloneGraph(graph) {
|
|
13
|
+
return structuredClone(graph);
|
|
14
|
+
}
|
|
15
|
+
export function migrateLegacyGraphResponseDefinition(graph) {
|
|
16
|
+
const graphRecord = graph;
|
|
17
|
+
const metadata = isPlainObject(graphRecord.metadata) ? graphRecord.metadata : undefined;
|
|
18
|
+
const graphResponse = metadata && isPlainObject(metadata.graphResponse) ? metadata.graphResponse : undefined;
|
|
19
|
+
const legacyMapping = graphResponse && isPlainObject(graphResponse.responseMapping)
|
|
20
|
+
? graphResponse.responseMapping
|
|
21
|
+
: undefined;
|
|
22
|
+
if (graphRecord.response !== undefined || !legacyMapping) {
|
|
23
|
+
return { graph, migrated: false };
|
|
24
|
+
}
|
|
25
|
+
const next = cloneGraph(graph);
|
|
26
|
+
const nextRecord = next;
|
|
27
|
+
const response = {};
|
|
28
|
+
for (const [key, value] of Object.entries(legacyMapping)) {
|
|
29
|
+
if (LEGACY_RESPONSE_DROP_KEYS.has(key))
|
|
30
|
+
continue;
|
|
31
|
+
response[key] = value;
|
|
32
|
+
}
|
|
33
|
+
if (!Object.prototype.hasOwnProperty.call(response, 'missing')) {
|
|
34
|
+
response.missing = 'omit';
|
|
35
|
+
}
|
|
36
|
+
nextRecord.response = response;
|
|
37
|
+
if (isPlainObject(nextRecord.metadata)) {
|
|
38
|
+
delete nextRecord.metadata.graphResponse;
|
|
39
|
+
}
|
|
40
|
+
return { graph: next, migrated: true };
|
|
41
|
+
}
|
|
42
|
+
export function migrateLegacyGraphResponse(graph) {
|
|
43
|
+
return migrateLegacyGraphResponseDefinition(graph);
|
|
44
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Job } from '../types/refs.js';
|
|
2
|
+
export type GraphEngineXynthesizedState = {
|
|
3
|
+
job: Record<string, unknown>;
|
|
4
|
+
taskByNode: Record<string, Record<string, unknown>>;
|
|
5
|
+
execution: Record<string, unknown>;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Ensures internal execution shape for xynthesized graph memory and caller `inputs` bag seeding.
|
|
9
|
+
*/
|
|
10
|
+
export declare function seedGraphRunExecutionState(args: {
|
|
11
|
+
execution: Record<string, unknown>;
|
|
12
|
+
jobMemory: Record<string, unknown>;
|
|
13
|
+
job?: Job;
|
|
14
|
+
}): void;
|
|
15
|
+
/** Outbound {@link XynthesizedMemory} for ai-tasks `xynthesized` field. */
|
|
16
|
+
export declare function xynthesizedOutboundForNode(execution: Record<string, unknown>, nodeId: string): {
|
|
17
|
+
job: Record<string, unknown>;
|
|
18
|
+
task: Record<string, unknown>;
|
|
19
|
+
execution: Record<string, unknown>;
|
|
20
|
+
};
|
|
21
|
+
export declare function mergeXynthesizedPatchIntoExecution(args: {
|
|
22
|
+
execution: Record<string, unknown>;
|
|
23
|
+
nodeId: string;
|
|
24
|
+
patch: {
|
|
25
|
+
job?: Record<string, unknown>;
|
|
26
|
+
task?: Record<string, unknown>;
|
|
27
|
+
execution?: Record<string, unknown>;
|
|
28
|
+
} | undefined | null;
|
|
29
|
+
}): void;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { extractCallerInputsBag } from './resolveGraphEngineMemoryPaths.js';
|
|
2
|
+
import { deepMerge } from './deepMerge.js';
|
|
3
|
+
function isPlainObject(v) {
|
|
4
|
+
return v != null && typeof v === 'object' && !Array.isArray(v);
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Ensures internal execution shape for xynthesized graph memory and caller `inputs` bag seeding.
|
|
8
|
+
*/
|
|
9
|
+
export function seedGraphRunExecutionState(args) {
|
|
10
|
+
const { execution, jobMemory } = args;
|
|
11
|
+
ensureXynthesizedOnExecution(execution);
|
|
12
|
+
const callerInputs = extractCallerInputsBag({ execution, jobMemory });
|
|
13
|
+
if (callerInputs != null && !isPlainObject(execution.inputs)) {
|
|
14
|
+
execution.inputs = { ...callerInputs };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** Outbound {@link XynthesizedMemory} for ai-tasks `xynthesized` field. */
|
|
18
|
+
export function xynthesizedOutboundForNode(execution, nodeId) {
|
|
19
|
+
const xy = execution.xynthesized;
|
|
20
|
+
const job = (xy?.job != null && typeof xy.job === 'object' && !Array.isArray(xy.job) ? xy.job : {});
|
|
21
|
+
const task = xy?.taskByNode != null && typeof xy.taskByNode === 'object' && !Array.isArray(xy.taskByNode)
|
|
22
|
+
? xy.taskByNode[nodeId] ?? {}
|
|
23
|
+
: {};
|
|
24
|
+
const executionBucket = xy?.execution != null && typeof xy.execution === 'object' && !Array.isArray(xy.execution) ? xy.execution : {};
|
|
25
|
+
return {
|
|
26
|
+
job,
|
|
27
|
+
task: task != null && typeof task === 'object' && !Array.isArray(task) ? task : {},
|
|
28
|
+
execution: executionBucket,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function ensureXynthesizedOnExecution(execution) {
|
|
32
|
+
let xy = execution.xynthesized;
|
|
33
|
+
if (!isPlainObject(xy)) {
|
|
34
|
+
xy = {};
|
|
35
|
+
execution.xynthesized = xy;
|
|
36
|
+
}
|
|
37
|
+
const xyo = xy;
|
|
38
|
+
if (!isPlainObject(xyo.job))
|
|
39
|
+
xyo.job = {};
|
|
40
|
+
if (!isPlainObject(xyo.taskByNode))
|
|
41
|
+
xyo.taskByNode = {};
|
|
42
|
+
if (!isPlainObject(xyo.execution))
|
|
43
|
+
xyo.execution = {};
|
|
44
|
+
return xyo;
|
|
45
|
+
}
|
|
46
|
+
export function mergeXynthesizedPatchIntoExecution(args) {
|
|
47
|
+
const { execution, nodeId, patch } = args;
|
|
48
|
+
if (patch == null || typeof patch !== 'object')
|
|
49
|
+
return;
|
|
50
|
+
const xy = ensureXynthesizedOnExecution(execution);
|
|
51
|
+
if (patch.job != null && typeof patch.job === 'object' && !Array.isArray(patch.job)) {
|
|
52
|
+
xy.job = deepMerge(xy.job ?? {}, patch.job);
|
|
53
|
+
}
|
|
54
|
+
if (patch.task != null && typeof patch.task === 'object' && !Array.isArray(patch.task)) {
|
|
55
|
+
const prev = xy.taskByNode[nodeId] ?? {};
|
|
56
|
+
xy.taskByNode[nodeId] = deepMerge(prev, patch.task);
|
|
57
|
+
}
|
|
58
|
+
if (patch.execution != null && typeof patch.execution === 'object' && !Array.isArray(patch.execution)) {
|
|
59
|
+
xy.execution = deepMerge(xy.execution ?? {}, patch.execution);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-supplied correlation id for a single graph run (queue/matrix/job id from outside this package).
|
|
3
|
+
* Must be non-empty after trim.
|
|
4
|
+
*/
|
|
5
|
+
export declare function assertHostJobId(jobId: unknown): string;
|
|
6
|
+
/** One UUID per `executeGraph` invocation — forwarded on every `runTask` as `taskId` and on graph/node events. */
|
|
7
|
+
export declare function newGraphRunTaskId(): string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { ExellixGraphError } from "../errors/ExellixGraphError.js";
|
|
3
|
+
import { ExellixGraphErrorCode } from "../errors/exellixGraphErrorCodes.js";
|
|
4
|
+
/**
|
|
5
|
+
* Host-supplied correlation id for a single graph run (queue/matrix/job id from outside this package).
|
|
6
|
+
* Must be non-empty after trim.
|
|
7
|
+
*/
|
|
8
|
+
export function assertHostJobId(jobId) {
|
|
9
|
+
const s = jobId == null ? "" : String(jobId).trim();
|
|
10
|
+
if (!s) {
|
|
11
|
+
throw new ExellixGraphError(ExellixGraphErrorCode.JOB_ID_REQUIRED, "executeGraph requires a non-empty host `jobId` string.", {});
|
|
12
|
+
}
|
|
13
|
+
return s;
|
|
14
|
+
}
|
|
15
|
+
/** One UUID per `executeGraph` invocation — forwarded on every `runTask` as `taskId` and on graph/node events. */
|
|
16
|
+
export function newGraphRunTaskId() {
|
|
17
|
+
return randomUUID();
|
|
18
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deterministic-rule — local deterministic skill.
|
|
3
|
+
*
|
|
4
|
+
* Evaluates a rule table against executionMemory (or a custom root path) and returns
|
|
5
|
+
* the first matching rule's output, a full evaluation trace, and optional sensitivity
|
|
6
|
+
* analysis for UNKNOWN-tagged inputs (DQ-1 swing calculation).
|
|
7
|
+
*
|
|
8
|
+
* Node config (in node.taskConfiguration):
|
|
9
|
+
* rules : Rule[] — ordered list of rules
|
|
10
|
+
* firstMatchWins : boolean — default true; when false all matching rules fire
|
|
11
|
+
* defaultOutput : object? — emitted when no rule matches
|
|
12
|
+
* sensitivityAnalysis : SensitivityAnalysisConfig? — only used by DQ-1
|
|
13
|
+
*
|
|
14
|
+
* Each rule:
|
|
15
|
+
* id : string
|
|
16
|
+
* label? : string — human-readable description
|
|
17
|
+
* condition : Condition — nested logical condition
|
|
18
|
+
* output : Record<string,unknown> — merged into result when this rule fires
|
|
19
|
+
* stopOnMatch? : boolean — default true (respected when firstMatchWins=true)
|
|
20
|
+
*
|
|
21
|
+
* Condition operators (leaf):
|
|
22
|
+
* { path, eq } — strict equality
|
|
23
|
+
* { path, in } — value in array
|
|
24
|
+
* { path, gte } — >= number
|
|
25
|
+
* { path, gt } — > number
|
|
26
|
+
* { path, lte } — <= number
|
|
27
|
+
* { path, lt } — < number
|
|
28
|
+
* { path, exists } — boolean (truthy check when true, falsy check when false)
|
|
29
|
+
* { path, contains } — string or array contains value
|
|
30
|
+
* { path, regex } — string matches pattern
|
|
31
|
+
* Compound:
|
|
32
|
+
* { all: Condition[] }
|
|
33
|
+
* { any: Condition[] }
|
|
34
|
+
* { not: Condition }
|
|
35
|
+
*
|
|
36
|
+
* Output:
|
|
37
|
+
* {
|
|
38
|
+
* matched : boolean
|
|
39
|
+
* rule_id : string | null
|
|
40
|
+
* rule_label : string | null
|
|
41
|
+
* output : Record<string,unknown>
|
|
42
|
+
* evaluation_trace : { ruleId, matched, shortCircuited }[]
|
|
43
|
+
* sensitivity? : SensitivityResult — only when sensitivityAnalysis is configured
|
|
44
|
+
* }
|
|
45
|
+
*/
|
|
46
|
+
import { type ResolveDotPathOpts } from './utils.js';
|
|
47
|
+
export type LeafCondition = {
|
|
48
|
+
path: string;
|
|
49
|
+
eq: unknown;
|
|
50
|
+
} | {
|
|
51
|
+
path: string;
|
|
52
|
+
in: unknown[];
|
|
53
|
+
} | {
|
|
54
|
+
path: string;
|
|
55
|
+
gte: number;
|
|
56
|
+
} | {
|
|
57
|
+
path: string;
|
|
58
|
+
gt: number;
|
|
59
|
+
} | {
|
|
60
|
+
path: string;
|
|
61
|
+
lte: number;
|
|
62
|
+
} | {
|
|
63
|
+
path: string;
|
|
64
|
+
lt: number;
|
|
65
|
+
} | {
|
|
66
|
+
path: string;
|
|
67
|
+
exists: boolean;
|
|
68
|
+
} | {
|
|
69
|
+
path: string;
|
|
70
|
+
contains: unknown;
|
|
71
|
+
} | {
|
|
72
|
+
path: string;
|
|
73
|
+
regex: string;
|
|
74
|
+
};
|
|
75
|
+
export type Condition = LeafCondition | {
|
|
76
|
+
all: Condition[];
|
|
77
|
+
} | {
|
|
78
|
+
any: Condition[];
|
|
79
|
+
} | {
|
|
80
|
+
not: Condition;
|
|
81
|
+
};
|
|
82
|
+
export type Rule = {
|
|
83
|
+
id: string;
|
|
84
|
+
label?: string;
|
|
85
|
+
condition: Condition;
|
|
86
|
+
output: Record<string, unknown>;
|
|
87
|
+
};
|
|
88
|
+
export type SensitivityAnalysisConfig = {
|
|
89
|
+
/**
|
|
90
|
+
* Dot-path into executionMemory where the unknowns array lives.
|
|
91
|
+
* Each unknown must have: { id, tag, up_substitute, down_substitute }
|
|
92
|
+
* and a path where the substitute should be injected for the re-run.
|
|
93
|
+
*/
|
|
94
|
+
unknownsPath: string;
|
|
95
|
+
/**
|
|
96
|
+
* The field in the rule output that holds the priority value for swing calculation.
|
|
97
|
+
* e.g. "priority"
|
|
98
|
+
*/
|
|
99
|
+
priorityField: string;
|
|
100
|
+
/**
|
|
101
|
+
* Ordered array of priority values from highest to lowest.
|
|
102
|
+
* e.g. ["P1","P2","P3","P4","CLOSE"]
|
|
103
|
+
* Swing = |rank(up_result) - rank(down_result)|
|
|
104
|
+
*/
|
|
105
|
+
priorityRank: string[];
|
|
106
|
+
};
|
|
107
|
+
export type SensitivityEntry = {
|
|
108
|
+
unknown_id: string;
|
|
109
|
+
up_substitute: unknown;
|
|
110
|
+
down_substitute: unknown;
|
|
111
|
+
up_priority: string | null;
|
|
112
|
+
down_priority: string | null;
|
|
113
|
+
swing: number;
|
|
114
|
+
};
|
|
115
|
+
export type SensitivityResult = {
|
|
116
|
+
any_high_swing: boolean;
|
|
117
|
+
entries: SensitivityEntry[];
|
|
118
|
+
};
|
|
119
|
+
export type DeterministicRuleOutput = {
|
|
120
|
+
matched: boolean;
|
|
121
|
+
rule_id: string | null;
|
|
122
|
+
rule_label: string | null;
|
|
123
|
+
output: Record<string, unknown>;
|
|
124
|
+
evaluation_trace: Array<{
|
|
125
|
+
ruleId: string;
|
|
126
|
+
matched: boolean;
|
|
127
|
+
shortCircuited?: boolean;
|
|
128
|
+
}>;
|
|
129
|
+
sensitivity?: SensitivityResult;
|
|
130
|
+
};
|
|
131
|
+
export type DeterministicRuleConfig = {
|
|
132
|
+
rules: Rule[];
|
|
133
|
+
firstMatchWins?: boolean;
|
|
134
|
+
defaultOutput?: Record<string, unknown>;
|
|
135
|
+
sensitivityAnalysis?: SensitivityAnalysisConfig;
|
|
136
|
+
};
|
|
137
|
+
export declare function runDeterministicRule(cfg: DeterministicRuleConfig, executionMemory: unknown, pathOpts?: ResolveDotPathOpts): DeterministicRuleOutput;
|