@codemation/core 0.0.19 → 0.2.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 +16 -0
- package/dist/EngineRuntimeRegistration.types-0sgV2XL2.d.ts +42 -0
- package/dist/EngineWorkflowRunnerService-Dx7bJsJR.d.cts +73 -0
- package/dist/InMemoryRunDataFactory-qIYQEar7.d.cts +94 -0
- package/dist/{InMemoryLiveWorkflowRepository-DxoualoC.d.ts → RunIntentService-BCvGdOSY.d.ts} +438 -9
- package/dist/{RunIntentService-C1nu_YwM.js → RunIntentService-BFA48UpH.js} +252 -67
- package/dist/RunIntentService-BFA48UpH.js.map +1 -0
- package/dist/{InMemoryLiveWorkflowRepository-orY1VsWG.d.cts → RunIntentService-CV8izV8t.d.cts} +214 -7
- package/dist/{RunIntentService-ZkjpY7MS.cjs → RunIntentService-DcxXf_AM.cjs} +262 -65
- package/dist/RunIntentService-DcxXf_AM.cjs.map +1 -0
- package/dist/bootstrap/index.cjs +14 -1135
- package/dist/bootstrap/index.d.cts +7 -60
- package/dist/bootstrap/index.d.ts +4 -40
- package/dist/bootstrap/index.js +3 -1122
- package/dist/bootstrap-D67Sf2BF.js +1136 -0
- package/dist/bootstrap-D67Sf2BF.js.map +1 -0
- package/dist/bootstrap-DoQHAEQJ.cjs +1203 -0
- package/dist/bootstrap-DoQHAEQJ.cjs.map +1 -0
- package/dist/{index-BIewO9-9.d.ts → index-BHmrZIHp.d.ts} +32 -260
- package/dist/index.cjs +98 -223
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +196 -6
- package/dist/index.d.ts +3 -3
- package/dist/index.js +92 -218
- package/dist/index.js.map +1 -1
- package/dist/testing.cjs +329 -3
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +181 -4
- package/dist/testing.d.ts +181 -3
- package/dist/testing.js +319 -2
- package/dist/testing.js.map +1 -1
- package/dist/workflowActivationPolicy-B8HzTk3o.js +201 -0
- package/dist/workflowActivationPolicy-B8HzTk3o.js.map +1 -0
- package/dist/workflowActivationPolicy-BzyzXLa_.cjs +231 -0
- package/dist/workflowActivationPolicy-BzyzXLa_.cjs.map +1 -0
- package/package.json +1 -1
- package/src/ai/AgentConnectionNodeCollector.ts +99 -0
- package/src/ai/AgentToolFactory.ts +38 -2
- package/src/ai/AiHost.ts +1 -1
- package/src/browser.ts +11 -0
- package/src/contracts/executionPersistenceContracts.ts +186 -0
- package/src/contracts/index.ts +1 -0
- package/src/contracts/runFinishedAtFactory.ts +5 -2
- package/src/contracts/runTypes.ts +10 -0
- package/src/contracts/runtimeTypes.ts +6 -2
- package/src/contracts/workflowTypes.ts +3 -2
- package/src/events/EventPublishingWorkflowExecutionRepository.ts +5 -0
- package/src/execution/ActivationEnqueueService.ts +8 -8
- package/src/execution/PersistedRunStateTerminalBuilder.ts +3 -0
- package/src/index.ts +6 -0
- package/src/orchestration/NodeExecutionRequestHandlerService.ts +11 -6
- package/src/orchestration/RunContinuationService.ts +94 -24
- package/src/runStorage/InMemoryWorkflowExecutionRepository.ts +14 -1
- package/src/scheduler/DefaultDrivingScheduler.ts +21 -11
- package/src/scheduler/InlineDrivingScheduler.ts +17 -21
- package/src/testing/CapturingScheduler.ts +15 -0
- package/src/testing/EngineTestKitRunIdFactory.ts +24 -0
- package/src/testing/InMemoryTriggerSetupStateRepository.ts +21 -0
- package/src/testing/PrefixedSequentialIdGenerator.ts +17 -0
- package/src/testing/RegistrarEngineTestKit.types.ts +76 -0
- package/src/testing/RegistrarEngineTestKitFactory.ts +154 -0
- package/src/testing/SubWorkflowRunnerTestNode.ts +83 -0
- package/src/testing/WorkflowTestHarnessManualTrigger.ts +39 -0
- package/src/testing/WorkflowTestKit.types.ts +9 -0
- package/src/testing/WorkflowTestKitBuilder.ts +77 -0
- package/src/testing/WorkflowTestKitNodeRegistrationContextFactory.ts +17 -0
- package/src/testing/WorkflowTestKitRunNodeWorkflowFactory.ts +26 -0
- package/src/testing.ts +19 -0
- package/src/types/index.ts +1 -0
- package/src/workflow/definition/ConnectionNodeIdFactory.ts +28 -0
- package/dist/InMemoryLiveWorkflowRepository-BTzHpQ6e.cjs +0 -151
- package/dist/InMemoryLiveWorkflowRepository-BTzHpQ6e.cjs.map +0 -1
- package/dist/InMemoryLiveWorkflowRepository-BoLNnVLg.js +0 -139
- package/dist/InMemoryLiveWorkflowRepository-BoLNnVLg.js.map +0 -1
- package/dist/RunIntentService-C1nu_YwM.js.map +0 -1
- package/dist/RunIntentService-DjbxzBBP.d.cts +0 -288
- package/dist/RunIntentService-ZkjpY7MS.cjs.map +0 -1
- package/dist/WorkflowSnapshotCodec-DSEzKyt3.d.cts +0 -22
- package/dist/bootstrap/index.cjs.map +0 -1
- package/dist/bootstrap/index.js.map +0 -1
|
@@ -183,6 +183,25 @@ var ConnectionNodeIdFactory = class {
|
|
|
183
183
|
static isToolConnectionNodeId(nodeId) {
|
|
184
184
|
return nodeId.includes(`${this.connectionSegment}tool${this.connectionSegment}`);
|
|
185
185
|
}
|
|
186
|
+
static parseLanguageModelConnectionNodeId(nodeId) {
|
|
187
|
+
if (!this.isLanguageModelConnectionNodeId(nodeId)) return;
|
|
188
|
+
const suffix = `${this.connectionSegment}llm`;
|
|
189
|
+
const parentNodeId = nodeId.slice(0, -suffix.length);
|
|
190
|
+
return parentNodeId ? { parentNodeId } : void 0;
|
|
191
|
+
}
|
|
192
|
+
static parseToolConnectionNodeId(nodeId) {
|
|
193
|
+
if (!this.isToolConnectionNodeId(nodeId)) return;
|
|
194
|
+
const marker = `${this.connectionSegment}tool${this.connectionSegment}`;
|
|
195
|
+
const idx = nodeId.lastIndexOf(marker);
|
|
196
|
+
if (idx < 0) return;
|
|
197
|
+
const parentNodeId = nodeId.slice(0, idx);
|
|
198
|
+
const normalizedToolName = nodeId.slice(idx + marker.length);
|
|
199
|
+
if (!parentNodeId || !normalizedToolName) return;
|
|
200
|
+
return {
|
|
201
|
+
parentNodeId,
|
|
202
|
+
normalizedToolName
|
|
203
|
+
};
|
|
204
|
+
}
|
|
186
205
|
/** True when `nodeId` is a connection-owned child of `parentNodeId` (LLM or tool slot). */
|
|
187
206
|
static isConnectionOwnedDescendantOf(parentNodeId, nodeId) {
|
|
188
207
|
return nodeId.startsWith(`${parentNodeId}${this.connectionSegment}`);
|
|
@@ -505,7 +524,7 @@ var ActivationEnqueueService = class {
|
|
|
505
524
|
return result;
|
|
506
525
|
}
|
|
507
526
|
async enqueueActivationWithSnapshot(args) {
|
|
508
|
-
const
|
|
527
|
+
const preparedDispatch = await this.activationScheduler.prepareDispatch(args.request);
|
|
509
528
|
const inputsByPort = NodeInputsByPortFactory.fromRequest(args.request);
|
|
510
529
|
const itemsIn = args.request.kind === "multi" ? args.planner.sumItemsByPort(args.request.inputsByPort) : args.request.input.length;
|
|
511
530
|
const enqueuedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -516,8 +535,8 @@ var ActivationEnqueueService = class {
|
|
|
516
535
|
nodeId: args.request.nodeId,
|
|
517
536
|
itemsIn,
|
|
518
537
|
inputsByPort,
|
|
519
|
-
receiptId: receipt.receiptId,
|
|
520
|
-
queue: receipt.queue,
|
|
538
|
+
receiptId: preparedDispatch.receipt.receiptId,
|
|
539
|
+
queue: preparedDispatch.receipt.queue,
|
|
521
540
|
batchId: args.request.batchId,
|
|
522
541
|
enqueuedAt
|
|
523
542
|
};
|
|
@@ -551,7 +570,7 @@ var ActivationEnqueueService = class {
|
|
|
551
570
|
[args.request.nodeId]: queuedSnapshot
|
|
552
571
|
}
|
|
553
572
|
});
|
|
554
|
-
this.
|
|
573
|
+
await this.dispatchPreparedActivation(preparedDispatch);
|
|
555
574
|
return {
|
|
556
575
|
result: {
|
|
557
576
|
runId: args.runId,
|
|
@@ -563,8 +582,8 @@ var ActivationEnqueueService = class {
|
|
|
563
582
|
queuedSnapshot
|
|
564
583
|
};
|
|
565
584
|
}
|
|
566
|
-
|
|
567
|
-
|
|
585
|
+
async dispatchPreparedActivation(preparedDispatch) {
|
|
586
|
+
await preparedDispatch.dispatch();
|
|
568
587
|
}
|
|
569
588
|
};
|
|
570
589
|
|
|
@@ -985,6 +1004,127 @@ var PersistedWorkflowTokenRegistry = class {
|
|
|
985
1004
|
}
|
|
986
1005
|
};
|
|
987
1006
|
|
|
1007
|
+
//#endregion
|
|
1008
|
+
//#region src/workflowSnapshots/WorkflowSnapshotCodec.ts
|
|
1009
|
+
var WorkflowSnapshotCodec = class {
|
|
1010
|
+
constructor(tokenRegistry) {
|
|
1011
|
+
this.tokenRegistry = tokenRegistry;
|
|
1012
|
+
}
|
|
1013
|
+
create(workflow) {
|
|
1014
|
+
return {
|
|
1015
|
+
id: workflow.id,
|
|
1016
|
+
name: workflow.name,
|
|
1017
|
+
workflowErrorHandlerConfigured: workflow.workflowErrorHandler !== void 0,
|
|
1018
|
+
...workflow.connections !== void 0 && workflow.connections.length > 0 ? { connections: workflow.connections } : {},
|
|
1019
|
+
nodes: workflow.nodes.map((node$1) => ({
|
|
1020
|
+
id: node$1.id,
|
|
1021
|
+
kind: node$1.kind,
|
|
1022
|
+
name: node$1.name,
|
|
1023
|
+
nodeTokenId: this.resolveTokenId(node$1.type),
|
|
1024
|
+
configTokenId: this.resolveTokenId(node$1.config.type),
|
|
1025
|
+
tokenName: this.resolveTokenName(node$1.type),
|
|
1026
|
+
configTokenName: this.resolveTokenName(node$1.config.type),
|
|
1027
|
+
config: this.serializeConfig(node$1.config)
|
|
1028
|
+
})),
|
|
1029
|
+
edges: workflow.edges.map((edge) => ({
|
|
1030
|
+
from: {
|
|
1031
|
+
nodeId: edge.from.nodeId,
|
|
1032
|
+
output: edge.from.output
|
|
1033
|
+
},
|
|
1034
|
+
to: {
|
|
1035
|
+
nodeId: edge.to.nodeId,
|
|
1036
|
+
input: edge.to.input
|
|
1037
|
+
}
|
|
1038
|
+
}))
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
1041
|
+
hydrate(snapshotNode, liveConfig) {
|
|
1042
|
+
const hydrated = this.mergeValue(liveConfig, snapshotNode.config);
|
|
1043
|
+
const configToken = this.tokenRegistry.resolve(snapshotNode.configTokenId);
|
|
1044
|
+
Object.assign(hydrated, {
|
|
1045
|
+
type: configToken ?? liveConfig.type,
|
|
1046
|
+
kind: snapshotNode.kind
|
|
1047
|
+
});
|
|
1048
|
+
if (snapshotNode.name && !("name" in hydrated && hydrated.name)) Object.assign(hydrated, { name: snapshotNode.name });
|
|
1049
|
+
return hydrated;
|
|
1050
|
+
}
|
|
1051
|
+
serializeConfig(config) {
|
|
1052
|
+
try {
|
|
1053
|
+
const cloned = JSON.parse(JSON.stringify(config));
|
|
1054
|
+
this.injectTokenIds(cloned, config);
|
|
1055
|
+
return cloned;
|
|
1056
|
+
} catch {
|
|
1057
|
+
const fallback = {
|
|
1058
|
+
kind: config.kind,
|
|
1059
|
+
name: config.name,
|
|
1060
|
+
id: config.id,
|
|
1061
|
+
icon: config.icon,
|
|
1062
|
+
execution: config.execution
|
|
1063
|
+
};
|
|
1064
|
+
this.injectTokenIds(fallback, config);
|
|
1065
|
+
return fallback;
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
injectTokenIds(target, source) {
|
|
1069
|
+
const type = this.asTypeToken(source.type);
|
|
1070
|
+
if (type) target.tokenId = this.tokenRegistry.getTokenId(type) ?? this.resolveTokenName(type) ?? "unknown";
|
|
1071
|
+
for (const [key, value] of Object.entries(source)) {
|
|
1072
|
+
if (key === "type" || value == null) continue;
|
|
1073
|
+
if (Array.isArray(value)) {
|
|
1074
|
+
const targetArray = target[key];
|
|
1075
|
+
if (Array.isArray(targetArray)) value.forEach((item, index) => {
|
|
1076
|
+
if (item && typeof item === "object" && targetArray[index] && typeof targetArray[index] === "object") this.injectTokenIds(targetArray[index], item);
|
|
1077
|
+
});
|
|
1078
|
+
continue;
|
|
1079
|
+
}
|
|
1080
|
+
if (typeof value === "object") {
|
|
1081
|
+
const targetValue = target[key];
|
|
1082
|
+
if (targetValue && typeof targetValue === "object") this.injectTokenIds(targetValue, value);
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
mergeValue(liveValue, snapshotValue) {
|
|
1087
|
+
const liveRecord = this.asRecord(liveValue);
|
|
1088
|
+
const snapshotRecord = this.asRecord(snapshotValue);
|
|
1089
|
+
const hydrated = Object.create(liveValue && typeof liveValue === "object" ? Object.getPrototypeOf(liveValue) ?? Object.prototype : Object.prototype);
|
|
1090
|
+
for (const [key, value] of Object.entries(snapshotRecord)) hydrated[key] = this.mergeNestedValue(liveRecord[key], value);
|
|
1091
|
+
this.restoreNonSerializableProperties(liveRecord, hydrated);
|
|
1092
|
+
this.restoreTypeProperty(hydrated);
|
|
1093
|
+
return hydrated;
|
|
1094
|
+
}
|
|
1095
|
+
mergeNestedValue(liveValue, snapshotValue) {
|
|
1096
|
+
if (Array.isArray(snapshotValue)) {
|
|
1097
|
+
const liveArray = Array.isArray(liveValue) ? liveValue : [];
|
|
1098
|
+
return snapshotValue.map((entry, index) => this.mergeNestedValue(liveArray[index], entry));
|
|
1099
|
+
}
|
|
1100
|
+
if (snapshotValue && typeof snapshotValue === "object") return this.mergeValue(liveValue, snapshotValue);
|
|
1101
|
+
return snapshotValue;
|
|
1102
|
+
}
|
|
1103
|
+
restoreNonSerializableProperties(liveRecord, hydrated) {
|
|
1104
|
+
for (const [key, value] of Object.entries(liveRecord)) if (typeof value === "function" || typeof value === "symbol") hydrated[key] = value;
|
|
1105
|
+
}
|
|
1106
|
+
restoreTypeProperty(record) {
|
|
1107
|
+
const tokenId = typeof record.tokenId === "string" ? record.tokenId : void 0;
|
|
1108
|
+
if (!tokenId) return;
|
|
1109
|
+
const type = this.tokenRegistry.resolve(tokenId);
|
|
1110
|
+
if (type) record.type = type;
|
|
1111
|
+
}
|
|
1112
|
+
resolveTokenId(token) {
|
|
1113
|
+
return this.tokenRegistry.getTokenId(token) ?? this.resolveTokenName(token) ?? "unknown";
|
|
1114
|
+
}
|
|
1115
|
+
resolveTokenName(token) {
|
|
1116
|
+
if (typeof token === "function" && token.name) return token.name;
|
|
1117
|
+
if (typeof token === "string") return token;
|
|
1118
|
+
}
|
|
1119
|
+
asTypeToken(value) {
|
|
1120
|
+
if (typeof value === "function" || typeof value === "string" || typeof value === "symbol") return value;
|
|
1121
|
+
}
|
|
1122
|
+
asRecord(value) {
|
|
1123
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
1124
|
+
return { ...value };
|
|
1125
|
+
}
|
|
1126
|
+
};
|
|
1127
|
+
|
|
988
1128
|
//#endregion
|
|
989
1129
|
//#region src/workflowSnapshots/WorkflowSnapshotResolver.ts
|
|
990
1130
|
var WorkflowSnapshotResolver = class {
|
|
@@ -1234,7 +1374,8 @@ var PersistedRunStateTerminalBuilder = class {
|
|
|
1234
1374
|
pending: void 0,
|
|
1235
1375
|
queue: args.queue,
|
|
1236
1376
|
outputsByNode: args.outputsByNode,
|
|
1237
|
-
nodeSnapshotsByNodeId: args.nodeSnapshotsByNodeId
|
|
1377
|
+
nodeSnapshotsByNodeId: args.nodeSnapshotsByNodeId,
|
|
1378
|
+
finishedAt: args.finishedAtIso ?? args.state.finishedAt
|
|
1238
1379
|
};
|
|
1239
1380
|
}
|
|
1240
1381
|
};
|
|
@@ -1424,9 +1565,10 @@ var RunContinuationService = class {
|
|
|
1424
1565
|
this.executionLimitsPolicy = executionLimitsPolicy;
|
|
1425
1566
|
}
|
|
1426
1567
|
async markNodeRunning(args) {
|
|
1427
|
-
const state = await this.workflowExecutionRepository.load(args.runId);
|
|
1428
|
-
|
|
1429
|
-
if (state
|
|
1568
|
+
const [state, schedulingState] = await Promise.all([this.workflowExecutionRepository.load(args.runId), this.workflowExecutionRepository.loadSchedulingState(args.runId)]);
|
|
1569
|
+
const pendingExecution = schedulingState?.pending;
|
|
1570
|
+
if (!state || !pendingExecution) return;
|
|
1571
|
+
if (pendingExecution.activationId !== args.activationId || pendingExecution.nodeId !== args.nodeId) return;
|
|
1430
1572
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1431
1573
|
const previous = state.nodeSnapshotsByNodeId?.[args.nodeId];
|
|
1432
1574
|
const snapshot = NodeExecutionSnapshotFactory.running({
|
|
@@ -1449,11 +1591,11 @@ var RunContinuationService = class {
|
|
|
1449
1591
|
await this.nodeEventPublisher.publish("nodeStarted", snapshot);
|
|
1450
1592
|
}
|
|
1451
1593
|
async resumeFromNodeResult(args) {
|
|
1452
|
-
const state = await this.workflowExecutionRepository.load(args.runId);
|
|
1594
|
+
const [state, schedulingState] = await Promise.all([this.workflowExecutionRepository.load(args.runId), this.workflowExecutionRepository.loadSchedulingState(args.runId)]);
|
|
1453
1595
|
if (!state) throw new Error(`Unknown runId: ${args.runId}`);
|
|
1454
|
-
|
|
1455
|
-
if (
|
|
1456
|
-
if (
|
|
1596
|
+
const pendingExecution = this.requirePendingExecution(args.runId, args.activationId, args.nodeId, state, schedulingState);
|
|
1597
|
+
if (pendingExecution.activationId !== args.activationId) throw new Error(`activationId mismatch for run ${args.runId}`);
|
|
1598
|
+
if (pendingExecution.nodeId !== args.nodeId) throw new Error(`nodeId mismatch for run ${args.runId}`);
|
|
1457
1599
|
const wf = this.resolvePersistedWorkflow(state);
|
|
1458
1600
|
if (!wf) throw new Error(`Unknown workflowId: ${state.workflowId}`);
|
|
1459
1601
|
const { topology, planner } = this.planningFactory.create(wf);
|
|
@@ -1481,7 +1623,7 @@ var RunContinuationService = class {
|
|
|
1481
1623
|
activationId: args.activationId,
|
|
1482
1624
|
parent: state.parent,
|
|
1483
1625
|
finishedAt: completedAt,
|
|
1484
|
-
inputsByPort:
|
|
1626
|
+
inputsByPort: pendingExecution.inputsByPort,
|
|
1485
1627
|
outputs: args.outputs
|
|
1486
1628
|
});
|
|
1487
1629
|
const completedActivations = (state.engineCounters?.completedNodeActivations ?? 0) + 1;
|
|
@@ -1497,7 +1639,8 @@ var RunContinuationService = class {
|
|
|
1497
1639
|
nodeSnapshotsByNodeId: {
|
|
1498
1640
|
...state.nodeSnapshotsByNodeId ?? {},
|
|
1499
1641
|
[args.nodeId]: completedSnapshot
|
|
1500
|
-
}
|
|
1642
|
+
},
|
|
1643
|
+
finishedAtIso: completedAt
|
|
1501
1644
|
});
|
|
1502
1645
|
await this.workflowExecutionRepository.save(completedState);
|
|
1503
1646
|
await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
|
|
@@ -1517,8 +1660,8 @@ var RunContinuationService = class {
|
|
|
1517
1660
|
this.waiters.resolveRunCompletion(result$1);
|
|
1518
1661
|
return result$1;
|
|
1519
1662
|
}
|
|
1520
|
-
const batchId =
|
|
1521
|
-
const queue = (
|
|
1663
|
+
const batchId = pendingExecution.batchId ?? "batch_1";
|
|
1664
|
+
const queue = (schedulingState?.queue ?? []).map((q) => ({
|
|
1522
1665
|
...q,
|
|
1523
1666
|
batchId: q.batchId ?? batchId
|
|
1524
1667
|
}));
|
|
@@ -1563,7 +1706,8 @@ var RunContinuationService = class {
|
|
|
1563
1706
|
status: "completed",
|
|
1564
1707
|
queue: [],
|
|
1565
1708
|
outputsByNode: data.dump(),
|
|
1566
|
-
nodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId
|
|
1709
|
+
nodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId,
|
|
1710
|
+
finishedAtIso: completedAt
|
|
1567
1711
|
});
|
|
1568
1712
|
await this.workflowExecutionRepository.save(completedState);
|
|
1569
1713
|
await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
|
|
@@ -1591,7 +1735,8 @@ var RunContinuationService = class {
|
|
|
1591
1735
|
status: "failed",
|
|
1592
1736
|
queue: queue.map((q) => ({ ...q })),
|
|
1593
1737
|
outputsByNode: data.dump(),
|
|
1594
|
-
nodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId
|
|
1738
|
+
nodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId,
|
|
1739
|
+
finishedAtIso: completedAt
|
|
1595
1740
|
});
|
|
1596
1741
|
await this.workflowExecutionRepository.save(failedState);
|
|
1597
1742
|
await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
|
|
@@ -1645,17 +1790,19 @@ var RunContinuationService = class {
|
|
|
1645
1790
|
return result;
|
|
1646
1791
|
}
|
|
1647
1792
|
async resumeFromNodeError(args) {
|
|
1648
|
-
const state = await this.workflowExecutionRepository.load(args.runId);
|
|
1793
|
+
const [state, schedulingState] = await Promise.all([this.workflowExecutionRepository.load(args.runId), this.workflowExecutionRepository.loadSchedulingState(args.runId)]);
|
|
1649
1794
|
if (!state) throw new Error(`Unknown runId: ${args.runId}`);
|
|
1650
|
-
|
|
1651
|
-
if (
|
|
1652
|
-
if (
|
|
1795
|
+
const pendingExecution = this.requirePendingExecution(args.runId, args.activationId, args.nodeId, state, schedulingState);
|
|
1796
|
+
if (pendingExecution.activationId !== args.activationId) throw new Error(`activationId mismatch for run ${args.runId}`);
|
|
1797
|
+
if (pendingExecution.nodeId !== args.nodeId) throw new Error(`nodeId mismatch for run ${args.runId}`);
|
|
1653
1798
|
const wf = this.resolvePersistedWorkflow(state);
|
|
1654
1799
|
if (!wf) throw new Error(`Unknown workflowId: ${state.workflowId}`);
|
|
1655
1800
|
const failedDefinition = WorkflowTopology.fromWorkflow(wf).defsById.get(args.nodeId);
|
|
1656
1801
|
const webhookControlSignal = state.executionOptions?.webhook && failedDefinition?.kind === "trigger" ? this.asWebhookControlSignal(args.error) : void 0;
|
|
1657
1802
|
if (webhookControlSignal) return await this.resumeFromWebhookControl({
|
|
1658
1803
|
state,
|
|
1804
|
+
schedulingState,
|
|
1805
|
+
pendingExecution,
|
|
1659
1806
|
workflow: wf,
|
|
1660
1807
|
args,
|
|
1661
1808
|
signal: webhookControlSignal
|
|
@@ -1663,8 +1810,8 @@ var RunContinuationService = class {
|
|
|
1663
1810
|
if (failedDefinition && failedDefinition.kind === "node") {
|
|
1664
1811
|
const nodeHandler = this.policyErrorServices.resolveNodeErrorHandler(failedDefinition.config.nodeErrorHandler);
|
|
1665
1812
|
if (nodeHandler) try {
|
|
1666
|
-
const ctx = this.buildNodeExecutionContextForPending(state, wf, failedDefinition, args.nodeId);
|
|
1667
|
-
const inputsByPort =
|
|
1813
|
+
const ctx = this.buildNodeExecutionContextForPending(state, pendingExecution, wf, failedDefinition, args.nodeId);
|
|
1814
|
+
const inputsByPort = pendingExecution.inputsByPort;
|
|
1668
1815
|
const portKeys = Object.keys(inputsByPort);
|
|
1669
1816
|
const kind = portKeys.length === 1 && portKeys[0] === "in" ? "single" : "multi";
|
|
1670
1817
|
const items = inputsByPort.in ?? [];
|
|
@@ -1693,19 +1840,20 @@ var RunContinuationService = class {
|
|
|
1693
1840
|
activationId: args.activationId,
|
|
1694
1841
|
parent: state.parent,
|
|
1695
1842
|
finishedAt,
|
|
1696
|
-
inputsByPort:
|
|
1843
|
+
inputsByPort: pendingExecution.inputsByPort,
|
|
1697
1844
|
error: args.error
|
|
1698
1845
|
});
|
|
1699
1846
|
const failedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
|
|
1700
1847
|
state,
|
|
1701
1848
|
engineCounters: state.engineCounters ?? { completedNodeActivations: 0 },
|
|
1702
1849
|
status: "failed",
|
|
1703
|
-
queue: (
|
|
1850
|
+
queue: (schedulingState?.queue ?? []).map((q) => ({ ...q })),
|
|
1704
1851
|
outputsByNode: state.outputsByNode,
|
|
1705
1852
|
nodeSnapshotsByNodeId: {
|
|
1706
1853
|
...state.nodeSnapshotsByNodeId ?? {},
|
|
1707
1854
|
[args.nodeId]: failedSnapshot
|
|
1708
|
-
}
|
|
1855
|
+
},
|
|
1856
|
+
finishedAtIso: finishedAt
|
|
1709
1857
|
});
|
|
1710
1858
|
await this.workflowExecutionRepository.save(failedState);
|
|
1711
1859
|
await this.nodeEventPublisher.publish("nodeFailed", failedSnapshot);
|
|
@@ -1782,7 +1930,7 @@ var RunContinuationService = class {
|
|
|
1782
1930
|
activationId: args.args.activationId,
|
|
1783
1931
|
parent: args.state.parent,
|
|
1784
1932
|
finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1785
|
-
inputsByPort: args.
|
|
1933
|
+
inputsByPort: args.pendingExecution.inputsByPort,
|
|
1786
1934
|
outputs: triggerOutputs
|
|
1787
1935
|
});
|
|
1788
1936
|
const completedActivations = (args.state.engineCounters?.completedNodeActivations ?? 0) + 1;
|
|
@@ -1798,7 +1946,8 @@ var RunContinuationService = class {
|
|
|
1798
1946
|
nodeSnapshotsByNodeId: {
|
|
1799
1947
|
...args.state.nodeSnapshotsByNodeId ?? {},
|
|
1800
1948
|
[args.args.nodeId]: completedSnapshot
|
|
1801
|
-
}
|
|
1949
|
+
},
|
|
1950
|
+
finishedAtIso: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt
|
|
1802
1951
|
});
|
|
1803
1952
|
await this.workflowExecutionRepository.save(completedState);
|
|
1804
1953
|
await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
|
|
@@ -1835,7 +1984,8 @@ var RunContinuationService = class {
|
|
|
1835
1984
|
nodeSnapshotsByNodeId: {
|
|
1836
1985
|
...args.state.nodeSnapshotsByNodeId ?? {},
|
|
1837
1986
|
[args.args.nodeId]: completedSnapshot
|
|
1838
|
-
}
|
|
1987
|
+
},
|
|
1988
|
+
finishedAtIso: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt
|
|
1839
1989
|
});
|
|
1840
1990
|
await this.workflowExecutionRepository.save(completedState);
|
|
1841
1991
|
await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
|
|
@@ -1862,8 +2012,8 @@ var RunContinuationService = class {
|
|
|
1862
2012
|
this.waiters.resolveRunCompletion(result$1);
|
|
1863
2013
|
return result$1;
|
|
1864
2014
|
}
|
|
1865
|
-
const batchId = args.
|
|
1866
|
-
const queue = (args.
|
|
2015
|
+
const batchId = args.pendingExecution.batchId ?? "batch_1";
|
|
2016
|
+
const queue = (args.schedulingState?.queue ?? []).map((entry) => ({
|
|
1867
2017
|
...entry,
|
|
1868
2018
|
batchId: entry.batchId ?? batchId
|
|
1869
2019
|
}));
|
|
@@ -1885,7 +2035,8 @@ var RunContinuationService = class {
|
|
|
1885
2035
|
nodeSnapshotsByNodeId: {
|
|
1886
2036
|
...args.state.nodeSnapshotsByNodeId ?? {},
|
|
1887
2037
|
[args.args.nodeId]: completedSnapshot
|
|
1888
|
-
}
|
|
2038
|
+
},
|
|
2039
|
+
finishedAtIso: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt
|
|
1889
2040
|
});
|
|
1890
2041
|
await this.workflowExecutionRepository.save(completedState);
|
|
1891
2042
|
await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
|
|
@@ -1923,7 +2074,8 @@ var RunContinuationService = class {
|
|
|
1923
2074
|
nodeSnapshotsByNodeId: {
|
|
1924
2075
|
...args.state.nodeSnapshotsByNodeId ?? {},
|
|
1925
2076
|
[args.args.nodeId]: completedSnapshot
|
|
1926
|
-
}
|
|
2077
|
+
},
|
|
2078
|
+
finishedAtIso: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt
|
|
1927
2079
|
});
|
|
1928
2080
|
await this.workflowExecutionRepository.save(failedState);
|
|
1929
2081
|
await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
|
|
@@ -2018,7 +2170,7 @@ var RunContinuationService = class {
|
|
|
2018
2170
|
workflowSnapshot: state.workflowSnapshot
|
|
2019
2171
|
});
|
|
2020
2172
|
}
|
|
2021
|
-
buildNodeExecutionContextForPending(state, wf, def, nodeId) {
|
|
2173
|
+
buildNodeExecutionContextForPending(state, pendingExecution, wf, def, nodeId) {
|
|
2022
2174
|
const data = this.runDataFactory.create(state.outputsByNode);
|
|
2023
2175
|
const limits = this.resolveEngineLimitsFromState(state);
|
|
2024
2176
|
const base = this.runExecutionContextFactory.create({
|
|
@@ -2032,7 +2184,7 @@ var RunContinuationService = class {
|
|
|
2032
2184
|
data,
|
|
2033
2185
|
nodeState: this.nodeStatePublisherFactory.create(state.runId, state.workflowId, state.parent)
|
|
2034
2186
|
});
|
|
2035
|
-
const activationId =
|
|
2187
|
+
const activationId = pendingExecution.activationId;
|
|
2036
2188
|
return {
|
|
2037
2189
|
...base,
|
|
2038
2190
|
data,
|
|
@@ -2046,6 +2198,14 @@ var RunContinuationService = class {
|
|
|
2046
2198
|
getCredential: this.credentialResolverFactory.create(wf.id, nodeId, def.config)
|
|
2047
2199
|
};
|
|
2048
2200
|
}
|
|
2201
|
+
requirePendingExecution(runId, activationId, nodeId, state, schedulingState) {
|
|
2202
|
+
if (state.status !== "pending") throw new Error(`Run ${runId} is not pending`);
|
|
2203
|
+
const pendingExecution = schedulingState?.pending;
|
|
2204
|
+
if (!pendingExecution) throw new Error(`Run ${runId} is not pending`);
|
|
2205
|
+
if (pendingExecution.activationId !== activationId) throw new Error(`activationId mismatch for run ${runId}`);
|
|
2206
|
+
if (pendingExecution.nodeId !== nodeId) throw new Error(`nodeId mismatch for run ${runId}`);
|
|
2207
|
+
return pendingExecution;
|
|
2208
|
+
}
|
|
2049
2209
|
resolveEngineLimitsFromState(state) {
|
|
2050
2210
|
const fb = this.executionLimitsPolicy.createRootExecutionOptions();
|
|
2051
2211
|
return {
|
|
@@ -2702,7 +2862,7 @@ var DefaultDrivingScheduler = class {
|
|
|
2702
2862
|
setContinuation(continuation) {
|
|
2703
2863
|
this.inline.setContinuation(continuation);
|
|
2704
2864
|
}
|
|
2705
|
-
async
|
|
2865
|
+
async prepareDispatch(request) {
|
|
2706
2866
|
const selection = await this.selectScheduler(request);
|
|
2707
2867
|
if (selection.mode === "worker") {
|
|
2708
2868
|
if (request.kind === "multi") throw new Error(`Multi-input node ${request.nodeId} cannot be scheduled to worker (insert local placement)`);
|
|
@@ -2717,15 +2877,17 @@ var DefaultDrivingScheduler = class {
|
|
|
2717
2877
|
executionOptions: request.executionOptions
|
|
2718
2878
|
};
|
|
2719
2879
|
return {
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2880
|
+
receipt: {
|
|
2881
|
+
receiptId: request.activationId,
|
|
2882
|
+
mode: "worker",
|
|
2883
|
+
queue: selection.queue
|
|
2884
|
+
},
|
|
2885
|
+
dispatch: async () => {
|
|
2886
|
+
await this.workerScheduler.enqueue(workerRequest);
|
|
2887
|
+
}
|
|
2723
2888
|
};
|
|
2724
2889
|
}
|
|
2725
|
-
return await this.
|
|
2726
|
-
}
|
|
2727
|
-
notifyPendingStatePersisted(runId) {
|
|
2728
|
-
this.inline.notifyPendingStatePersisted(runId);
|
|
2890
|
+
return await this.prepareInlineDispatch(request);
|
|
2729
2891
|
}
|
|
2730
2892
|
/**
|
|
2731
2893
|
* Scheduler precedence is explicit:
|
|
@@ -2757,10 +2919,16 @@ var DefaultDrivingScheduler = class {
|
|
|
2757
2919
|
hasNodeSchedulingPreference(request) {
|
|
2758
2920
|
return request.ctx.config.execution?.hint !== void 0 || request.ctx.config.execution?.queue !== void 0;
|
|
2759
2921
|
}
|
|
2760
|
-
async
|
|
2922
|
+
async prepareInlineDispatch(request) {
|
|
2923
|
+
const prepared = await this.inline.prepareDispatch(request);
|
|
2761
2924
|
return {
|
|
2762
|
-
|
|
2763
|
-
|
|
2925
|
+
receipt: {
|
|
2926
|
+
...prepared.receipt,
|
|
2927
|
+
mode: "local"
|
|
2928
|
+
},
|
|
2929
|
+
dispatch: async () => {
|
|
2930
|
+
await prepared.dispatch();
|
|
2931
|
+
}
|
|
2764
2932
|
};
|
|
2765
2933
|
}
|
|
2766
2934
|
};
|
|
@@ -2784,29 +2952,29 @@ var InlineDrivingScheduler = class {
|
|
|
2784
2952
|
drainingRuns = /* @__PURE__ */ new Set();
|
|
2785
2953
|
queuesByRunId = /* @__PURE__ */ new Map();
|
|
2786
2954
|
scheduledRuns = /* @__PURE__ */ new Set();
|
|
2787
|
-
seq = 0;
|
|
2788
2955
|
constructor(nodeExecutor) {
|
|
2789
2956
|
this.nodeExecutor = nodeExecutor;
|
|
2790
2957
|
}
|
|
2791
2958
|
setContinuation(continuation) {
|
|
2792
2959
|
this.continuation = continuation;
|
|
2793
2960
|
}
|
|
2794
|
-
async
|
|
2961
|
+
async prepareDispatch(request) {
|
|
2795
2962
|
const receipt = {
|
|
2796
|
-
receiptId:
|
|
2963
|
+
receiptId: request.activationId,
|
|
2797
2964
|
mode: "local"
|
|
2798
2965
|
};
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2966
|
+
return {
|
|
2967
|
+
receipt,
|
|
2968
|
+
dispatch: async () => {
|
|
2969
|
+
const queue = this.queuesByRunId.get(request.runId) ?? [];
|
|
2970
|
+
queue.push({
|
|
2971
|
+
request,
|
|
2972
|
+
receipt
|
|
2973
|
+
});
|
|
2974
|
+
this.queuesByRunId.set(request.runId, queue);
|
|
2975
|
+
this.scheduleDrain(request.runId);
|
|
2976
|
+
}
|
|
2977
|
+
};
|
|
2810
2978
|
}
|
|
2811
2979
|
async drainRun(runId) {
|
|
2812
2980
|
if (this.drainingRuns.has(runId)) return;
|
|
@@ -3072,9 +3240,10 @@ var InMemoryRunDataFactory = class {
|
|
|
3072
3240
|
|
|
3073
3241
|
//#endregion
|
|
3074
3242
|
//#region src/contracts/runFinishedAtFactory.ts
|
|
3075
|
-
/** Derives workflow end time from node snapshots for run listings. */
|
|
3243
|
+
/** Derives workflow end time from persisted run root or node snapshots for run listings. */
|
|
3076
3244
|
var RunFinishedAtFactory = class {
|
|
3077
3245
|
static resolveIso(state) {
|
|
3246
|
+
if (state.finishedAt && state.status !== "running" && state.status !== "pending") return state.finishedAt;
|
|
3078
3247
|
if (state.status === "running" || state.status === "pending") return;
|
|
3079
3248
|
let max;
|
|
3080
3249
|
for (const snap of Object.values(state.nodeSnapshotsByNodeId)) if (snap?.finishedAt && (!max || snap.finishedAt > max)) max = snap.finishedAt;
|
|
@@ -3082,6 +3251,22 @@ var RunFinishedAtFactory = class {
|
|
|
3082
3251
|
}
|
|
3083
3252
|
};
|
|
3084
3253
|
|
|
3254
|
+
//#endregion
|
|
3255
|
+
//#region src/runtime/InMemoryLiveWorkflowRepository.ts
|
|
3256
|
+
var InMemoryLiveWorkflowRepository = class {
|
|
3257
|
+
workflowsById = /* @__PURE__ */ new Map();
|
|
3258
|
+
setWorkflows(workflows) {
|
|
3259
|
+
this.workflowsById.clear();
|
|
3260
|
+
for (const workflow of workflows) this.workflowsById.set(workflow.id, workflow);
|
|
3261
|
+
}
|
|
3262
|
+
list() {
|
|
3263
|
+
return [...this.workflowsById.values()];
|
|
3264
|
+
}
|
|
3265
|
+
get(workflowId) {
|
|
3266
|
+
return this.workflowsById.get(workflowId);
|
|
3267
|
+
}
|
|
3268
|
+
};
|
|
3269
|
+
|
|
3085
3270
|
//#endregion
|
|
3086
3271
|
//#region src/runtime/RunIntentService.ts
|
|
3087
3272
|
var RunIntentService = class {
|
|
@@ -3288,6 +3473,12 @@ Object.defineProperty(exports, 'InMemoryBinaryStorage', {
|
|
|
3288
3473
|
return InMemoryBinaryStorage;
|
|
3289
3474
|
}
|
|
3290
3475
|
});
|
|
3476
|
+
Object.defineProperty(exports, 'InMemoryLiveWorkflowRepository', {
|
|
3477
|
+
enumerable: true,
|
|
3478
|
+
get: function () {
|
|
3479
|
+
return InMemoryLiveWorkflowRepository;
|
|
3480
|
+
}
|
|
3481
|
+
});
|
|
3291
3482
|
Object.defineProperty(exports, 'InMemoryRunDataFactory', {
|
|
3292
3483
|
enumerable: true,
|
|
3293
3484
|
get: function () {
|
|
@@ -3474,6 +3665,12 @@ Object.defineProperty(exports, 'WorkflowRunExecutionContextFactory', {
|
|
|
3474
3665
|
return WorkflowRunExecutionContextFactory;
|
|
3475
3666
|
}
|
|
3476
3667
|
});
|
|
3668
|
+
Object.defineProperty(exports, 'WorkflowSnapshotCodec', {
|
|
3669
|
+
enumerable: true,
|
|
3670
|
+
get: function () {
|
|
3671
|
+
return WorkflowSnapshotCodec;
|
|
3672
|
+
}
|
|
3673
|
+
});
|
|
3477
3674
|
Object.defineProperty(exports, 'WorkflowSnapshotResolver', {
|
|
3478
3675
|
enumerable: true,
|
|
3479
3676
|
get: function () {
|
|
@@ -3516,4 +3713,4 @@ Object.defineProperty(exports, 'tool', {
|
|
|
3516
3713
|
return tool;
|
|
3517
3714
|
}
|
|
3518
3715
|
});
|
|
3519
|
-
//# sourceMappingURL=RunIntentService-
|
|
3716
|
+
//# sourceMappingURL=RunIntentService-DcxXf_AM.cjs.map
|