@exellix/graph-engine 7.8.1 → 8.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/CHANGELOG.md +42 -0
- package/README.md +16 -13
- package/dist/src/adapters/compileExellixExecutablePlan.d.ts +8 -0
- package/dist/src/adapters/compileExellixExecutablePlan.js +18 -0
- package/dist/src/adapters/migrateExellixGraphModelToAuthoring.d.ts +6 -0
- package/dist/src/adapters/migrateExellixGraphModelToAuthoring.js +273 -0
- package/dist/src/adapters/patchFinalizerPlans.d.ts +7 -0
- package/dist/src/adapters/patchFinalizerPlans.js +63 -0
- package/dist/src/errors/exellixGraphErrorCodes.d.ts +5 -0
- package/dist/src/errors/exellixGraphErrorCodes.js +5 -0
- package/dist/src/index.d.ts +9 -2
- package/dist/src/index.js +6 -2
- package/dist/src/integrations/ActivixNodeActivityIntegration.js +7 -0
- package/dist/src/plan/aiModelSelectionWire.d.ts +11 -0
- package/dist/src/plan/aiModelSelectionWire.js +39 -0
- package/dist/src/plan/applyNodePlanInvoke.d.ts +10 -0
- package/dist/src/plan/applyNodePlanInvoke.js +67 -0
- package/dist/src/plan/embeddedGraphToExellixGraph.d.ts +5 -0
- package/dist/src/plan/embeddedGraphToExellixGraph.js +131 -0
- package/dist/src/plan/planDeferredGates.d.ts +16 -0
- package/dist/src/plan/planDeferredGates.js +118 -0
- package/dist/src/plan/planExecuteEntry.d.ts +12 -0
- package/dist/src/plan/planExecuteEntry.js +73 -0
- package/dist/src/plan/planExecutionPipeline.d.ts +11 -0
- package/dist/src/plan/planExecutionPipeline.js +54 -0
- package/dist/src/plan/planModelConfig.d.ts +10 -0
- package/dist/src/plan/planModelConfig.js +46 -0
- package/dist/src/runtime/ExellixGraphRuntime.d.ts +9 -6
- package/dist/src/runtime/ExellixGraphRuntime.js +138 -98
- package/dist/src/runtime/executionMatrixHost.js +2 -1
- package/dist/src/runtime/studioGraphExecuteRequest.d.ts +51 -0
- package/dist/src/runtime/studioGraphExecuteRequest.js +78 -0
- package/dist/testkit/buildExecuteGraphInput.d.ts +4 -0
- package/dist/testkit/buildExecuteGraphInput.js +8 -0
- package/dist/testkit/index.d.ts +1 -0
- package/dist/testkit/index.js +1 -0
- package/dist/testkit/testModelAliasRuntime.js +2 -2
- package/package.json +9 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 8.0.0
|
|
4
|
+
|
|
5
|
+
### Breaking
|
|
6
|
+
|
|
7
|
+
- **`executeGraph({ plan, runtime })` only** — removed `ExecuteGraphInput.model`. Hosts compile with `compileExellixExecutablePlan` or `@x12i/graphenix-plan-compiler` before invoke.
|
|
8
|
+
- **`ExecuteGraphResult.graphAudit` → `planAudit`** (`{ planHash, source }`).
|
|
9
|
+
- Execute-time model case selection and `assertCanonicalGraphDocument` removed from the run path; frozen `plan.nodePlans` / `plan.finalizerPlans` drive model config and invoke contracts.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **`@x12i/graphenix-*` integration:** plan validation, deferred gates, trace events (`ExecuteGraphResult.trace`), and exports for `ExecutableGraphPlanV2`.
|
|
14
|
+
- **`compileExellixExecutablePlan`**, **`migrateExellixGraphModelToAuthoring`** — host compile helpers for legacy exellix `GraphModelObject`.
|
|
15
|
+
- **`buildAuthoringStudioGraphExecutionRequest`** re-export from `@x12i/graphenix-execute-envelope`.
|
|
16
|
+
|
|
17
|
+
See [`BREAKING-CHANGES.md`](BREAKING-CHANGES.md) §8.0.0.
|
|
18
|
+
|
|
19
|
+
## 7.8.3
|
|
20
|
+
|
|
21
|
+
### Breaking
|
|
22
|
+
|
|
23
|
+
- **Studio graph execute envelope:** `graphDefaultModel` removed with **no legacy reader**. Request-level model defaults duplicated `graph.modelConfig` and were never applied by graph-engine. Hosts (graphs-studio) must persist defaults on **`graph.modelConfig` only** and stop sending `graphDefaultModel`.
|
|
24
|
+
- **Validation:** `assertCanonicalStudioGraphExecuteRequest` and `buildGraphExecutionRequestFromStudioExecute` reject the removed key (`NON_CANONICAL_STUDIO_GRAPH_EXECUTE_REQUEST`).
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- **Documentation:** [`formats-documentations/graph-format-boundaries.md`](formats-documentations/graph-format-boundaries.md) — four-layer model (graph / runtime / studio envelope / studio DB), field mapping from playground payloads, and explicit list of what is not on `GraphModelObject`.
|
|
29
|
+
|
|
30
|
+
## 7.8.2
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- **ai-tasks error propagation:** Node failures preserve upstream `error.code` and full `error.message` from `@exellix/ai-tasks` (no `TASK_RUN_FAILED: {skillKey}` message wrapper).
|
|
35
|
+
- **Activix node fail records:** `failRecord` updates include `errorCode` alongside the upstream error message.
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- **Dependencies:** `@exellix/ai-tasks` ^8.8.0 (transitive: `@exellix/ai-skills` ≥6.5.0, `@exellix/xynthesis` ≥4.6.0, `@x12i/ai-profiles` ≥3.2.0).
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
|
|
43
|
+
- **Tests:** SubNets (`graph-qcrbz6t`) synthesis PRE alias pass-through; ai-tasks `SKILL_MODEL_RESOLUTION_FAILED` / `XYNTHESIS_*` error surfacing on `node:fail` and Activix `failRecord`.
|
|
44
|
+
|
|
3
45
|
## 7.8.1
|
|
4
46
|
|
|
5
47
|
### Changed
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ A minimal, focused SDK for executing graphs in the exellix ecosystem.
|
|
|
4
4
|
|
|
5
5
|
## What this package does and does not
|
|
6
6
|
|
|
7
|
-
**In scope — what this package does:** On each **`createExellixGraphRuntime(...).executeGraph({
|
|
7
|
+
**In scope — what this package does:** On each **`createExellixGraphRuntime(...).executeGraph({ plan, runtime })`** invocation, it runs **exactly one graph run** (validate plan → schedule waves → nodes → finalizer) until that run **completes or fails**, then returns the result. There is **no** batching, queueing, or multi-job orchestration inside this package — each call is one logical run. You supply a compiled v2 **`plan: ExecutableGraphPlanV2`** (from `@x12i/graphenix-plan-compiler` or {@link compileExellixExecutablePlan}), planner (`GraphEngineFactory`), tasks client, and dynamic **`runtime: GraphRuntimeObject`** with the mandatory host `jobId`, `job` envelope, active `input`, memory, variables, and per-run options. The engine generates a fresh **`taskId`** (UUID) per invocation and sends it on **every** `runTask` request together with **`jobId`**. That is the **entire** product role of graph-engine.
|
|
8
8
|
|
|
9
9
|
**Out of scope — what this package does not do:** It does **not** schedule work, own **execution matrices**, manage **claims** or **rows**, persist **job** lifecycle, implement **retry/requeue policy**, or **track** runs across tenants or sessions. Optional helpers and docs for matrix *hosts* only help **build arguments** for the same single-run API; they do **not** move orchestration into this package. Integrations (e.g. Activix graph-run events) emit data **for that call** when you wire an `eventEmitter` — they do not make graph-engine a workflow or matrix service.
|
|
10
10
|
|
|
@@ -12,8 +12,8 @@ A minimal, focused SDK for executing graphs in the exellix ecosystem.
|
|
|
12
12
|
|
|
13
13
|
`exellix-graph-engine` does exactly this loop:
|
|
14
14
|
|
|
15
|
-
1. **Validate
|
|
16
|
-
2. `plan
|
|
15
|
+
1. **Validate executable plan:** The caller supplies **`plan: ExecutableGraphPlanV2`** (compiled upstream). The effective correlation **`graphId`** on the result and in telemetry is **`plan.source.graphId`**.
|
|
16
|
+
2. `executeGraph({ plan, runtime })`
|
|
17
17
|
3. For each runnable node:
|
|
18
18
|
- Map node → `skillKey` (strict rules)
|
|
19
19
|
- If `skillKey` is a **local skill** (`scoped-data-reader`, `deterministic-rule`, `scoped-answer-writer`, `scoped-answer-assembler`), run it in-process (no `ai-tasks` call); otherwise call `ai-tasks.runTask(...)`
|
|
@@ -97,7 +97,7 @@ Lower-level helpers (`validateRunTaskConfig`, `validateRunTaskInvoke`, `analyzeE
|
|
|
97
97
|
## Quick Start
|
|
98
98
|
|
|
99
99
|
```typescript
|
|
100
|
-
import { createExellixGraphRuntime } from '@exellix/graph-engine';
|
|
100
|
+
import { compileExellixExecutablePlan, createExellixGraphRuntime } from '@exellix/graph-engine';
|
|
101
101
|
|
|
102
102
|
const runtime = createExellixGraphRuntime({
|
|
103
103
|
graphLoader: myGraphLoader,
|
|
@@ -121,15 +121,18 @@ const graphModel = {
|
|
|
121
121
|
// …
|
|
122
122
|
};
|
|
123
123
|
|
|
124
|
+
const graphRuntime = {
|
|
125
|
+
jobId: 'job-123',
|
|
126
|
+
job: { agentId: 'agent-1', input: {} },
|
|
127
|
+
input: { question: 'Analyze this record' },
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const plan = compileExellixExecutablePlan(graphModel, graphRuntime);
|
|
131
|
+
|
|
124
132
|
// Host correlation id (required). Engine sets `job.id` / `job.jobId` from it and generates `result.taskId`.
|
|
125
133
|
const result = await runtime.executeGraph({
|
|
126
|
-
|
|
127
|
-
runtime:
|
|
128
|
-
jobId: 'job-123',
|
|
129
|
-
job: { agentId: 'agent-1', input: {} },
|
|
130
|
-
input: { question: 'Analyze this record' },
|
|
131
|
-
// no modelConfig or aliasConfig on runtime (removed in 7.7)
|
|
132
|
-
},
|
|
134
|
+
plan,
|
|
135
|
+
runtime: graphRuntime,
|
|
133
136
|
});
|
|
134
137
|
|
|
135
138
|
// Canonical business output + per-run ids:
|
|
@@ -138,11 +141,11 @@ console.log(result.finalOutput, result.jobId, result.taskId);
|
|
|
138
141
|
|
|
139
142
|
## Public API
|
|
140
143
|
|
|
141
|
-
### `runtime.executeGraph({
|
|
144
|
+
### `runtime.executeGraph({ plan, runtime })`
|
|
142
145
|
|
|
143
146
|
Execute a complete graph through the **single canonical client API**: `createExellixGraphRuntime(...)`. The runtime owns local-skill interception, conditional edge filtering, optional `eventEmitter`, optional `debugMode`, and produces one `ExecuteGraphResult` shape.
|
|
144
147
|
|
|
145
|
-
Every call requires a
|
|
148
|
+
Every call requires a compiled v2 **`plan: ExecutableGraphPlanV2`** and a dynamic **`runtime: GraphRuntimeObject`**. Hosts compile authoring graphs with `@x12i/graphenix-plan-compiler` (or {@link compileExellixExecutablePlan} for legacy exellix `GraphModelObject`) before invoke. `runtime.jobId` is mandatory and non-empty. The engine also generates a **`taskId`** (UUID) per invocation. Together they form the **identity** forwarded to **`@exellix/ai-tasks`** (`runTask({ jobId, taskId, … })`), graph/node **`eventEmitter`** payloads, structured **`runLog`**, and Activix **`runContext`** / record metadata.
|
|
146
149
|
|
|
147
150
|
```typescript
|
|
148
151
|
import { createExellixGraphRuntime } from '@exellix/graph-engine';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CompileExecutablePlanV2Options, ExecutableGraphPlanV2 } from '@x12i/graphenix-executable-contracts';
|
|
2
|
+
import type { Graph, GraphModelObject } from '../types/refs.js';
|
|
3
|
+
import type { GraphRuntimeObject } from '../runtime/ExellixGraphRuntime.js';
|
|
4
|
+
export type CompileExellixExecutablePlanOptions = CompileExecutablePlanV2Options;
|
|
5
|
+
/**
|
|
6
|
+
* Host/test helper: exellix graph model + runtime → validated v2 executable plan.
|
|
7
|
+
*/
|
|
8
|
+
export declare function compileExellixExecutablePlan(model: Graph | GraphModelObject, runtime: GraphRuntimeObject, options?: CompileExellixExecutablePlanOptions): ExecutableGraphPlanV2;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { compileExecutablePlanV2 } from '@x12i/graphenix-plan-compiler';
|
|
2
|
+
import { validateExecutablePlan } from '@x12i/graphenix-plan-format';
|
|
3
|
+
import { migrateExellixGraphModelToAuthoring } from './migrateExellixGraphModelToAuthoring.js';
|
|
4
|
+
import { patchFinalizerPlansOnExecutablePlan } from './patchFinalizerPlans.js';
|
|
5
|
+
/**
|
|
6
|
+
* Host/test helper: exellix graph model + runtime → validated v2 executable plan.
|
|
7
|
+
*/
|
|
8
|
+
export function compileExellixExecutablePlan(model, runtime, options) {
|
|
9
|
+
const authoring = migrateExellixGraphModelToAuthoring(model);
|
|
10
|
+
const compiled = compileExecutablePlanV2(authoring, runtime, options);
|
|
11
|
+
const plan = patchFinalizerPlansOnExecutablePlan(compiled, runtime);
|
|
12
|
+
const validation = validateExecutablePlan(plan);
|
|
13
|
+
if (!validation.valid) {
|
|
14
|
+
const summary = validation.errors.map((e) => `${e.path}: ${e.message}`).join('; ');
|
|
15
|
+
throw new Error(`compileExellixExecutablePlan: invalid plan: ${summary}`);
|
|
16
|
+
}
|
|
17
|
+
return plan;
|
|
18
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type AuthoringGraphDocument } from '@x12i/graphenix-executable-contracts';
|
|
2
|
+
import type { Graph, GraphModelObject } from '../types/refs.js';
|
|
3
|
+
/**
|
|
4
|
+
* Converts exellix {@link GraphModelObject} to graphenix {@link AuthoringGraphDocument} for plan compilation.
|
|
5
|
+
*/
|
|
6
|
+
export declare function migrateExellixGraphModelToAuthoring(model: Graph | GraphModelObject): AuthoringGraphDocument;
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { GRAPHENIX_FORMAT_VERSION } from '@x12i/graphenix-core';
|
|
2
|
+
import { EXECUTABLE_PROFILE_NAMESPACE, EXECUTABLE_PROFILE_VERSION, FINALIZER_NODE_KIND, FINALIZER_NODE_PROFILE, TASK_NODE_KIND, TASK_NODE_PROFILE, } from '@x12i/graphenix-executable-contracts';
|
|
3
|
+
import { EXELLIX_STRUCTURED_DATA_FILTERS_V1 } from '../types/refs.js';
|
|
4
|
+
import { DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG } from '../runtime/graphAiModelConfig.js';
|
|
5
|
+
import { migrateLegacyGraphResponse } from '../runtime/graphResponseMigration.js';
|
|
6
|
+
function isPlainRecord(v) {
|
|
7
|
+
return v != null && typeof v === 'object' && !Array.isArray(v);
|
|
8
|
+
}
|
|
9
|
+
function aliasToProfileChoice(value) {
|
|
10
|
+
const trimmed = value.trim();
|
|
11
|
+
if (trimmed.includes('/'))
|
|
12
|
+
return { kind: 'profileChoice', key: trimmed };
|
|
13
|
+
const shortcuts = {
|
|
14
|
+
cheap: 'cheap/default',
|
|
15
|
+
balanced: 'vol/default',
|
|
16
|
+
deep: 'deep/openai_deep',
|
|
17
|
+
pro: 'pro/default',
|
|
18
|
+
};
|
|
19
|
+
const key = shortcuts[trimmed] ?? `${trimmed}/default`;
|
|
20
|
+
return { kind: 'profileChoice', key };
|
|
21
|
+
}
|
|
22
|
+
function exellixModelConfigToExecutable(modelConfig) {
|
|
23
|
+
if (!modelConfig?.cases?.length)
|
|
24
|
+
return undefined;
|
|
25
|
+
const cases = modelConfig.cases.map((c, index) => {
|
|
26
|
+
const mc = c.modelConfig;
|
|
27
|
+
const modelConfigOut = {};
|
|
28
|
+
if (mc.preActionModel != null && String(mc.preActionModel).trim() !== '') {
|
|
29
|
+
modelConfigOut.preActionModel = aliasToProfileChoice(String(mc.preActionModel));
|
|
30
|
+
}
|
|
31
|
+
if (mc.skillModel != null && String(mc.skillModel).trim() !== '') {
|
|
32
|
+
modelConfigOut.skillModel = aliasToProfileChoice(String(mc.skillModel));
|
|
33
|
+
}
|
|
34
|
+
if (mc.postActionModel != null && String(mc.postActionModel).trim() !== '') {
|
|
35
|
+
modelConfigOut.postActionModel = aliasToProfileChoice(String(mc.postActionModel));
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
id: c.when == null ? 'default' : `case-${index}`,
|
|
39
|
+
...(c.when != null ? { when: c.when } : {}),
|
|
40
|
+
modelConfig: modelConfigOut,
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
const hasPartialCase = cases.some((c) => !c.modelConfig.preActionModel ||
|
|
44
|
+
!c.modelConfig.skillModel ||
|
|
45
|
+
!c.modelConfig.postActionModel);
|
|
46
|
+
return {
|
|
47
|
+
version: 'graph-model-config/v1',
|
|
48
|
+
cases,
|
|
49
|
+
...(hasPartialCase ? { inherit: true } : {}),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const DEFAULT_EXECUTABLE_FALLBACK_POLICY = {
|
|
53
|
+
enabled: true,
|
|
54
|
+
allowedTriggers: [
|
|
55
|
+
'nodeSlotMissing',
|
|
56
|
+
'nodeModelUnavailable',
|
|
57
|
+
'nodeModelUnsupported',
|
|
58
|
+
'nodeProviderNotConfigured',
|
|
59
|
+
'nodeModelRateLimited',
|
|
60
|
+
'nodeModelTransientFailure',
|
|
61
|
+
],
|
|
62
|
+
maxAttemptsPerSlot: 1,
|
|
63
|
+
};
|
|
64
|
+
function defaultExecutableModelConfig() {
|
|
65
|
+
const mc = DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG;
|
|
66
|
+
return {
|
|
67
|
+
version: 'graph-model-config/v1',
|
|
68
|
+
cases: [
|
|
69
|
+
{
|
|
70
|
+
id: 'default',
|
|
71
|
+
modelConfig: {
|
|
72
|
+
preActionModel: aliasToProfileChoice(mc.preActionModel),
|
|
73
|
+
skillModel: aliasToProfileChoice(mc.skillModel),
|
|
74
|
+
postActionModel: aliasToProfileChoice(mc.postActionModel),
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
fallbackPolicy: DEFAULT_EXECUTABLE_FALLBACK_POLICY,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function isStructuredExellixDataFilters(value) {
|
|
82
|
+
return (isPlainRecord(value) &&
|
|
83
|
+
value.version === EXELLIX_STRUCTURED_DATA_FILTERS_V1 &&
|
|
84
|
+
isPlainRecord(value.when));
|
|
85
|
+
}
|
|
86
|
+
function exellixGraphEntryToAuthoring(graphEntry) {
|
|
87
|
+
if (!isPlainRecord(graphEntry))
|
|
88
|
+
return graphEntry;
|
|
89
|
+
const next = structuredClone(graphEntry);
|
|
90
|
+
const dataFilters = next.dataFilters;
|
|
91
|
+
if (isStructuredExellixDataFilters(dataFilters)) {
|
|
92
|
+
next.dataFilters = [dataFilters.when];
|
|
93
|
+
}
|
|
94
|
+
return next;
|
|
95
|
+
}
|
|
96
|
+
/** Authoring validation requires jsonConditions as an array; exellix uses a CaseCondition object. */
|
|
97
|
+
function exellixConditionsToAuthoring(conditions) {
|
|
98
|
+
if (Array.isArray(conditions)) {
|
|
99
|
+
return { runWhen: conditions };
|
|
100
|
+
}
|
|
101
|
+
const runWhenEntry = {};
|
|
102
|
+
if (conditions.jsonConditions != null) {
|
|
103
|
+
runWhenEntry.jsonConditions = structuredClone(conditions.jsonConditions);
|
|
104
|
+
}
|
|
105
|
+
if (conditions.jsConditionFunction != null) {
|
|
106
|
+
runWhenEntry.jsConditionFunction = structuredClone(conditions.jsConditionFunction);
|
|
107
|
+
}
|
|
108
|
+
if (conditions.aiCondition != null) {
|
|
109
|
+
runWhenEntry.aiCondition = structuredClone(conditions.aiCondition);
|
|
110
|
+
}
|
|
111
|
+
const out = {};
|
|
112
|
+
if (Object.keys(runWhenEntry).length > 0) {
|
|
113
|
+
out.runWhen = [runWhenEntry];
|
|
114
|
+
}
|
|
115
|
+
if (conditions.dataFilters != null) {
|
|
116
|
+
out.dataFilters = structuredClone(conditions.dataFilters);
|
|
117
|
+
}
|
|
118
|
+
if (conditions.narratives != null) {
|
|
119
|
+
out.narratives = structuredClone(conditions.narratives);
|
|
120
|
+
}
|
|
121
|
+
return out;
|
|
122
|
+
}
|
|
123
|
+
function defaultPorts(nodeId) {
|
|
124
|
+
return {
|
|
125
|
+
in: `in:${nodeId}`,
|
|
126
|
+
out: `out:${nodeId}`,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function exellixTaskNodeToExecutable(node) {
|
|
130
|
+
const ports = defaultPorts(String(node.id));
|
|
131
|
+
const params = {
|
|
132
|
+
profile: TASK_NODE_PROFILE,
|
|
133
|
+
nodeType: 'task',
|
|
134
|
+
skillKey: node.skillKey,
|
|
135
|
+
};
|
|
136
|
+
if (node.taskConfiguration != null)
|
|
137
|
+
params.taskConfiguration = structuredClone(node.taskConfiguration);
|
|
138
|
+
if (node.taskVariable != null)
|
|
139
|
+
params.taskVariable = structuredClone(node.taskVariable);
|
|
140
|
+
if (node.inputsConfig != null)
|
|
141
|
+
params.inputsConfig = structuredClone(node.inputsConfig);
|
|
142
|
+
if (node.executionMapping != null)
|
|
143
|
+
params.executionMapping = structuredClone(node.executionMapping);
|
|
144
|
+
if (node.conditions != null)
|
|
145
|
+
params.conditions = exellixConditionsToAuthoring(node.conditions);
|
|
146
|
+
if (Array.isArray(node.taskKnowledge)) {
|
|
147
|
+
params.taskKnowledge = exellixKnowledgeRefsToAuthoring(node.taskKnowledge);
|
|
148
|
+
}
|
|
149
|
+
if (node.variables != null)
|
|
150
|
+
params.variables = structuredClone(node.variables);
|
|
151
|
+
if (node.metadata != null)
|
|
152
|
+
params.metadata = structuredClone(node.metadata);
|
|
153
|
+
if (node.executionPipeline != null)
|
|
154
|
+
params.executionPipeline = structuredClone(node.executionPipeline);
|
|
155
|
+
if (node.jobContextMapping != null)
|
|
156
|
+
params.jobContextMapping = structuredClone(node.jobContextMapping);
|
|
157
|
+
if (node.scope != null)
|
|
158
|
+
params.scope = structuredClone(node.scope);
|
|
159
|
+
if (node.smartInput != null)
|
|
160
|
+
params.smartInput = exellixSmartInputToAuthoring(node.smartInput);
|
|
161
|
+
if (node.outputValidation != null)
|
|
162
|
+
params.outputValidation = structuredClone(node.outputValidation);
|
|
163
|
+
const nodeModelConfig = node.taskConfiguration?.modelConfig;
|
|
164
|
+
if (nodeModelConfig != null) {
|
|
165
|
+
const converted = exellixModelConfigToExecutable(nodeModelConfig);
|
|
166
|
+
if (converted) {
|
|
167
|
+
params.taskConfiguration = {
|
|
168
|
+
...(isPlainRecord(params.taskConfiguration) ? params.taskConfiguration : {}),
|
|
169
|
+
modelConfig: converted,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
id: String(node.id),
|
|
175
|
+
kind: TASK_NODE_KIND,
|
|
176
|
+
inputs: [{ id: ports.in, direction: 'input', type: 'builtin:object', required: false }],
|
|
177
|
+
outputs: [{ id: ports.out, direction: 'output', type: 'builtin:object' }],
|
|
178
|
+
parameters: params,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
function exellixSmartInputToAuthoring(smartInput) {
|
|
182
|
+
if (!isPlainRecord(smartInput))
|
|
183
|
+
return structuredClone(smartInput);
|
|
184
|
+
const next = structuredClone(smartInput);
|
|
185
|
+
if (Array.isArray(next.paths)) {
|
|
186
|
+
next.paths = next.paths.map((entry) => typeof entry === 'string' ? { path: entry } : entry);
|
|
187
|
+
}
|
|
188
|
+
return next;
|
|
189
|
+
}
|
|
190
|
+
function exellixKnowledgeRefsToAuthoring(refs) {
|
|
191
|
+
return refs.map((ref) => ({ id: ref }));
|
|
192
|
+
}
|
|
193
|
+
function exellixFinalizerToExecutable(node) {
|
|
194
|
+
const n = node;
|
|
195
|
+
const ports = defaultPorts(String(node.id));
|
|
196
|
+
return {
|
|
197
|
+
id: String(node.id),
|
|
198
|
+
kind: FINALIZER_NODE_KIND,
|
|
199
|
+
inputs: [{ id: ports.in, direction: 'input', type: 'builtin:object', required: false }],
|
|
200
|
+
outputs: [{ id: ports.out, direction: 'output', type: 'builtin:object' }],
|
|
201
|
+
parameters: {
|
|
202
|
+
profile: FINALIZER_NODE_PROFILE,
|
|
203
|
+
nodeType: 'finalizer',
|
|
204
|
+
finalizerType: n.finalizerType,
|
|
205
|
+
config: isPlainRecord(n.config) ? structuredClone(n.config) : {},
|
|
206
|
+
...(n.inputs != null ? { inputs: structuredClone(n.inputs) } : {}),
|
|
207
|
+
...(n.outputMapping != null ? { outputMapping: structuredClone(n.outputMapping) } : {}),
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Converts exellix {@link GraphModelObject} to graphenix {@link AuthoringGraphDocument} for plan compilation.
|
|
213
|
+
*/
|
|
214
|
+
export function migrateExellixGraphModelToAuthoring(model) {
|
|
215
|
+
const legacyMigrated = migrateLegacyGraphResponse(structuredClone(model));
|
|
216
|
+
const source = legacyMigrated.graph;
|
|
217
|
+
const executableModelConfig = exellixModelConfigToExecutable(source.modelConfig) ?? defaultExecutableModelConfig();
|
|
218
|
+
const metadata = isPlainRecord(source.metadata) ? structuredClone(source.metadata) : {};
|
|
219
|
+
const extensions = isPlainRecord(metadata.extensions) ? { ...metadata.extensions } : {};
|
|
220
|
+
extensions[EXECUTABLE_PROFILE_NAMESPACE] = {
|
|
221
|
+
...(isPlainRecord(extensions[EXECUTABLE_PROFILE_NAMESPACE])
|
|
222
|
+
? extensions[EXECUTABLE_PROFILE_NAMESPACE]
|
|
223
|
+
: {}),
|
|
224
|
+
profileVersion: EXECUTABLE_PROFILE_VERSION,
|
|
225
|
+
modelConfig: executableModelConfig,
|
|
226
|
+
};
|
|
227
|
+
metadata.extensions = extensions;
|
|
228
|
+
if (metadata.graphEntry != null) {
|
|
229
|
+
metadata.graphEntry = exellixGraphEntryToAuthoring(metadata.graphEntry);
|
|
230
|
+
}
|
|
231
|
+
if (Array.isArray(source.jobKnowledge)) {
|
|
232
|
+
metadata.jobKnowledge = exellixKnowledgeRefsToAuthoring(source.jobKnowledge);
|
|
233
|
+
}
|
|
234
|
+
const nodes = (source.nodes ?? []).map((node) => {
|
|
235
|
+
const type = node.type ?? 'task';
|
|
236
|
+
if (type === 'finalizer')
|
|
237
|
+
return exellixFinalizerToExecutable(node);
|
|
238
|
+
return exellixTaskNodeToExecutable(node);
|
|
239
|
+
});
|
|
240
|
+
const portByNode = new Map();
|
|
241
|
+
for (const n of nodes)
|
|
242
|
+
portByNode.set(n.id, defaultPorts(n.id));
|
|
243
|
+
const edges = (source.edges ?? []).map((e, index) => {
|
|
244
|
+
const fromPorts = portByNode.get(e.from) ?? defaultPorts(e.from);
|
|
245
|
+
const toPorts = portByNode.get(e.to) ?? defaultPorts(e.to);
|
|
246
|
+
return {
|
|
247
|
+
id: `edge:${index}:${e.from}->${e.to}`,
|
|
248
|
+
from: { nodeId: e.from, portId: fromPorts.out },
|
|
249
|
+
to: { nodeId: e.to, portId: toPorts.in },
|
|
250
|
+
...(e.when != null ? { when: e.when } : {}),
|
|
251
|
+
};
|
|
252
|
+
});
|
|
253
|
+
const graphResponse = isPlainRecord(source.response)
|
|
254
|
+
? { shape: source.response.shape, ...source.response }
|
|
255
|
+
: undefined;
|
|
256
|
+
return {
|
|
257
|
+
formatVersion: GRAPHENIX_FORMAT_VERSION,
|
|
258
|
+
id: String(source.id),
|
|
259
|
+
revision: typeof source.version === 'string' ? source.version : '1.0.0',
|
|
260
|
+
name: typeof metadata.name === 'string' ? metadata.name : String(source.id),
|
|
261
|
+
graph: {
|
|
262
|
+
nodes,
|
|
263
|
+
edges,
|
|
264
|
+
inputs: [],
|
|
265
|
+
outputs: [],
|
|
266
|
+
metadata: {
|
|
267
|
+
...metadata,
|
|
268
|
+
...(graphResponse ? { graphResponse } : {}),
|
|
269
|
+
graphEntry: metadata.graphEntry,
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ExecutableGraphPlanV2 } from '@x12i/graphenix-executable-contracts';
|
|
2
|
+
import type { GraphRuntimeObject } from '../runtime/ExellixGraphRuntime.js';
|
|
3
|
+
/**
|
|
4
|
+
* `@x12i/graphenix-plan-compiler` v1.0.0 builds AI finalizer plans without resolved
|
|
5
|
+
* `finalizerModel` slots. Rebuild finalizer plans using published compiler helpers.
|
|
6
|
+
*/
|
|
7
|
+
export declare function patchFinalizerPlansOnExecutablePlan(plan: ExecutableGraphPlanV2, runtime: GraphRuntimeObject): ExecutableGraphPlanV2;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { getFinalizerNodeConfig, isExecutableFinalizerNode, } from '@x12i/graphenix-executable-contracts';
|
|
2
|
+
import { buildFinalizerPlans, buildDeterministicCaseContext, resolveGraphModelConfig, } from '@x12i/graphenix-plan-compiler';
|
|
3
|
+
const AI_FINALIZER_TYPES = new Set(['synthesize']);
|
|
4
|
+
/**
|
|
5
|
+
* `@x12i/graphenix-plan-compiler` v1.0.0 builds AI finalizer plans without resolved
|
|
6
|
+
* `finalizerModel` slots. Rebuild finalizer plans using published compiler helpers.
|
|
7
|
+
*/
|
|
8
|
+
export function patchFinalizerPlansOnExecutablePlan(plan, runtime) {
|
|
9
|
+
if (plan.normalizedGraph.mode !== 'embedded')
|
|
10
|
+
return plan;
|
|
11
|
+
const normalized = plan.normalizedGraph.graph;
|
|
12
|
+
const aiFinalizers = normalized.graph.nodes.filter(isExecutableFinalizerNode).filter((node) => {
|
|
13
|
+
const config = getFinalizerNodeConfig(node);
|
|
14
|
+
return config != null && AI_FINALIZER_TYPES.has(String(config.finalizerType));
|
|
15
|
+
});
|
|
16
|
+
if (aiFinalizers.length === 0)
|
|
17
|
+
return plan;
|
|
18
|
+
const context = buildDeterministicCaseContext(normalized, runtime);
|
|
19
|
+
const graphResolution = resolveGraphModelConfig(normalized, context);
|
|
20
|
+
const triplet = graphResolution.triplet;
|
|
21
|
+
if (triplet.preActionModel == null && triplet.skillModel == null && triplet.postActionModel == null) {
|
|
22
|
+
return plan;
|
|
23
|
+
}
|
|
24
|
+
const slotMeta = {
|
|
25
|
+
source: 'graphDefault',
|
|
26
|
+
inherited: true,
|
|
27
|
+
graphCaseId: graphResolution.caseId,
|
|
28
|
+
};
|
|
29
|
+
const resolvedFinalizerSlots = {};
|
|
30
|
+
for (const node of aiFinalizers) {
|
|
31
|
+
const finalizerSelection = triplet.postActionModel ?? triplet.skillModel ?? triplet.preActionModel;
|
|
32
|
+
if (finalizerSelection == null)
|
|
33
|
+
continue;
|
|
34
|
+
resolvedFinalizerSlots[node.id] = {
|
|
35
|
+
selection: finalizerSelection,
|
|
36
|
+
...slotMeta,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const finalizerPlans = buildFinalizerPlans(normalized, resolvedFinalizerSlots);
|
|
40
|
+
for (const node of aiFinalizers) {
|
|
41
|
+
const entry = finalizerPlans[node.id];
|
|
42
|
+
if (!entry)
|
|
43
|
+
continue;
|
|
44
|
+
entry.modelSlots = {
|
|
45
|
+
...(triplet.preActionModel != null
|
|
46
|
+
? { preActionModel: { selection: triplet.preActionModel, ...slotMeta } }
|
|
47
|
+
: {}),
|
|
48
|
+
...(triplet.skillModel != null
|
|
49
|
+
? { skillModel: { selection: triplet.skillModel, ...slotMeta } }
|
|
50
|
+
: {}),
|
|
51
|
+
...(triplet.postActionModel != null
|
|
52
|
+
? { postActionModel: { selection: triplet.postActionModel, ...slotMeta } }
|
|
53
|
+
: {}),
|
|
54
|
+
...(entry.modelSlots?.finalizerModel != null
|
|
55
|
+
? { finalizerModel: entry.modelSlots.finalizerModel }
|
|
56
|
+
: {}),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
...plan,
|
|
61
|
+
finalizerPlans,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -13,6 +13,11 @@ 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
|
+
/**
|
|
17
|
+
* Graphs-studio execute envelope carries a removed or forbidden key (e.g. request-level `graphDefaultModel`).
|
|
18
|
+
* Model defaults belong on `graph.modelConfig` only.
|
|
19
|
+
*/
|
|
20
|
+
NON_CANONICAL_STUDIO_GRAPH_EXECUTE_REQUEST = "NON_CANONICAL_STUDIO_GRAPH_EXECUTE_REQUEST",
|
|
16
21
|
/** Runtime object carries forbidden model / llmCall overrides (graph document only since 7.7). */
|
|
17
22
|
NON_CANONICAL_GRAPH_RUNTIME = "NON_CANONICAL_GRAPH_RUNTIME",
|
|
18
23
|
/**
|
|
@@ -14,6 +14,11 @@ 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
|
+
/**
|
|
18
|
+
* Graphs-studio execute envelope carries a removed or forbidden key (e.g. request-level `graphDefaultModel`).
|
|
19
|
+
* Model defaults belong on `graph.modelConfig` only.
|
|
20
|
+
*/
|
|
21
|
+
ExellixGraphErrorCode["NON_CANONICAL_STUDIO_GRAPH_EXECUTE_REQUEST"] = "NON_CANONICAL_STUDIO_GRAPH_EXECUTE_REQUEST";
|
|
17
22
|
/** Runtime object carries forbidden model / llmCall overrides (graph document only since 7.7). */
|
|
18
23
|
ExellixGraphErrorCode["NON_CANONICAL_GRAPH_RUNTIME"] = "NON_CANONICAL_GRAPH_RUNTIME";
|
|
19
24
|
/**
|
package/dist/src/index.d.ts
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* 5. Repeat until done/fail
|
|
10
10
|
*
|
|
11
11
|
* Single canonical entry point: {@link createExellixGraphRuntime} returns
|
|
12
|
-
* `{ executeGraph({
|
|
13
|
-
*
|
|
12
|
+
* `{ executeGraph({ plan, runtime }: GraphExecutionRequest) }`. Hosts compile upstream via
|
|
13
|
+
* {@link compileExellixExecutablePlan} or `@x12i/graphenix-plan-compiler`.
|
|
14
14
|
*/
|
|
15
15
|
export type { HostExecuteGraphRunOptions, MainReadinessPolicy, ExecutionStepOption, StepRetryPolicy, ActivixNodeActivityExellixConfig, SkillKeyResolutionOptions, RunTaskRequest as ExellixGraphRunTaskRequest, RunTaskResponse as ExellixGraphRunTaskResponse, } from './types/options.js';
|
|
16
16
|
export type { AiTaskProfileMetadata, AiTaskProfileWebScoping, AiTaskProfileInputSynthesis, } from './types/aiTaskProfile.js';
|
|
@@ -83,11 +83,18 @@ export type { AssertCanonicalGraphDocumentOptions, CanonicalGraphDocumentValidat
|
|
|
83
83
|
export { assertCanonicalGraphRuntimeObject } from './runtime/validateCanonicalGraphRuntime.js';
|
|
84
84
|
export { GRAPH_ENTRY_STUDIO_ONLY_KEYS, GRAPH_METADATA_STUDIO_ONLY_KEYS, stripGraphModelStudioFields, primaryRuntimeInputFromStudioDocument, getGraphEntryStudioOnlyKeyViolations, getGraphMetadataStudioOnlyKeyViolations, getGraphEntryEmptyInputPathViolations, } from './runtime/graphModelStudioSeparation.js';
|
|
85
85
|
export type { GraphStudioDocument } from './runtime/graphModelStudioSeparation.js';
|
|
86
|
+
export { STUDIO_GRAPH_EXECUTE_REMOVED_KEYS, getStudioGraphExecuteRemovedKeyViolations, assertCanonicalStudioGraphExecuteRequest, buildGraphExecutionRequestFromStudioExecute, } from './runtime/studioGraphExecuteRequest.js';
|
|
87
|
+
export type { StudioGraphExecuteRemovedKey, StudioGraphExecuteRequest, BuildGraphExecutionRequestFromStudioExecuteOptions, } from './runtime/studioGraphExecuteRequest.js';
|
|
86
88
|
export { computeGraphDocumentContentSha256, stableStringifyGraphDocument, } from './runtime/graphDocumentFingerprint.js';
|
|
87
89
|
export { migrateLegacyGraphResponse, migrateLegacyGraphResponseDefinition, } from './runtime/graphResponseMigration.js';
|
|
88
90
|
export type { MigrateGraphResponseResult } from './runtime/graphResponseMigration.js';
|
|
89
91
|
export { applyAiTaskProfileWebScopingToNarrix, mapAiTaskProfileQuestionsToWebScopeQuestions, } from './runtime/applyAiTaskProfileWebScopingToNarrix.js';
|
|
90
92
|
export { createExellixGraphRuntime } from './runtime/ExellixGraphRuntime.js';
|
|
93
|
+
export type { ExecutableGraphPlanV2, NodeExecutionPlan, ExecutionUnitPlanV2, } from '@x12i/graphenix-executable-contracts';
|
|
94
|
+
export { compileExellixExecutablePlan } from './adapters/compileExellixExecutablePlan.js';
|
|
95
|
+
export type { CompileExellixExecutablePlanOptions } from './adapters/compileExellixExecutablePlan.js';
|
|
96
|
+
export { migrateExellixGraphModelToAuthoring } from './adapters/migrateExellixGraphModelToAuthoring.js';
|
|
97
|
+
export { buildGraphExecutionRequestFromStudioExecute as buildAuthoringStudioGraphExecutionRequest } from '@x12i/graphenix-execute-envelope';
|
|
91
98
|
export type { RunTaskRequest, RunTaskResponse, TasksClientLike, GraphLoader as RuntimeGraphLoader, ExecuteGraphInput, GraphExecutionRequest, GraphRuntimeObject, GraphKnowledgeResolver, GraphKnowledgeResolverContext, ExecuteGraphResult, ExellixGraphRuntimeOptions, } from './runtime/ExellixGraphRuntime.js';
|
|
92
99
|
export type { PlanStatus, GraphPlan, GraphEngine, GraphEngineFactory, } from './runtime/GraphEngine.js';
|
|
93
100
|
export { InMemoryGraphLoader, DepGraphEngineFactory } from '../testkit/index.js';
|
package/dist/src/index.js
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* 5. Repeat until done/fail
|
|
10
10
|
*
|
|
11
11
|
* Single canonical entry point: {@link createExellixGraphRuntime} returns
|
|
12
|
-
* `{ executeGraph({
|
|
13
|
-
*
|
|
12
|
+
* `{ executeGraph({ plan, runtime }: GraphExecutionRequest) }`. Hosts compile upstream via
|
|
13
|
+
* {@link compileExellixExecutablePlan} or `@x12i/graphenix-plan-compiler`.
|
|
14
14
|
*/
|
|
15
15
|
export { mergeGraphDocumentModel, EXELLIX_GRAPH_MODEL_VARIABLE_KEY, EXELLIX_STRUCTURED_DATA_FILTERS_V1, } from './types/refs.js';
|
|
16
16
|
export { getTaskConfiguration } from './types/taskNodeConfiguration.js';
|
|
@@ -61,11 +61,15 @@ export { buildExellixGraphRuntimeObjects, setRuntimeObjectsLastJobId, summarizeR
|
|
|
61
61
|
export { assertCanonicalGraphDocument, assertCanonicalTaskNode, getCanonicalGraphDocumentViolations, CANONICAL_GRAPH_TOP_LEVEL_KEYS, } from './runtime/validateCanonicalGraphDocument.js';
|
|
62
62
|
export { assertCanonicalGraphRuntimeObject } from './runtime/validateCanonicalGraphRuntime.js';
|
|
63
63
|
export { GRAPH_ENTRY_STUDIO_ONLY_KEYS, GRAPH_METADATA_STUDIO_ONLY_KEYS, stripGraphModelStudioFields, primaryRuntimeInputFromStudioDocument, getGraphEntryStudioOnlyKeyViolations, getGraphMetadataStudioOnlyKeyViolations, getGraphEntryEmptyInputPathViolations, } from './runtime/graphModelStudioSeparation.js';
|
|
64
|
+
export { STUDIO_GRAPH_EXECUTE_REMOVED_KEYS, getStudioGraphExecuteRemovedKeyViolations, assertCanonicalStudioGraphExecuteRequest, buildGraphExecutionRequestFromStudioExecute, } from './runtime/studioGraphExecuteRequest.js';
|
|
64
65
|
export { computeGraphDocumentContentSha256, stableStringifyGraphDocument, } from './runtime/graphDocumentFingerprint.js';
|
|
65
66
|
export { migrateLegacyGraphResponse, migrateLegacyGraphResponseDefinition, } from './runtime/graphResponseMigration.js';
|
|
66
67
|
export { applyAiTaskProfileWebScopingToNarrix, mapAiTaskProfileQuestionsToWebScopeQuestions, } from './runtime/applyAiTaskProfileWebScopingToNarrix.js';
|
|
67
68
|
// New runtime with injection seam
|
|
68
69
|
export { createExellixGraphRuntime } from './runtime/ExellixGraphRuntime.js';
|
|
70
|
+
export { compileExellixExecutablePlan } from './adapters/compileExellixExecutablePlan.js';
|
|
71
|
+
export { migrateExellixGraphModelToAuthoring } from './adapters/migrateExellixGraphModelToAuthoring.js';
|
|
72
|
+
export { buildGraphExecutionRequestFromStudioExecute as buildAuthoringStudioGraphExecutionRequest } from '@x12i/graphenix-execute-envelope';
|
|
69
73
|
// Testkit (in-memory loader, dep engine, recording client — sample NARRIX tasks: `@exellix/graph-engine/testkit`)
|
|
70
74
|
export { InMemoryGraphLoader, DepGraphEngineFactory } from '../testkit/index.js';
|
|
71
75
|
// Graph loaders
|
|
@@ -149,11 +149,18 @@ export function createActivixNodeActivityIntegration(ax, options) {
|
|
|
149
149
|
: typeof err === 'object' && err && 'message' in err
|
|
150
150
|
? String(err.message)
|
|
151
151
|
: String(err ?? 'unknown error');
|
|
152
|
+
const errorCode = (() => {
|
|
153
|
+
if (err == null || typeof err !== 'object')
|
|
154
|
+
return undefined;
|
|
155
|
+
const code = err.code;
|
|
156
|
+
return code != null ? String(code) : undefined;
|
|
157
|
+
})();
|
|
152
158
|
const outerResponse = nodeEvent.data?.response;
|
|
153
159
|
const outerMemoryEnd = nodeEvent.data?.memoryAfter;
|
|
154
160
|
const recordId = await recordPromise;
|
|
155
161
|
await ax.failRecord(recordId, message, {
|
|
156
162
|
failedAt: nodeEvent.timestamp,
|
|
163
|
+
...(errorCode != null ? { errorCode } : {}),
|
|
157
164
|
outer: {
|
|
158
165
|
output: {
|
|
159
166
|
response: outerResponse,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AiModelSelection } from '@x12i/graphenix-executable-contracts';
|
|
2
|
+
import type { ResolvedInvocationSnapshot } from '@x12i/graphenix-executable-contracts';
|
|
3
|
+
/**
|
|
4
|
+
* Maps plan {@link AiModelSelection} to ai-tasks 8.4+ wire profile strings.
|
|
5
|
+
*/
|
|
6
|
+
export declare function aiModelSelectionToWireString(selection: AiModelSelection | undefined): string | undefined;
|
|
7
|
+
export declare function resolvedSnapshotToWireString(snapshot: ResolvedInvocationSnapshot | undefined): string | undefined;
|
|
8
|
+
export declare function unitModelWireString(args: {
|
|
9
|
+
modelSelection?: AiModelSelection;
|
|
10
|
+
resolvedInvocationSnapshot?: ResolvedInvocationSnapshot;
|
|
11
|
+
}): string | undefined;
|