@exellix/graph-engine 7.5.1 → 7.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/src/errors/exellixGraphErrorCodes.d.ts +2 -0
  2. package/dist/src/errors/exellixGraphErrorCodes.js +2 -0
  3. package/dist/src/index.d.ts +3 -2
  4. package/dist/src/index.js +3 -2
  5. package/dist/src/inspection/graphModelSelection.d.ts +3 -3
  6. package/dist/src/inspection/graphModelSelection.js +2 -2
  7. package/dist/src/runtime/ExellixGraphRuntime.d.ts +6 -17
  8. package/dist/src/runtime/ExellixGraphRuntime.js +49 -34
  9. package/dist/src/runtime/aiTasksStrategyPhases.d.ts +2 -5
  10. package/dist/src/runtime/aiTasksStrategyPhases.js +2 -5
  11. package/dist/src/runtime/buildAiTasksRunTaskRequest.d.ts +2 -2
  12. package/dist/src/runtime/buildAiTasksRunTaskRequest.js +1 -1
  13. package/dist/src/runtime/canonicalModelUsed.js +1 -2
  14. package/dist/src/runtime/graphAiModelConfig.d.ts +7 -11
  15. package/dist/src/runtime/graphAiModelConfig.js +9 -33
  16. package/dist/src/runtime/mergeExellixGraphRuntimeInvocation.js +0 -4
  17. package/dist/src/runtime/resolveModelConfigForNode.d.ts +4 -7
  18. package/dist/src/runtime/resolveModelConfigForNode.js +4 -9
  19. package/dist/src/runtime/runTaskAugments.d.ts +7 -0
  20. package/dist/src/runtime/runTaskAugments.js +12 -3
  21. package/dist/src/runtime/taskNodeRunTaskPreflight.d.ts +3 -8
  22. package/dist/src/runtime/taskNodeRunTaskPreflight.js +5 -5
  23. package/dist/src/runtime/validateCanonicalGraphRuntime.d.ts +16 -0
  24. package/dist/src/runtime/validateCanonicalGraphRuntime.js +35 -0
  25. package/dist/src/types/options.d.ts +2 -10
  26. package/dist/src/types/refs.d.ts +4 -10
  27. package/dist/testkit/index.d.ts +1 -1
  28. package/dist/testkit/index.js +1 -1
  29. package/dist/testkit/testModelAliasRuntime.d.ts +2 -9
  30. package/dist/testkit/testModelAliasRuntime.js +1 -9
  31. package/package.json +3 -4
@@ -13,6 +13,8 @@ export declare enum ExellixGraphErrorCode {
13
13
  INVALID_GRAPH = "INVALID_GRAPH",
14
14
  /** Graph JSON has forbidden top-level keys; document metadata must be under `metadata` only. */
15
15
  NON_CANONICAL_GRAPH_DOCUMENT = "NON_CANONICAL_GRAPH_DOCUMENT",
16
+ /** Runtime object carries forbidden model / llmCall overrides (graph document only since 7.7). */
17
+ NON_CANONICAL_GRAPH_RUNTIME = "NON_CANONICAL_GRAPH_RUNTIME",
16
18
  /**
17
19
  * A task node uses a legacy authoring alias that 5.x rejects at load time.
18
20
  * Examples: `node.data.skillKey`, `node.metadata.skillKey`, `node.data.variables`,
@@ -14,6 +14,8 @@ export var ExellixGraphErrorCode;
14
14
  ExellixGraphErrorCode["INVALID_GRAPH"] = "INVALID_GRAPH";
15
15
  /** Graph JSON has forbidden top-level keys; document metadata must be under `metadata` only. */
16
16
  ExellixGraphErrorCode["NON_CANONICAL_GRAPH_DOCUMENT"] = "NON_CANONICAL_GRAPH_DOCUMENT";
17
+ /** Runtime object carries forbidden model / llmCall overrides (graph document only since 7.7). */
18
+ ExellixGraphErrorCode["NON_CANONICAL_GRAPH_RUNTIME"] = "NON_CANONICAL_GRAPH_RUNTIME";
17
19
  /**
18
20
  * A task node uses a legacy authoring alias that 5.x rejects at load time.
19
21
  * Examples: `node.data.skillKey`, `node.metadata.skillKey`, `node.data.variables`,
@@ -39,7 +39,7 @@ export type { PathSegment } from './runtime/pathExpr.js';
39
39
  export { evaluateStructuredDataFilters, evaluateDataFilterPredicate, getStructuredDataFilterPathViolations, isStructuredDataFiltersV1, } from './runtime/dataFiltersEvaluation.js';
40
40
  export { evaluateTaskNodeConditions, evaluateConditionWhen, applyConditionNegate, } from './runtime/taskNodeConditionsEvaluation.js';
41
41
  export type { TaskNodeConditionsEvalDeps, TaskNodeConditionsEvalResult, TaskNodeConditionEvalContext, } from './runtime/taskNodeConditionsEvaluation.js';
42
- export { resolveModelConfigForNode, resolveGraphAiModelConfig, toRunTaskModelConfigForPhase, DEFAULT_GRAPH_AI_MODEL_IDS, DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, } from './runtime/resolveModelConfigForNode.js';
42
+ export { resolveModelConfigForNode, resolveGraphAiModelConfig, toRunTaskModelConfig, DEFAULT_GRAPH_AI_MODEL_IDS, DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, } from './runtime/resolveModelConfigForNode.js';
43
43
  export { looksLikeConcreteModelId, isGraphAiProfileName, assertGraphAiProfileNameString, type RunTaskModelConfigWire, type EngineModelPhase, } from './runtime/graphAiModelConfig.js';
44
44
  /** @deprecated Use {@link resolveGraphAiModelConfig}. */
45
45
  export { resolveGraphAiModelConfig as resolveGraphAiModelConfigAliases } from './runtime/graphAiModelConfig.js';
@@ -73,12 +73,13 @@ export { runTaskResponseSucceeded } from './runtime/runTaskResponse.js';
73
73
  export { buildTaskNodeRunTaskRequest, validateTaskNodeRunTaskConfig, validateTaskNodeRunTaskInvoke, analyzeTaskNodeRunTaskRequest, } from './runtime/taskNodeRunTaskPreflight.js';
74
74
  export type { BuildTaskNodeRunTaskRequestArgs, BuildTaskNodeRunTaskRequestResult, TaskNodeRunTaskPreflightSkipReason, ValidateTaskNodeRunTaskConfigArgs, ValidateTaskNodeRunTaskConfigResult, ValidateTaskNodeRunTaskInvokeArgs, ValidateTaskNodeRunTaskInvokeResult, AnalyzeTaskNodeRunTaskRequestArgs, AnalyzeTaskNodeRunTaskRequestResult, } from './runtime/taskNodeRunTaskPreflight.js';
75
75
  /** Re-exported from `@exellix/ai-tasks` — preflight validation and analysis without `runTask`. */
76
- export { validateRunTaskConfig, validateRunTaskInvoke, analyzeExpectedRunTaskInput, checkExpectedInputAgainstRequest, collectSmartInputValidationIssues, buildRunTaskValidationContext, analyzeRunTaskRequest, validateParsedOutput, analyzeSkillRequest, buildSkillRequestAnalysisPacket, formatSkillRequestAnalysisMarkdown, listTokens, analyzeTemplateResolution, renderSmartInput, extractTokenNamesFromStrings, getSkillTokens, getSkillContent, } from '@exellix/ai-tasks';
76
+ export { validateRunTaskConfig, validateRunTaskInvoke, analyzeExpectedRunTaskInput, checkExpectedInputAgainstRequest, collectSmartInputValidationIssues, buildRunTaskValidationContext, analyzeRunTaskRequest, validateParsedOutput, buildSkillRequestAnalysisPacket, formatSkillRequestAnalysisMarkdown, listTokens, analyzeTemplateResolution, renderSmartInput, extractTokenNamesFromStrings, getSkillTokens, getSkillContent, } from '@exellix/ai-tasks';
77
77
  export type { RunTaskValidationIssue, RunTaskValidationResult, RunTaskInvokeValidationResult, ExpectedRunTaskInputPath, AnalyzeExpectedRunTaskInputResult, ValidateRunTaskInvokeParams, RunTaskTemplateResolver, AnalyzeRunTaskRequestOptions, AnalyzeRunTaskRequestResult, AnalyzeSkillRequestOptions, AnalyzeSkillRequestResult, SkillRequestAnalysisReport, OutputValidationResult, } from '@exellix/ai-tasks';
78
78
  export { buildExellixGraphRuntimeObjects, setRuntimeObjectsLastJobId, summarizeRuntimeObjectsForPlayground, EXELLIX_GRAPH_RUNTIME_PACKAGE_NAME, EXELLIX_AI_TASKS_PACKAGE_NAME, } from './runtime/runtimeObjects.js';
79
79
  export type { ActivixQueryableClient, LogxerQueryableClient, LogxerLogLine, PackageRuntimeObjects, RuntimeObjects, BuildExellixGraphRuntimeObjectsInput, RuntimeObjectsObservabilitySummary, } from './runtime/runtimeObjects.js';
80
80
  export type { GetJobLogsInput, GetJobLogsResult, QueryableLogLine } from '@x12i/logxer';
81
81
  export { assertCanonicalGraphDocument, assertCanonicalTaskNode, getCanonicalGraphDocumentViolations, CANONICAL_GRAPH_TOP_LEVEL_KEYS, } from './runtime/validateCanonicalGraphDocument.js';
82
+ export { assertCanonicalGraphRuntimeObject } from './runtime/validateCanonicalGraphRuntime.js';
82
83
  export { GRAPH_ENTRY_STUDIO_ONLY_KEYS, GRAPH_METADATA_STUDIO_ONLY_KEYS, stripGraphModelStudioFields, primaryRuntimeInputFromStudioDocument, getGraphEntryStudioOnlyKeyViolations, getGraphMetadataStudioOnlyKeyViolations, getGraphEntryEmptyInputPathViolations, } from './runtime/graphModelStudioSeparation.js';
83
84
  export type { GraphStudioDocument } from './runtime/graphModelStudioSeparation.js';
84
85
  export { computeGraphDocumentContentSha256, stableStringifyGraphDocument, } from './runtime/graphDocumentFingerprint.js';
package/dist/src/index.js CHANGED
@@ -29,7 +29,7 @@ export { mergeMemory } from './runtime/memory.js';
29
29
  export { selectByPath, writeByPath, parsePath } from './runtime/pathExpr.js';
30
30
  export { evaluateStructuredDataFilters, evaluateDataFilterPredicate, getStructuredDataFilterPathViolations, isStructuredDataFiltersV1, } from './runtime/dataFiltersEvaluation.js';
31
31
  export { evaluateTaskNodeConditions, evaluateConditionWhen, applyConditionNegate, } from './runtime/taskNodeConditionsEvaluation.js';
32
- export { resolveModelConfigForNode, resolveGraphAiModelConfig, toRunTaskModelConfigForPhase, DEFAULT_GRAPH_AI_MODEL_IDS, DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, } from './runtime/resolveModelConfigForNode.js';
32
+ export { resolveModelConfigForNode, resolveGraphAiModelConfig, toRunTaskModelConfig, DEFAULT_GRAPH_AI_MODEL_IDS, DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, } from './runtime/resolveModelConfigForNode.js';
33
33
  export { looksLikeConcreteModelId, isGraphAiProfileName, assertGraphAiProfileNameString, } from './runtime/graphAiModelConfig.js';
34
34
  /** @deprecated Use {@link resolveGraphAiModelConfig}. */
35
35
  export { resolveGraphAiModelConfig as resolveGraphAiModelConfigAliases } from './runtime/graphAiModelConfig.js';
@@ -56,9 +56,10 @@ export { resolveNarrixForTaskNode } from './runtime/resolveNarrixForTaskNode.js'
56
56
  export { runTaskResponseSucceeded } from './runtime/runTaskResponse.js';
57
57
  export { buildTaskNodeRunTaskRequest, validateTaskNodeRunTaskConfig, validateTaskNodeRunTaskInvoke, analyzeTaskNodeRunTaskRequest, } from './runtime/taskNodeRunTaskPreflight.js';
58
58
  /** Re-exported from `@exellix/ai-tasks` — preflight validation and analysis without `runTask`. */
59
- export { validateRunTaskConfig, validateRunTaskInvoke, analyzeExpectedRunTaskInput, checkExpectedInputAgainstRequest, collectSmartInputValidationIssues, buildRunTaskValidationContext, analyzeRunTaskRequest, validateParsedOutput, analyzeSkillRequest, buildSkillRequestAnalysisPacket, formatSkillRequestAnalysisMarkdown, listTokens, analyzeTemplateResolution, renderSmartInput, extractTokenNamesFromStrings, getSkillTokens, getSkillContent, } from '@exellix/ai-tasks';
59
+ export { validateRunTaskConfig, validateRunTaskInvoke, analyzeExpectedRunTaskInput, checkExpectedInputAgainstRequest, collectSmartInputValidationIssues, buildRunTaskValidationContext, analyzeRunTaskRequest, validateParsedOutput, buildSkillRequestAnalysisPacket, formatSkillRequestAnalysisMarkdown, listTokens, analyzeTemplateResolution, renderSmartInput, extractTokenNamesFromStrings, getSkillTokens, getSkillContent, } from '@exellix/ai-tasks';
60
60
  export { buildExellixGraphRuntimeObjects, setRuntimeObjectsLastJobId, summarizeRuntimeObjectsForPlayground, EXELLIX_GRAPH_RUNTIME_PACKAGE_NAME, EXELLIX_AI_TASKS_PACKAGE_NAME, } from './runtime/runtimeObjects.js';
61
61
  export { assertCanonicalGraphDocument, assertCanonicalTaskNode, getCanonicalGraphDocumentViolations, CANONICAL_GRAPH_TOP_LEVEL_KEYS, } from './runtime/validateCanonicalGraphDocument.js';
62
+ export { assertCanonicalGraphRuntimeObject } from './runtime/validateCanonicalGraphRuntime.js';
62
63
  export { GRAPH_ENTRY_STUDIO_ONLY_KEYS, GRAPH_METADATA_STUDIO_ONLY_KEYS, stripGraphModelStudioFields, primaryRuntimeInputFromStudioDocument, getGraphEntryStudioOnlyKeyViolations, getGraphMetadataStudioOnlyKeyViolations, getGraphEntryEmptyInputPathViolations, } from './runtime/graphModelStudioSeparation.js';
63
64
  export { computeGraphDocumentContentSha256, stableStringifyGraphDocument, } from './runtime/graphDocumentFingerprint.js';
64
65
  export { migrateLegacyGraphResponse, migrateLegacyGraphResponseDefinition, } from './runtime/graphResponseMigration.js';
@@ -16,8 +16,8 @@ export type GraphModelSelectionInspection = {
16
16
  /** Graph-level default profile aliases (undefined when the graph declares none). */
17
17
  graphDefaultProfiles?: GraphAiModelConfig;
18
18
  nodes: NodeModelSelection[];
19
- /** Distinct profile alias names referenced anywhere in the model (for `runtime.aliasConfig` wiring). */
20
- aliasesUsed: string[];
19
+ /** Distinct profile alias names referenced anywhere in the graph model document. */
20
+ profileNamesUsed: string[];
21
21
  };
22
22
  /**
23
23
  * Static, runtime-free view of which model-profile aliases each node would use.
@@ -28,6 +28,6 @@ export type GraphModelSelectionInspection = {
28
28
  *
29
29
  * Only the unconditional (`when`-less) default case is reported per tier; `conditionalCaseCount`
30
30
  * flags nodes whose effective model may change at runtime via gated cases. Alias → concrete
31
- * provider id still happens at runtime through `runtime.aliasConfig`.
31
+ * provider id resolution happens inside `@exellix/ai-tasks`.
32
32
  */
33
33
  export declare function inspectGraphModelSelection(graph: Graph): GraphModelSelectionInspection;
@@ -33,7 +33,7 @@ function finalizerUsesModel(node) {
33
33
  *
34
34
  * Only the unconditional (`when`-less) default case is reported per tier; `conditionalCaseCount`
35
35
  * flags nodes whose effective model may change at runtime via gated cases. Alias → concrete
36
- * provider id still happens at runtime through `runtime.aliasConfig`.
36
+ * provider id resolution happens inside `@exellix/ai-tasks`.
37
37
  */
38
38
  export function inspectGraphModelSelection(graph) {
39
39
  const graphDefaultProfiles = defaultCaseProfiles(graph.modelConfig);
@@ -103,6 +103,6 @@ export function inspectGraphModelSelection(graph) {
103
103
  return {
104
104
  graphDefaultProfiles,
105
105
  nodes,
106
- aliasesUsed: [...aliases].sort(),
106
+ profileNamesUsed: [...aliases].sort(),
107
107
  };
108
108
  }
@@ -1,12 +1,11 @@
1
1
  import type { GraphEngineFactory } from "./GraphEngine.js";
2
2
  import type { ExecutionStep } from "@exellix/ai-tasks";
3
- import type { Graph, GraphModelObject, GraphNode, GraphAiModelConfig, GraphModelAliasConfig, TaskNodeRuntimeObject } from "../types/refs.js";
3
+ import type { Graph, GraphModelObject, GraphNode, GraphAiModelConfig, TaskNodeRuntimeObject } from "../types/refs.js";
4
4
  import type { RunLogEntry } from "../types/runLog.js";
5
5
  import type { RunTaskDiagnostics } from "../types/options.js";
6
6
  import type { ExecutionStepOption, HostExecuteGraphRunOptions, SkillKeyResolutionOptions } from "../types/options.js";
7
7
  import type { PlaygroundReporter } from "../playground/PlaygroundReporter.js";
8
8
  import type { CreateRunxOptions, RunxClient } from "@x12i/runx";
9
- import type { ModelConfigSelection } from "../types/refs.js";
10
9
  import { type EventEmitter } from "./events.js";
11
10
  import type { NodeTraceEntry } from "../types/results.js";
12
11
  import type { ExecuteGraphStepResponse } from "../types/results.js";
@@ -89,15 +88,7 @@ export interface GraphRuntimeObject extends HostExecuteGraphRunOptions {
89
88
  jobVariables?: Record<string, unknown>;
90
89
  /** Task-scoped overrides for the active node → `executionMemory.taskVariables`. */
91
90
  taskVariables?: Record<string, unknown>;
92
- /** Runtime default model selection (`cases`); overrides GraphModelObject.modelConfig. */
93
- modelConfig?: ModelConfigSelection;
94
- /** Profile aliases for xynthesis when runtime.modelConfig is host-resolved concrete ids. */
95
- aiProfiles?: GraphAiModelConfig;
96
- /**
97
- * @deprecated Unused since 7.1 — profile aliases pass through to downstream resolution.
98
- */
99
- aliasConfig?: GraphModelAliasConfig;
100
- /** Task-node runtime overrides keyed by node id. */
91
+ /** Task-node runtime bag keyed by node id (no model overrides since 7.7). */
101
92
  nodes?: Record<string, TaskNodeRuntimeObject>;
102
93
  mode?: "forward" | "backward" | "hybrid";
103
94
  goalNodeId?: string;
@@ -197,9 +188,8 @@ export declare function createExellixGraphRuntime(opts: ExellixGraphRuntimeOptio
197
188
  executeGraph: (input: ExecuteGraphInput) => Promise<ExecuteGraphResult>;
198
189
  executeNode: (input: {
199
190
  graphId: string;
191
+ /** Graph document for standalone {@link executeNode} — resolves {@link modelConfig} from the model when omitted. */
200
192
  graph?: Graph;
201
- /** Same UUID for every `runTask` in this `executeGraph` invocation; omitted → new UUID per direct `executeNode` call. */
202
- graphRunTaskId?: string;
203
193
  node: any;
204
194
  job: any;
205
195
  jobMemory?: any;
@@ -210,11 +200,10 @@ export declare function createExellixGraphRuntime(opts: ExellixGraphRuntimeOptio
210
200
  /** Per-node task-scope overrides → `executionMemory.taskVariables`. */
211
201
  taskVariables?: Record<string, unknown>;
212
202
  prevNodeId?: string;
213
- /** Overrides graph-level / runtime default for this node only. */
203
+ /** Resolved graph model profiles; omitted when {@link graph} is supplied (resolved from the model document). */
214
204
  modelConfig?: GraphAiModelConfig;
215
- /** Profile aliases for xynthesis PRE/POST when modelConfig is host-resolved concrete ids. */
216
- aiProfiles?: GraphAiModelConfig;
217
- llmCall?: Record<string, unknown>;
205
+ /** Same UUID for every `runTask` in this `executeGraph` invocation; omitted → new UUID per direct `executeNode` call. */
206
+ graphRunTaskId?: string;
218
207
  runTaskIdentity?: Record<string, unknown>;
219
208
  runTaskExecutionMode?: "default" | "trace";
220
209
  runTaskDiagnostics?: RunTaskDiagnostics;
@@ -17,11 +17,12 @@ import { assertFinalizerRequiredReadsResolvable, validateGraphFinalizer, } from
17
17
  import { executeDeterministicFinalizer, executeSynthesizeFinalizer } from "./finalizers/executeFinalizer.js";
18
18
  import { createFinalizerError } from "./finalizers/errors.js";
19
19
  import { assertCanonicalGraphDocument } from "./validateCanonicalGraphDocument.js";
20
+ import { assertCanonicalGraphRuntimeObject } from "./validateCanonicalGraphRuntime.js";
20
21
  import { applyGraphResponseDefinition } from "./graphResponseMapping.js";
21
22
  import { migrateLegacyGraphResponse } from "./graphResponseMigration.js";
22
23
  import { computeGraphDocumentContentSha256 } from "./graphDocumentFingerprint.js";
23
24
  import { buildAiTasksObservabilityRecord } from "./aiTasksObservability.js";
24
- import { buildRunTaskIdentityEnvelope, mergeDefinedLlmCallParts, shouldForwardRunTaskTraceMode, } from "./runTaskAugments.js";
25
+ import { buildMainLlmCallForRunTask, buildRunTaskIdentityEnvelope, shouldForwardRunTaskTraceMode, } from "./runTaskAugments.js";
25
26
  import { buildRunLog, extractLogxerCorrelationFromMetadata, extractTaskRunLogFromMetadata, resolveRunLogLimits, } from "./buildRunLog.js";
26
27
  import { setRuntimeObjectsLastJobId, summarizeRuntimeObjectsForPlayground } from "./runtimeObjects.js";
27
28
  import { DebugLogAbstract, bindGraphEngineRunLogxer, clearGraphEngineRunLogxer, createGraphEngineLogxer, ensureGraphEngineLogxerOnRuntimeObjects, logGraphEngineErrorCode, patchGraphNodeLogContext, runGraphWithLogContext, traceExecutionMemory, } from "./graphEngineLogxer.js";
@@ -36,10 +37,13 @@ import { evaluateGraphPredicate } from "./predicates.js";
36
37
  import { evaluateStructuredDataFilters } from "./dataFiltersEvaluation.js";
37
38
  import { evaluateTaskNodeConditions } from "./taskNodeConditionsEvaluation.js";
38
39
  import { resolveModelConfigForNode } from "./resolveModelConfigForNode.js";
39
- import { toRunTaskModelConfigForPhase } from "./graphAiModelConfig.js";
40
+ import { toRunTaskModelConfig } from "./graphAiModelConfig.js";
41
+ import { isGraphAiModelConfig } from "./modelConfigSelection.js";
42
+ import { createClient } from "@x12i/funcx";
40
43
  import { createRunx } from "@x12i/runx";
41
44
  import { selectByPath } from "./pathExpr.js";
42
45
  import { createGraphStartEvent, createGraphCompleteEvent, createGraphFailEvent, createNodeStartEvent, createNodeCompleteEvent, createNodeFailEvent, } from "./events.js";
46
+ import { ExellixGraphError } from "../errors/ExellixGraphError.js";
43
47
  import { ExellixGraphErrorCode } from "../errors/exellixGraphErrorCodes.js";
44
48
  const NODE_LIFECYCLE_EMITTED = "__exellixNodeLifecycleEmitted";
45
49
  function skippedByConditionsOutput(skipReason) {
@@ -183,12 +187,6 @@ function mergeExecutionUpdate(current, next, base) {
183
187
  applyExecutionDelta(merged, next, isPlainRecord(base) ? base : {});
184
188
  return merged;
185
189
  }
186
- function readRuntimeNodeConfig(nodes, nodeId) {
187
- if (nodes == null || typeof nodeId !== "string" || nodeId.length === 0)
188
- return undefined;
189
- const candidate = nodes[nodeId];
190
- return isPlainRecord(candidate) ? candidate : undefined;
191
- }
192
190
  function taskNodeNeedsRunxClient(conditions) {
193
191
  return conditions?.jsConditionFunction != null || conditions?.aiCondition != null;
194
192
  }
@@ -197,9 +195,7 @@ function modelConfigSelectionNeedsRunx(sel) {
197
195
  return false;
198
196
  return sel.cases.some((c) => c.when?.jsConditionFunction != null || c.when?.aiCondition != null);
199
197
  }
200
- function graphNeedsRunxClient(graph, runtimeModelConfig) {
201
- if (modelConfigSelectionNeedsRunx(runtimeModelConfig))
202
- return true;
198
+ function graphNeedsRunxClient(graph) {
203
199
  if (modelConfigSelectionNeedsRunx(graph.modelConfig))
204
200
  return true;
205
201
  for (const n of graph.nodes ?? []) {
@@ -339,7 +335,37 @@ export function createExellixGraphRuntime(opts) {
339
335
  const graphRunTaskId = input.graphRunTaskId ?? newGraphRunTaskId();
340
336
  const runTaskJobIdStr = String(input.job?.jobId ?? input.job?.id ?? "");
341
337
  const lifecycleJobId = runTaskJobIdStr || String(input.job?.jobId ?? input.job?.id ?? "standalone-job");
342
- const effectiveLlmCall = mergeDefinedLlmCallParts((input.llmCall ?? opts.llmCall), input.node?.taskConfiguration?.llmCall);
338
+ let executionSeed = input.execution;
339
+ if (executionSeed == null || typeof executionSeed !== "object")
340
+ executionSeed = {};
341
+ const executionRecSeed = executionSeed;
342
+ const dataFiltersRecordSeed = isPlainRecord(executionRecSeed.input)
343
+ ? executionRecSeed.input
344
+ : {};
345
+ let effectiveModelConfig = input.modelConfig;
346
+ if (!isGraphAiModelConfig(effectiveModelConfig)) {
347
+ if (input.graph == null) {
348
+ throw new ExellixGraphError(ExellixGraphErrorCode.MODEL_CONFIG_INCOMPLETE, "executeNode requires modelConfig or graph for model resolution from the graph document", { graphId: input.graphId, nodeId: String(input.node?.id ?? "") });
349
+ }
350
+ effectiveModelConfig = await resolveModelConfigForNode({
351
+ nodeModelConfig: input.node?.taskConfiguration?.modelConfig,
352
+ graphModelConfig: input.graph.modelConfig,
353
+ conditionCtx: buildPredicateEvalContextForNode({
354
+ executionMemory: executionRecSeed,
355
+ jobMemory: input.jobMemory,
356
+ taskMemory: input.taskMemory,
357
+ node: input.node,
358
+ runtimeTaskVariables: input.taskVariables,
359
+ }),
360
+ executionInput: dataFiltersRecordSeed,
361
+ runx: opts.runx,
362
+ graphId: input.graphId,
363
+ nodeId: String(input.node?.id ?? ""),
364
+ jobId: lifecycleJobId,
365
+ });
366
+ }
367
+ const wireModelConfig = toRunTaskModelConfig(effectiveModelConfig);
368
+ const effectiveLlmCall = buildMainLlmCallForRunTask(wireModelConfig, input.node?.taskConfiguration?.llmCall);
343
369
  const forwardRunTaskTrace = shouldForwardRunTaskTraceMode({
344
370
  runTaskExecutionMode: input.runTaskExecutionMode ?? opts.runTaskExecutionMode,
345
371
  });
@@ -394,12 +420,8 @@ export function createExellixGraphRuntime(opts) {
394
420
  : {}),
395
421
  kind: "finalizer",
396
422
  },
397
- ...(input.modelConfig != null
398
- ? {
399
- modelConfig: toRunTaskModelConfigForPhase(input.modelConfig, 'pre', input.aiProfiles),
400
- }
401
- : {}),
402
- ...(effectiveLlmCall != null ? { llmCall: effectiveLlmCall } : {}),
423
+ modelConfig: wireModelConfig,
424
+ llmCall: effectiveLlmCall,
403
425
  ...(forwardRunTaskTrace ? { executionMode: "trace" } : {}),
404
426
  ...((input.runTaskDiagnostics ?? opts.runTaskDiagnostics) != null
405
427
  ? { diagnostics: input.runTaskDiagnostics ?? opts.runTaskDiagnostics }
@@ -607,10 +629,6 @@ export function createExellixGraphRuntime(opts) {
607
629
  if (input.eventEmitter) {
608
630
  input.eventEmitter.emit(createNodeStartEvent(lifecycleJobId, input.graphId, graphRunTaskId, input.node, skillKey, undefined, input.jobCorrelation));
609
631
  }
610
- const effectiveModelConfig = input.modelConfig;
611
- const mainRunTaskModelConfig = effectiveModelConfig != null
612
- ? toRunTaskModelConfigForPhase(effectiveModelConfig, 'main', input.aiProfiles)
613
- : undefined;
614
632
  // DEBUG: Verify execution object before sending
615
633
  traceExecutionMemory('executeNode', 'Node execution object before runTask', {
616
634
  nodeId: input.node?.id,
@@ -720,8 +738,6 @@ export function createExellixGraphRuntime(opts) {
720
738
  jobContext,
721
739
  prevNodeId: input.prevNodeId,
722
740
  modelConfig: effectiveModelConfig,
723
- aiProfiles: input.aiProfiles,
724
- llmCall: effectiveLlmCall,
725
741
  runTaskIdentity: runTaskIdentityBase,
726
742
  nodeTaskConfiguration: input.node?.taskConfiguration,
727
743
  forwardRunTaskTrace,
@@ -840,7 +856,7 @@ export function createExellixGraphRuntime(opts) {
840
856
  ? input.node.taskConfiguration.aiTasksOutputValidation
841
857
  : undefined,
842
858
  diagnostics: (input.runTaskDiagnostics ?? opts.runTaskDiagnostics),
843
- modelConfig: mainRunTaskModelConfig,
859
+ modelConfig: wireModelConfig,
844
860
  llmCall: effectiveLlmCall,
845
861
  identity: buildRunTaskIdentityEnvelope({
846
862
  base: runTaskIdentityBase,
@@ -1022,8 +1038,6 @@ export function createExellixGraphRuntime(opts) {
1022
1038
  jobContext,
1023
1039
  prevNodeId: input.prevNodeId,
1024
1040
  modelConfig: effectiveModelConfig,
1025
- aiProfiles: input.aiProfiles,
1026
- llmCall: effectiveLlmCall,
1027
1041
  runTaskIdentity: runTaskIdentityBase,
1028
1042
  nodeTaskConfiguration: input.node?.taskConfiguration,
1029
1043
  forwardRunTaskTrace,
@@ -1162,15 +1176,21 @@ export function createExellixGraphRuntime(opts) {
1162
1176
  bindGraphEngineRunLogxer(runLogxer);
1163
1177
  try {
1164
1178
  assertCanonicalGraphDocument(graph, { jobId, graphId: resolvedGraphId });
1179
+ assertCanonicalGraphRuntimeObject(runtime, { jobId, graphId: resolvedGraphId });
1165
1180
  let runxClient = opts.runx;
1166
- if (graphNeedsRunxClient(graph, merged.modelConfig)) {
1181
+ if (graphNeedsRunxClient(graph)) {
1167
1182
  if (!runxClient) {
1168
1183
  if (!opts.runxCreateOptions) {
1169
1184
  const err = new Error("RUNX_REQUIRED: graph uses jsConditionFunction, aiCondition, or conditional modelConfig cases that require runx. Pass runx or runxCreateOptions on createExellixGraphRuntime.");
1170
1185
  err.code = "RUNX_REQUIRED";
1171
1186
  throw err;
1172
1187
  }
1173
- runxClient = await createRunx(opts.runxCreateOptions);
1188
+ const runxOpts = {
1189
+ ...opts.runxCreateOptions,
1190
+ funcx: opts.runxCreateOptions.funcx ??
1191
+ createClient((opts.runxCreateOptions.funcxCreateOptions ?? {})),
1192
+ };
1193
+ runxClient = await createRunx(runxOpts);
1174
1194
  await runxClient.bootstrap();
1175
1195
  await runxClient.reload();
1176
1196
  }
@@ -1582,11 +1602,8 @@ export function createExellixGraphRuntime(opts) {
1582
1602
  context: { model: graph, runtime, graphId: resolvedGraphId, jobId, taskId: graphTaskId, node: node },
1583
1603
  });
1584
1604
  const nodeTaskMemory = isPlainRecord(currentTaskMemory) ? { ...currentTaskMemory } : currentTaskMemory;
1585
- const runtimeNodeConfig = readRuntimeNodeConfig(merged.nodes, typeof node.id === "string" ? node.id : undefined);
1586
1605
  const effectiveModelConfig = await resolveModelConfigForNode({
1587
- runtimeNodeConfig,
1588
1606
  nodeModelConfig: node.taskConfiguration?.modelConfig,
1589
- runtimeModelConfig: merged.modelConfig,
1590
1607
  graphModelConfig: graph.modelConfig,
1591
1608
  conditionCtx: buildPredicateEvalContextForNode({
1592
1609
  executionMemory: currentExecution,
@@ -1616,8 +1633,6 @@ export function createExellixGraphRuntime(opts) {
1616
1633
  variables: runtime.variables,
1617
1634
  taskVariables: runtime.taskVariables,
1618
1635
  modelConfig: effectiveModelConfig,
1619
- aiProfiles: merged.aiProfiles,
1620
- llmCall: merged.llmCall,
1621
1636
  runTaskIdentity: merged.runTaskIdentity,
1622
1637
  runTaskExecutionMode: merged.runTaskExecutionMode,
1623
1638
  runTaskDiagnostics: merged.runTaskDiagnostics,
@@ -25,11 +25,8 @@ export type RunEngineAiTasksStrategyPhaseArgs = {
25
25
  taskMemory?: unknown;
26
26
  jobContext?: Record<string, unknown>;
27
27
  prevNodeId?: string;
28
- /** Resolved three-phase config; routed to the correct ai-tasks slot for this strategy phase. */
29
- modelConfig?: GraphAiModelConfig;
30
- /** Profile aliases for xynthesis slots when modelConfig is host-resolved concrete ids. */
31
- aiProfiles?: GraphAiModelConfig;
32
- llmCall?: RunTaskRequest['llmCall'];
28
+ /** Resolved three-phase graph model config (required). */
29
+ modelConfig: GraphAiModelConfig;
33
30
  runTaskIdentity?: Record<string, unknown>;
34
31
  /** Task node `taskConfiguration` (identity envelope merge). */
35
32
  nodeTaskConfiguration?: Record<string, unknown>;
@@ -1,4 +1,4 @@
1
- import { toRunTaskModelConfigForPhase } from './graphAiModelConfig.js';
1
+ import { toRunTaskModelConfig } from './graphAiModelConfig.js';
2
2
  import { buildAiTasksRunTaskRequest } from './buildAiTasksRunTaskRequest.js';
3
3
  import { buildRunTaskIdentityEnvelope } from './runTaskAugments.js';
4
4
  import { runTaskResponseSucceeded } from './runTaskResponse.js';
@@ -54,10 +54,7 @@ export async function runEngineAiTasksStrategyPhase(args) {
54
54
  prevNodeId: args.prevNodeId,
55
55
  executionPipeline: [{ phase: 'main', type: 'direct' }],
56
56
  executionStrategies: [],
57
- modelConfig: args.modelConfig != null
58
- ? toRunTaskModelConfigForPhase(args.modelConfig, args.phase, args.aiProfiles)
59
- : undefined,
60
- llmCall: args.llmCall ?? undefined,
57
+ modelConfig: toRunTaskModelConfig(args.modelConfig),
61
58
  identity,
62
59
  ...(args.forwardRunTaskTrace ? { executionMode: 'trace' } : {}),
63
60
  ...(args.runTaskDiagnostics != null && { diagnostics: args.runTaskDiagnostics }),
@@ -46,8 +46,8 @@ export type BuildAiTasksRunTaskRequestArgs = {
46
46
  narrix?: ResolvedNarrixWirePayload;
47
47
  outputValidation?: RunTaskRequest['outputValidation'];
48
48
  diagnostics?: RunTaskRequest['diagnostics'];
49
- /** Resolved ai-tasks slot pair (`xynthesisModel` / `skillModel`) for this runTask phase. */
50
- modelConfig?: RunTaskModelConfigWire;
49
+ /** Required on every `runTask` (@exellix/ai-tasks 8.4+). */
50
+ modelConfig: RunTaskModelConfigWire;
51
51
  llmCall?: LlmCallConfig;
52
52
  identity?: Record<string, unknown>;
53
53
  executionMode?: 'default' | 'trace';
@@ -146,7 +146,7 @@ export function buildAiTasksRunTaskRequest(args) {
146
146
  ...(args.narrix != null ? { narrix: args.narrix } : {}),
147
147
  ...(args.outputValidation != null ? { outputValidation: args.outputValidation } : {}),
148
148
  ...(args.diagnostics != null ? { diagnostics: args.diagnostics } : {}),
149
- ...(args.modelConfig != null ? { modelConfig: args.modelConfig } : {}),
149
+ modelConfig: args.modelConfig,
150
150
  ...(args.llmCall != null ? { llmCall: args.llmCall } : {}),
151
151
  ...(args.identity != null ? { identity: args.identity } : {}),
152
152
  ...(args.executionMode != null ? { executionMode: args.executionMode } : {}),
@@ -18,8 +18,7 @@ export function resolveCanonicalModelUsed(response) {
18
18
  rawConfig.model ??
19
19
  rawConfig.skillModel ??
20
20
  rawConfig.preActionModel ??
21
- rawConfig.postActionModel ??
22
- rawConfig.xynthesisModel;
21
+ rawConfig.postActionModel;
23
22
  if (typeof fromRaw === 'string' && fromRaw.trim() !== '')
24
23
  return fromRaw.trim();
25
24
  }
@@ -1,8 +1,9 @@
1
1
  import type { GraphAiModelConfig } from '../types/refs.js';
2
- /** Wire shape expected by `@exellix/ai-tasks` `RunTaskRequest.modelConfig`. */
2
+ /** Wire shape for `@exellix/ai-tasks` `RunTaskRequest.modelConfig` (8.4+). */
3
3
  export type RunTaskModelConfigWire = {
4
- xynthesisModel: string;
4
+ preActionModel: string;
5
5
  skillModel: string;
6
+ postActionModel: string;
6
7
  };
7
8
  /** Profile alias names used when no modelConfig tier resolves. */
8
9
  export declare const DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG: GraphAiModelConfig;
@@ -28,17 +29,12 @@ export declare function looksLikeConcreteModelId(value: string): boolean;
28
29
  export declare function isGraphAiProfileName(value: unknown): value is string;
29
30
  export declare function assertGraphAiProfileNameString(value: unknown, path: string, context?: GraphAiModelConfigResolveContext): asserts value is string;
30
31
  /**
31
- * Validates and normalizes graph/runtime {@link GraphAiModelConfig}.
32
- * Profile aliases and host-resolved concrete ids pass through unchanged for downstream resolution.
32
+ * Validates and normalizes graph {@link GraphAiModelConfig} (profile alias names).
33
33
  */
34
34
  export declare function resolveGraphAiModelConfig(modelConfig: GraphAiModelConfig | undefined, context?: GraphAiModelConfigResolveContext): Promise<GraphAiModelConfig>;
35
35
  export type EngineModelPhase = 'pre' | 'main' | 'post';
36
36
  /**
37
- * Maps three-phase graph config to ai-tasks slot pair for a single runTask phase.
38
- * Values are forwarded as-is (profile aliases or concrete ids).
39
- *
40
- * When {@link aiProfiles} is set (studio/playground host pattern), xynthesis slots use profile
41
- * aliases so PRE synthesis inside ai-tasks resolves via ai-profiles even when {@link config}
42
- * carries host-resolved concrete provider ids on `runtime.modelConfig`.
37
+ * Maps graph three-phase config to ai-tasks `RunTaskRequest.modelConfig` (8.4+ triplet).
38
+ * Values are profile alias names from the graph document; ai-tasks resolves and routes slots per phase.
43
39
  */
44
- export declare function toRunTaskModelConfigForPhase(config: GraphAiModelConfig, phase: EngineModelPhase, aiProfiles?: GraphAiModelConfig): RunTaskModelConfigWire;
40
+ export declare function toRunTaskModelConfig(config: GraphAiModelConfig): RunTaskModelConfigWire;
@@ -66,8 +66,7 @@ function normalizeModelSlot(slot, context) {
66
66
  return trimmed;
67
67
  }
68
68
  /**
69
- * Validates and normalizes graph/runtime {@link GraphAiModelConfig}.
70
- * Profile aliases and host-resolved concrete ids pass through unchanged for downstream resolution.
69
+ * Validates and normalizes graph {@link GraphAiModelConfig} (profile alias names).
71
70
  */
72
71
  export async function resolveGraphAiModelConfig(modelConfig, context) {
73
72
  if (!isGraphAiModelConfig(modelConfig)) {
@@ -79,37 +78,14 @@ export async function resolveGraphAiModelConfig(modelConfig, context) {
79
78
  postActionModel: normalizeModelSlot(modelConfig.postActionModel, context),
80
79
  };
81
80
  }
82
- function xynthesisSlotForWire(config, phase, aiProfiles) {
83
- if (aiProfiles != null) {
84
- return phase === 'post' ? aiProfiles.postActionModel : aiProfiles.preActionModel;
85
- }
86
- return phase === 'post' ? config.postActionModel : config.preActionModel;
87
- }
88
81
  /**
89
- * Maps three-phase graph config to ai-tasks slot pair for a single runTask phase.
90
- * Values are forwarded as-is (profile aliases or concrete ids).
91
- *
92
- * When {@link aiProfiles} is set (studio/playground host pattern), xynthesis slots use profile
93
- * aliases so PRE synthesis inside ai-tasks resolves via ai-profiles even when {@link config}
94
- * carries host-resolved concrete provider ids on `runtime.modelConfig`.
82
+ * Maps graph three-phase config to ai-tasks `RunTaskRequest.modelConfig` (8.4+ triplet).
83
+ * Values are profile alias names from the graph document; ai-tasks resolves and routes slots per phase.
95
84
  */
96
- export function toRunTaskModelConfigForPhase(config, phase, aiProfiles) {
97
- const xynthesisModel = xynthesisSlotForWire(config, phase, aiProfiles);
98
- switch (phase) {
99
- case 'pre':
100
- return {
101
- xynthesisModel,
102
- skillModel: xynthesisModel,
103
- };
104
- case 'main':
105
- return {
106
- xynthesisModel,
107
- skillModel: config.skillModel,
108
- };
109
- case 'post':
110
- return {
111
- xynthesisModel,
112
- skillModel: xynthesisModel,
113
- };
114
- }
85
+ export function toRunTaskModelConfig(config) {
86
+ return {
87
+ preActionModel: config.preActionModel,
88
+ skillModel: config.skillModel,
89
+ postActionModel: config.postActionModel,
90
+ };
115
91
  }
@@ -15,11 +15,7 @@ export function mergeExellixGraphRuntimeInvocation(input, opts) {
15
15
  executionPipeline: input.executionPipeline ?? opts.executionPipeline,
16
16
  playgroundMeta: input.playgroundMeta ?? opts.playgroundMeta,
17
17
  clearSynthesizedContextPerNode: input.clearSynthesizedContextPerNode ?? opts.clearSynthesizedContextPerNode,
18
- modelConfig: input.modelConfig ?? opts.modelConfig,
19
- aiProfiles: input.aiProfiles ?? opts.aiProfiles,
20
- aliasConfig: input.aliasConfig ?? opts.aliasConfig,
21
18
  nodes: input.nodes ?? opts.nodes,
22
- llmCall: input.llmCall ?? opts.llmCall,
23
19
  runTaskIdentity: input.runTaskIdentity ?? opts.runTaskIdentity,
24
20
  runTaskExecutionMode: input.runTaskExecutionMode ?? opts.runTaskExecutionMode,
25
21
  runLogMode: input.runLogMode ?? opts.runLogMode,
@@ -1,11 +1,9 @@
1
1
  import type { RunxClient } from '@x12i/runx';
2
- import type { GraphAiModelConfig, ModelConfigSelection, TaskNodeRuntimeObject } from '../types/refs.js';
2
+ import type { GraphAiModelConfig, ModelConfigSelection } from '../types/refs.js';
3
3
  import { conditionWhenSignature, isEmptyConditionWhen } from './modelConfigSelection.js';
4
4
  import { type TaskNodeConditionEvalContext } from './taskNodeConditionsEvaluation.js';
5
5
  export type ResolveModelConfigForNodeArgs = {
6
- runtimeNodeConfig?: TaskNodeRuntimeObject;
7
6
  nodeModelConfig?: unknown;
8
- runtimeModelConfig?: ModelConfigSelection;
9
7
  graphModelConfig?: ModelConfigSelection;
10
8
  conditionCtx: TaskNodeConditionEvalContext;
11
9
  executionInput: Record<string, unknown>;
@@ -15,10 +13,9 @@ export type ResolveModelConfigForNodeArgs = {
15
13
  jobId?: string;
16
14
  };
17
15
  /**
18
- * Resolves effective model config for a task node (precedence + conditional cases).
19
- * Returns profile aliases (or host-resolved concrete ids from runtime overrides) for
20
- * {@link toRunTaskModelConfigForPhase} / ai-tasks wire. Alias → model resolution is downstream.
16
+ * Resolves effective model config for a task node from the graph document only.
17
+ * Precedence: `node.taskConfiguration.modelConfig` `graph.modelConfig` engine default profiles.
21
18
  */
22
19
  export declare function resolveModelConfigForNode(args: ResolveModelConfigForNodeArgs): Promise<GraphAiModelConfig>;
23
20
  export { conditionWhenSignature, isEmptyConditionWhen };
24
- export { resolveGraphAiModelConfig, toRunTaskModelConfigForPhase, DEFAULT_GRAPH_AI_MODEL_IDS, DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, } from './graphAiModelConfig.js';
21
+ export { resolveGraphAiModelConfig, toRunTaskModelConfig, DEFAULT_GRAPH_AI_MODEL_IDS, DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, } from './graphAiModelConfig.js';
@@ -34,16 +34,11 @@ async function resolveTier(value, ctx, executionInput, runx) {
34
34
  return undefined;
35
35
  }
36
36
  /**
37
- * Resolves effective model config for a task node (precedence + conditional cases).
38
- * Returns profile aliases (or host-resolved concrete ids from runtime overrides) for
39
- * {@link toRunTaskModelConfigForPhase} / ai-tasks wire. Alias → model resolution is downstream.
37
+ * Resolves effective model config for a task node from the graph document only.
38
+ * Precedence: `node.taskConfiguration.modelConfig` `graph.modelConfig` engine default profiles.
40
39
  */
41
40
  export async function resolveModelConfigForNode(args) {
42
- const staticHost = args.runtimeNodeConfig?.modelConfig;
43
- if (isGraphAiModelConfig(staticHost)) {
44
- return staticHost;
45
- }
46
- const tiers = [args.nodeModelConfig, args.runtimeModelConfig, args.graphModelConfig];
41
+ const tiers = [args.nodeModelConfig, args.graphModelConfig];
47
42
  for (const tier of tiers) {
48
43
  const selected = await resolveTier(tier, args.conditionCtx, args.executionInput, args.runx);
49
44
  if (selected != null) {
@@ -53,4 +48,4 @@ export async function resolveModelConfigForNode(args) {
53
48
  return DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG;
54
49
  }
55
50
  export { conditionWhenSignature, isEmptyConditionWhen };
56
- export { resolveGraphAiModelConfig, toRunTaskModelConfigForPhase, DEFAULT_GRAPH_AI_MODEL_IDS, DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, } from './graphAiModelConfig.js';
51
+ export { resolveGraphAiModelConfig, toRunTaskModelConfig, DEFAULT_GRAPH_AI_MODEL_IDS, DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, } from './graphAiModelConfig.js';
@@ -1,7 +1,14 @@
1
1
  /**
2
2
  * Shared pieces for assembling `@exellix/ai-tasks` requests from graph-engine (llmCall merge, identity, trace mode).
3
3
  */
4
+ import type { LlmCallConfig } from '@exellix/ai-tasks';
5
+ import type { RunTaskModelConfigWire } from './graphAiModelConfig.js';
4
6
  export declare function mergeDefinedLlmCallParts(...parts: Array<Record<string, unknown> | undefined | null>): Record<string, unknown> | undefined;
7
+ /**
8
+ * MAIN-only `llmCall` for ai-tasks 8.4+: `model` is always {@link RunTaskModelConfigWire.skillModel};
9
+ * node `taskConfiguration.llmCall` may supply caps/options but not override the skill slot model.
10
+ */
11
+ export declare function buildMainLlmCallForRunTask(modelConfig: RunTaskModelConfigWire, ...parts: Array<Record<string, unknown> | undefined | null>): LlmCallConfig;
5
12
  /** Whether to send `executionMode: "trace"` on `runTask` (ai-tasks 5.6+). */
6
13
  export declare function shouldForwardRunTaskTraceMode(opts: {
7
14
  debugMode?: boolean;
@@ -1,6 +1,3 @@
1
- /**
2
- * Shared pieces for assembling `@exellix/ai-tasks` requests from graph-engine (llmCall merge, identity, trace mode).
3
- */
4
1
  export function mergeDefinedLlmCallParts(...parts) {
5
2
  const out = {};
6
3
  for (const p of parts) {
@@ -13,6 +10,18 @@ export function mergeDefinedLlmCallParts(...parts) {
13
10
  }
14
11
  return Object.keys(out).length > 0 ? out : undefined;
15
12
  }
13
+ /**
14
+ * MAIN-only `llmCall` for ai-tasks 8.4+: `model` is always {@link RunTaskModelConfigWire.skillModel};
15
+ * node `taskConfiguration.llmCall` may supply caps/options but not override the skill slot model.
16
+ */
17
+ export function buildMainLlmCallForRunTask(modelConfig, ...parts) {
18
+ const merged = mergeDefinedLlmCallParts(...parts) ?? {};
19
+ const { model: _ignored, ...rest } = merged;
20
+ return {
21
+ ...rest,
22
+ model: modelConfig.skillModel,
23
+ };
24
+ }
16
25
  /** Whether to send `executionMode: "trace"` on `runTask` (ai-tasks 5.6+). */
17
26
  export function shouldForwardRunTaskTraceMode(opts) {
18
27
  if (opts.runTaskExecutionMode === 'trace')
@@ -5,7 +5,7 @@
5
5
  import type { Catalox } from '@x12i/catalox';
6
6
  import type { RunTaskRequest } from '@exellix/ai-tasks';
7
7
  import { type AnalyzeRunTaskRequestOptions, type AnalyzeRunTaskRequestResult, type RunTaskInvokeValidationResult, type RunTaskValidationResult, type ValidateRunTaskInvokeParams } from '@exellix/ai-tasks';
8
- import type { GraphAiModelConfig, GraphModelAliasConfig, Job, TaskNode } from '../types/refs.js';
8
+ import type { GraphAiModelConfig, Job, TaskNode } from '../types/refs.js';
9
9
  import type { ExecutionStepOption, RunTaskDiagnostics, SkillKeyResolutionOptions } from '../types/options.js';
10
10
  export type TaskNodeRunTaskPreflightSkipReason = 'local_skill' | 'finalizer';
11
11
  export type BuildTaskNodeRunTaskRequestResult = {
@@ -30,13 +30,8 @@ export type BuildTaskNodeRunTaskRequestArgs = {
30
30
  graphRunTaskId?: string;
31
31
  /** Host job id on `job.jobId` / `job.id`; defaults from `job` when omitted. */
32
32
  runTaskJobId?: string;
33
- /** Profile aliases or host-resolved concrete ids; forwarded unchanged on the ai-tasks wire. */
34
- modelConfig?: GraphAiModelConfig;
35
- /** @deprecated Unused since 7.1. */
36
- aliasConfig?: GraphModelAliasConfig;
37
- llmCall?: Record<string, unknown>;
38
- /** Runtime default merged with per-node `taskConfiguration.llmCall`. */
39
- runtimeLlmCall?: Record<string, unknown>;
33
+ /** Resolved graph model profiles (required for runnable MAIN). */
34
+ modelConfig: GraphAiModelConfig;
40
35
  runTaskIdentity?: Record<string, unknown>;
41
36
  runTaskExecutionMode?: 'default' | 'trace';
42
37
  runTaskDiagnostics?: RunTaskDiagnostics;
@@ -1,5 +1,5 @@
1
1
  import { analyzeRunTaskRequest, validateRunTaskConfig, validateRunTaskInvoke, } from '@exellix/ai-tasks';
2
- import { toRunTaskModelConfigForPhase } from './graphAiModelConfig.js';
2
+ import { toRunTaskModelConfig } from './graphAiModelConfig.js';
3
3
  import { resolveTaskKey } from './resolveTaskKey.js';
4
4
  import { isLocalSkillKey } from './localSkills/index.js';
5
5
  import { buildAiTasksRunTaskRequest, extractRunTaskStrategyOverrides, } from './buildAiTasksRunTaskRequest.js';
@@ -12,7 +12,7 @@ import { xynthesizedOutboundForNode } from './graphRunExecutionSeed.js';
12
12
  import { buildTaskNodeJobContext } from './buildTaskNodeJobContext.js';
13
13
  import { resolveNarrixForTaskNode } from './resolveNarrixForTaskNode.js';
14
14
  import { normalizeSynthesizedContextConfig } from './synthesizedContextPipeline.js';
15
- import { buildRunTaskIdentityEnvelope, mergeDefinedLlmCallParts, shouldForwardRunTaskTraceMode, } from './runTaskAugments.js';
15
+ import { buildMainLlmCallForRunTask, buildRunTaskIdentityEnvelope, shouldForwardRunTaskTraceMode, } from './runTaskAugments.js';
16
16
  import { mirrorTaskVariablesOnExecution, readExecutionVariableBuckets, } from './executionVariableBuckets.js';
17
17
  import { newGraphRunTaskId } from './graphRunIdentity.js';
18
18
  function isPlainRecord(v) {
@@ -115,13 +115,13 @@ export async function buildTaskNodeRunTaskRequest(args) {
115
115
  mirrorStructuredInputOntoExecutionMemory(executionForTask, taskInput);
116
116
  const runTaskJobMemory = mergeKnowledgePatchIntoRunTaskMemory(args.jobMemory, args.jobKnowledgePatch);
117
117
  const runTaskTaskMemory = mergeKnowledgePatchIntoRunTaskMemory(args.taskMemory, args.taskKnowledgePatch);
118
- const effectiveLlmCall = mergeDefinedLlmCallParts(args.runtimeLlmCall, args.llmCall, node.taskConfiguration?.llmCall);
118
+ const wireModelConfig = toRunTaskModelConfig(args.modelConfig);
119
+ const effectiveLlmCall = buildMainLlmCallForRunTask(wireModelConfig, node.taskConfiguration?.llmCall);
119
120
  const forwardRunTaskTrace = shouldForwardRunTaskTraceMode({
120
121
  runTaskExecutionMode: args.runTaskExecutionMode,
121
122
  });
122
123
  const metaStrats = node.taskConfiguration?.executionStrategies;
123
124
  const ov = node.taskConfiguration?.aiTasksOutputValidation;
124
- const mainRunTaskModelConfig = args.modelConfig != null ? toRunTaskModelConfigForPhase(args.modelConfig, 'main') : undefined;
125
125
  const request = buildAiTasksRunTaskRequest({
126
126
  skillKey,
127
127
  job: args.job,
@@ -146,7 +146,7 @@ export async function buildTaskNodeRunTaskRequest(args) {
146
146
  ? ov
147
147
  : undefined,
148
148
  diagnostics: args.runTaskDiagnostics,
149
- modelConfig: mainRunTaskModelConfig,
149
+ modelConfig: wireModelConfig,
150
150
  llmCall: effectiveLlmCall,
151
151
  identity: buildRunTaskIdentityEnvelope({
152
152
  base: args.runTaskIdentity,
@@ -0,0 +1,16 @@
1
+ /** Minimal runtime shape validated at `executeGraph` entry (avoids circular import with ExellixGraphRuntime). */
2
+ export type CanonicalGraphRuntimeShape = {
3
+ modelConfig?: unknown;
4
+ aiProfiles?: unknown;
5
+ aliasConfig?: unknown;
6
+ llmCall?: unknown;
7
+ nodes?: Record<string, unknown>;
8
+ };
9
+ /**
10
+ * Rejects runtime-layer AI model selection and `llmCall` overrides (7.7+).
11
+ * Profile aliases and `modelConfig` cases belong on {@link GraphModelObject} / task nodes only.
12
+ */
13
+ export declare function assertCanonicalGraphRuntimeObject(runtime: CanonicalGraphRuntimeShape, context?: {
14
+ jobId?: string;
15
+ graphId?: string;
16
+ }): void;
@@ -0,0 +1,35 @@
1
+ import { ExellixGraphError } from '../errors/ExellixGraphError.js';
2
+ import { ExellixGraphErrorCode } from '../errors/exellixGraphErrorCodes.js';
3
+ const FORBIDDEN_RUNTIME_ROOT_KEYS = [
4
+ 'modelConfig',
5
+ 'aiProfiles',
6
+ 'aliasConfig',
7
+ 'llmCall',
8
+ ];
9
+ const FORBIDDEN_RUNTIME_NODE_KEYS = ['modelConfig', 'aliasConfig'];
10
+ function isPlainObject(v) {
11
+ return v != null && typeof v === 'object' && !Array.isArray(v);
12
+ }
13
+ /**
14
+ * Rejects runtime-layer AI model selection and `llmCall` overrides (7.7+).
15
+ * Profile aliases and `modelConfig` cases belong on {@link GraphModelObject} / task nodes only.
16
+ */
17
+ export function assertCanonicalGraphRuntimeObject(runtime, context) {
18
+ for (const key of FORBIDDEN_RUNTIME_ROOT_KEYS) {
19
+ if (runtime[key] !== undefined) {
20
+ throw new ExellixGraphError(ExellixGraphErrorCode.NON_CANONICAL_GRAPH_RUNTIME, `runtime.${key} was removed in 7.7; configure model profiles on graph.modelConfig and node.taskConfiguration.modelConfig only.`, context);
21
+ }
22
+ }
23
+ const nodes = runtime.nodes;
24
+ if (nodes == null || typeof nodes !== 'object' || Array.isArray(nodes))
25
+ return;
26
+ for (const [nodeId, nodeCfg] of Object.entries(nodes)) {
27
+ if (!isPlainObject(nodeCfg))
28
+ continue;
29
+ for (const key of FORBIDDEN_RUNTIME_NODE_KEYS) {
30
+ if (nodeCfg[key] !== undefined) {
31
+ throw new ExellixGraphError(ExellixGraphErrorCode.NON_CANONICAL_GRAPH_RUNTIME, `runtime.nodes["${nodeId}"].${key} was removed in 7.7; use graph / task node modelConfig on the model document.`, context);
32
+ }
33
+ }
34
+ }
35
+ }
@@ -1,7 +1,7 @@
1
1
  import type { Activix } from '@x12i/activix';
2
2
  import type { StackLoggingOptions } from '@x12i/logxer';
3
- import type { LlmCallConfig, RunTaskRequest as AiTasksRunTaskRequest, RunTaskResponse as AiTasksRunTaskResponse } from '@exellix/ai-tasks';
4
- import type { GraphAiModelConfig, GraphModelAliasConfig, ModelConfigSelection, TaskNodeRuntimeObject } from './refs.js';
3
+ import type { RunTaskRequest as AiTasksRunTaskRequest, RunTaskResponse as AiTasksRunTaskResponse } from '@exellix/ai-tasks';
4
+ import type { TaskNodeRuntimeObject } from './refs.js';
5
5
  import type { RuntimeObjects } from '../runtime/runtimeObjects.js';
6
6
  /**
7
7
  * NOTE: `@exellix/ai-tasks` 5.5+ removed the exported `RunTaskDiagnostics` type.
@@ -62,15 +62,7 @@ export interface HostExecuteGraphRunOptions {
62
62
  executionPipeline?: ExecutionStepOption[];
63
63
  playgroundMeta?: Record<string, unknown>;
64
64
  clearSynthesizedContextPerNode?: boolean;
65
- modelConfig?: ModelConfigSelection;
66
- /**
67
- * Profile aliases for xynthesis PRE/POST when {@link modelConfig} carries host-resolved concrete ids.
68
- * MAIN `skillModel` still comes from resolved `modelConfig`; xynthesis slots prefer these aliases.
69
- */
70
- aiProfiles?: GraphAiModelConfig;
71
- aliasConfig?: GraphModelAliasConfig;
72
65
  nodes?: Record<string, TaskNodeRuntimeObject>;
73
- llmCall?: LlmCallConfig;
74
66
  runTaskIdentity?: Record<string, unknown>;
75
67
  runTaskExecutionMode?: 'default' | 'trace';
76
68
  runLogMode?: import('./runLog.js').RunLogMode;
@@ -14,8 +14,7 @@ export type TaskNodeExecutionPipelineStep = {
14
14
  */
15
15
  /**
16
16
  * Three-phase AI model selection on graph model / node `modelConfig`.
17
- * Values are profile alias names (`cheap`, `balanced`, `deep`, …) in graph JSON,
18
- * or host-resolved concrete provider ids on runtime overrides. Alias resolution is downstream.
17
+ * Values are profile alias names (`cheap`, `balanced`, `deep`, …) in graph JSON only.
19
18
  */
20
19
  export type GraphAiModelConfig = {
21
20
  preActionModel: string;
@@ -26,12 +25,8 @@ export type GraphAiModelConfig = {
26
25
  * @deprecated Legacy alias map — no longer required for execute. Hosts may omit `runtime.aliasConfig`.
27
26
  */
28
27
  export type GraphModelAliasConfig = Record<string, string>;
29
- /** Runtime overrides for a single task node, stored at GraphRuntimeObject.nodes[nodeId]. */
30
- export type TaskNodeRuntimeObject = {
31
- modelConfig?: GraphAiModelConfig;
32
- /** @deprecated Unused since 7.1 — profile aliases pass through to downstream resolution. */
33
- aliasConfig?: GraphModelAliasConfig;
34
- };
28
+ /** Per-node runtime bag (extensible). Model selection is graph-only since 7.7. */
29
+ export type TaskNodeRuntimeObject = Record<string, unknown>;
35
30
  /** Backwards-readable alias for per-node runtime overrides keyed by task node id. */
36
31
  export type GraphRuntimeNodeConfig = TaskNodeRuntimeObject;
37
32
  /** Schema version for structured record gates on `conditions.dataFilters` (and optional `graphEntry.dataFilters`). */
@@ -701,8 +696,7 @@ export interface GraphModelObject {
701
696
  /** Optional static model version for authoring, storage, and replay/audit tooling. */
702
697
  version?: string;
703
698
  /**
704
- * Graph-level default AI model selection. Runtime aliases are resolved from
705
- * GraphRuntimeObject.aliasConfig / nodes[nodeId].aliasConfig before runTask.
699
+ * Graph-level default AI model selection (profile alias names per slot).
706
700
  */
707
701
  modelConfig?: ModelConfigSelection;
708
702
  /**
@@ -1,5 +1,5 @@
1
1
  export { InMemoryGraphLoader } from './inMemoryGraphLoader.js';
2
2
  export { DepGraphEngineFactory } from './depGraphEngineFactory.js';
3
3
  export { RealTasksClient } from './RealTasksClient.js';
4
- export { buildTestAliasConfig, withTestAliasRuntime, createTestExellixGraphRuntime, } from './testModelAliasRuntime.js';
4
+ export { createTestExellixGraphRuntime } from './testModelAliasRuntime.js';
5
5
  export { tryLoadExellixAiTasksRuntimeSubtree, loadExellixGraphRuntimeObjects, } from './exellixRuntimeObjects.js';
@@ -1,5 +1,5 @@
1
1
  export { InMemoryGraphLoader } from './inMemoryGraphLoader.js';
2
2
  export { DepGraphEngineFactory } from './depGraphEngineFactory.js';
3
3
  export { RealTasksClient } from './RealTasksClient.js';
4
- export { buildTestAliasConfig, withTestAliasRuntime, createTestExellixGraphRuntime, } from './testModelAliasRuntime.js';
4
+ export { createTestExellixGraphRuntime } from './testModelAliasRuntime.js';
5
5
  export { tryLoadExellixAiTasksRuntimeSubtree, loadExellixGraphRuntimeObjects, } from './exellixRuntimeObjects.js';
@@ -1,14 +1,7 @@
1
- import type { Graph } from '../src/types/refs.js';
2
- import { createExellixGraphRuntime, type GraphRuntimeObject } from '../src/runtime/ExellixGraphRuntime.js';
1
+ import { createExellixGraphRuntime } from '../src/runtime/ExellixGraphRuntime.js';
3
2
  type CreateOpts = Parameters<typeof createExellixGraphRuntime>[0];
4
3
  /**
5
- * Testkit runtime for graphs using profile aliases (no `runtime.aliasConfig` required).
4
+ * Testkit runtime for graphs using profile aliases on the graph document.
6
5
  */
7
6
  export declare function createTestExellixGraphRuntime(opts: CreateOpts): ReturnType<typeof createExellixGraphRuntime>;
8
- /** @deprecated Alias map test helper removed in 7.1 — profile aliases pass through to ai-tasks. */
9
- export declare function buildTestAliasConfig(_graph: Pick<Graph, 'modelConfig' | 'nodes'>, runtimePartial?: Pick<GraphRuntimeObject, 'modelConfig' | 'nodes'> & {
10
- aliasConfig?: Record<string, string>;
11
- }): Record<string, string>;
12
- /** @deprecated No-op — `runtime.aliasConfig` is not required in 7.1. */
13
- export declare function withTestAliasRuntime(_graph: Pick<Graph, 'id' | 'modelConfig' | 'nodes'>, runtime: Partial<GraphRuntimeObject> & Pick<GraphRuntimeObject, 'jobId' | 'job'>): GraphRuntimeObject;
14
7
  export {};
@@ -1,6 +1,6 @@
1
1
  import { createExellixGraphRuntime, } from '../src/runtime/ExellixGraphRuntime.js';
2
2
  /**
3
- * Testkit runtime for graphs using profile aliases (no `runtime.aliasConfig` required).
3
+ * Testkit runtime for graphs using profile aliases on the graph document.
4
4
  */
5
5
  export function createTestExellixGraphRuntime(opts) {
6
6
  const runtime = createExellixGraphRuntime(opts);
@@ -20,11 +20,3 @@ export function createTestExellixGraphRuntime(opts) {
20
20
  };
21
21
  return runtime;
22
22
  }
23
- /** @deprecated Alias map test helper removed in 7.1 — profile aliases pass through to ai-tasks. */
24
- export function buildTestAliasConfig(_graph, runtimePartial) {
25
- return { ...(runtimePartial?.aliasConfig ?? {}) };
26
- }
27
- /** @deprecated No-op — `runtime.aliasConfig` is not required in 7.1. */
28
- export function withTestAliasRuntime(_graph, runtime) {
29
- return runtime;
30
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exellix/graph-engine",
3
- "version": "7.5.1",
3
+ "version": "7.7.0",
4
4
  "type": "module",
5
5
  "description": "Graph executor SDK",
6
6
  "main": "dist/src/index.js",
@@ -52,18 +52,17 @@
52
52
  "access": "public"
53
53
  },
54
54
  "dependencies": {
55
- "@exellix/ai-tasks": "^8.2.9",
55
+ "@exellix/ai-tasks": "^8.4.3",
56
56
  "@x12i/activix": "8.5.0",
57
57
  "@x12i/catalox": "5.1.3",
58
58
  "@x12i/env": "4.0.1",
59
- "@x12i/funcx": "4.3.0",
59
+ "@x12i/funcx": "4.3.3",
60
60
  "@x12i/graphenix": "2.5.0",
61
61
  "@x12i/graphenix-format": "2.0.0",
62
62
  "@x12i/logxer": "^4.6.0",
63
63
  "@x12i/memorix-descriptors": "1.6.0",
64
64
  "@x12i/memorix-retrieval": "1.11.2",
65
65
  "@x12i/memorix-writer": "1.0.0",
66
- "@x12i/optimixer": "^2.4.4",
67
66
  "@x12i/rendrix": "4.3.0",
68
67
  "@x12i/runx": "1.3.0"
69
68
  },