@exellix/graph-engine 8.0.0 → 8.1.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 +27 -1
- package/README.md +11 -12
- package/dist/src/compile/authoringDocumentHelpers.d.ts +9 -0
- package/dist/src/compile/authoringDocumentHelpers.js +18 -0
- package/dist/src/compile/compileExellixExecutablePlan.d.ts +8 -0
- package/dist/src/compile/compileExellixExecutablePlan.js +75 -0
- package/dist/src/index.d.ts +4 -6
- package/dist/src/index.js +2 -4
- package/dist/src/runtime/ExellixGraphRuntime.d.ts +11 -37
- package/dist/src/runtime/ExellixGraphRuntime.js +78 -173
- package/dist/src/runtime/aiTasksStrategyPhases.js +7 -3
- package/dist/src/runtime/buildAiTasksRunTaskRequest.d.ts +6 -8
- package/dist/src/runtime/buildAiTasksRunTaskRequest.js +2 -7
- package/dist/src/runtime/executionMatrixHost.d.ts +6 -3
- package/dist/src/runtime/executionMatrixHost.js +6 -4
- package/dist/src/runtime/runTaskNodePlan.d.ts +15 -0
- package/dist/src/runtime/runTaskNodePlan.js +46 -0
- package/dist/src/runtime/studioGraphExecuteRequest.d.ts +5 -30
- package/dist/src/runtime/studioGraphExecuteRequest.js +14 -50
- package/dist/src/runtime/taskNodeRunTaskPreflight.d.ts +7 -5
- package/dist/src/runtime/taskNodeRunTaskPreflight.js +31 -26
- package/dist/src/types/refs.d.ts +1 -1
- package/dist/testkit/authoringGraphFixtures.d.ts +8 -0
- package/dist/testkit/authoringGraphFixtures.js +249 -0
- package/dist/testkit/buildExecuteGraphInput.d.ts +3 -3
- package/dist/testkit/buildExecuteGraphInput.js +8 -4
- package/dist/testkit/flatGraphToAuthoring.d.ts +29 -0
- package/dist/testkit/flatGraphToAuthoring.js +281 -0
- package/dist/testkit/index.d.ts +3 -0
- package/dist/testkit/index.js +3 -0
- package/dist/testkit/runTaskNodePlanAssertions.d.ts +34 -0
- package/dist/testkit/runTaskNodePlanAssertions.js +32 -0
- package/package.json +8 -7
- package/dist/src/adapters/compileExellixExecutablePlan.d.ts +0 -8
- package/dist/src/adapters/compileExellixExecutablePlan.js +0 -18
- package/dist/src/adapters/migrateExellixGraphModelToAuthoring.d.ts +0 -6
- package/dist/src/adapters/migrateExellixGraphModelToAuthoring.js +0 -273
- package/dist/src/adapters/patchFinalizerPlans.d.ts +0 -7
- package/dist/src/adapters/patchFinalizerPlans.js +0 -63
- package/dist/src/runtime/graphResponseMigration.d.ts +0 -7
- package/dist/src/runtime/graphResponseMigration.js +0 -44
|
@@ -1,273 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
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;
|
|
@@ -1,63 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { GraphModelObject } from '../types/refs.js';
|
|
2
|
-
export type MigrateGraphResponseResult<T> = {
|
|
3
|
-
graph: T;
|
|
4
|
-
migrated: boolean;
|
|
5
|
-
};
|
|
6
|
-
export declare function migrateLegacyGraphResponseDefinition<T extends object>(graph: T): MigrateGraphResponseResult<T>;
|
|
7
|
-
export declare function migrateLegacyGraphResponse<T extends GraphModelObject | object>(graph: T): MigrateGraphResponseResult<T>;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
const LEGACY_RESPONSE_DROP_KEYS = new Set([
|
|
2
|
-
'version',
|
|
3
|
-
'target',
|
|
4
|
-
'primaryResponsePaths',
|
|
5
|
-
'debugResponsePaths',
|
|
6
|
-
'notableExecutionPaths',
|
|
7
|
-
'mappingPreset',
|
|
8
|
-
]);
|
|
9
|
-
function isPlainObject(value) {
|
|
10
|
-
return value != null && typeof value === 'object' && !Array.isArray(value);
|
|
11
|
-
}
|
|
12
|
-
function cloneGraph(graph) {
|
|
13
|
-
return structuredClone(graph);
|
|
14
|
-
}
|
|
15
|
-
export function migrateLegacyGraphResponseDefinition(graph) {
|
|
16
|
-
const graphRecord = graph;
|
|
17
|
-
const metadata = isPlainObject(graphRecord.metadata) ? graphRecord.metadata : undefined;
|
|
18
|
-
const graphResponse = metadata && isPlainObject(metadata.graphResponse) ? metadata.graphResponse : undefined;
|
|
19
|
-
const legacyMapping = graphResponse && isPlainObject(graphResponse.responseMapping)
|
|
20
|
-
? graphResponse.responseMapping
|
|
21
|
-
: undefined;
|
|
22
|
-
if (graphRecord.response !== undefined || !legacyMapping) {
|
|
23
|
-
return { graph, migrated: false };
|
|
24
|
-
}
|
|
25
|
-
const next = cloneGraph(graph);
|
|
26
|
-
const nextRecord = next;
|
|
27
|
-
const response = {};
|
|
28
|
-
for (const [key, value] of Object.entries(legacyMapping)) {
|
|
29
|
-
if (LEGACY_RESPONSE_DROP_KEYS.has(key))
|
|
30
|
-
continue;
|
|
31
|
-
response[key] = value;
|
|
32
|
-
}
|
|
33
|
-
if (!Object.prototype.hasOwnProperty.call(response, 'missing')) {
|
|
34
|
-
response.missing = 'omit';
|
|
35
|
-
}
|
|
36
|
-
nextRecord.response = response;
|
|
37
|
-
if (isPlainObject(nextRecord.metadata)) {
|
|
38
|
-
delete nextRecord.metadata.graphResponse;
|
|
39
|
-
}
|
|
40
|
-
return { graph: next, migrated: true };
|
|
41
|
-
}
|
|
42
|
-
export function migrateLegacyGraphResponse(graph) {
|
|
43
|
-
return migrateLegacyGraphResponseDefinition(graph);
|
|
44
|
-
}
|