@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
|
-
import { container, delay, inject, injectAll, injectable, instanceCachingFactory, instancePerContainerCachingFactory, predicateAwareClassFactory, registry, singleton } from "tsyringe";
|
|
2
|
+
import { container as container$1, delay, inject, injectAll, injectable, instanceCachingFactory, instancePerContainerCachingFactory, predicateAwareClassFactory, registry, singleton } from "tsyringe";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import { ReadableStream } from "node:stream/web";
|
|
5
5
|
|
|
@@ -157,6 +157,25 @@ var ConnectionNodeIdFactory = class {
|
|
|
157
157
|
static isToolConnectionNodeId(nodeId) {
|
|
158
158
|
return nodeId.includes(`${this.connectionSegment}tool${this.connectionSegment}`);
|
|
159
159
|
}
|
|
160
|
+
static parseLanguageModelConnectionNodeId(nodeId) {
|
|
161
|
+
if (!this.isLanguageModelConnectionNodeId(nodeId)) return;
|
|
162
|
+
const suffix = `${this.connectionSegment}llm`;
|
|
163
|
+
const parentNodeId = nodeId.slice(0, -suffix.length);
|
|
164
|
+
return parentNodeId ? { parentNodeId } : void 0;
|
|
165
|
+
}
|
|
166
|
+
static parseToolConnectionNodeId(nodeId) {
|
|
167
|
+
if (!this.isToolConnectionNodeId(nodeId)) return;
|
|
168
|
+
const marker = `${this.connectionSegment}tool${this.connectionSegment}`;
|
|
169
|
+
const idx = nodeId.lastIndexOf(marker);
|
|
170
|
+
if (idx < 0) return;
|
|
171
|
+
const parentNodeId = nodeId.slice(0, idx);
|
|
172
|
+
const normalizedToolName = nodeId.slice(idx + marker.length);
|
|
173
|
+
if (!parentNodeId || !normalizedToolName) return;
|
|
174
|
+
return {
|
|
175
|
+
parentNodeId,
|
|
176
|
+
normalizedToolName
|
|
177
|
+
};
|
|
178
|
+
}
|
|
160
179
|
/** True when `nodeId` is a connection-owned child of `parentNodeId` (LLM or tool slot). */
|
|
161
180
|
static isConnectionOwnedDescendantOf(parentNodeId, nodeId) {
|
|
162
181
|
return nodeId.startsWith(`${parentNodeId}${this.connectionSegment}`);
|
|
@@ -479,7 +498,7 @@ var ActivationEnqueueService = class {
|
|
|
479
498
|
return result;
|
|
480
499
|
}
|
|
481
500
|
async enqueueActivationWithSnapshot(args) {
|
|
482
|
-
const
|
|
501
|
+
const preparedDispatch = await this.activationScheduler.prepareDispatch(args.request);
|
|
483
502
|
const inputsByPort = NodeInputsByPortFactory.fromRequest(args.request);
|
|
484
503
|
const itemsIn = args.request.kind === "multi" ? args.planner.sumItemsByPort(args.request.inputsByPort) : args.request.input.length;
|
|
485
504
|
const enqueuedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -490,8 +509,8 @@ var ActivationEnqueueService = class {
|
|
|
490
509
|
nodeId: args.request.nodeId,
|
|
491
510
|
itemsIn,
|
|
492
511
|
inputsByPort,
|
|
493
|
-
receiptId: receipt.receiptId,
|
|
494
|
-
queue: receipt.queue,
|
|
512
|
+
receiptId: preparedDispatch.receipt.receiptId,
|
|
513
|
+
queue: preparedDispatch.receipt.queue,
|
|
495
514
|
batchId: args.request.batchId,
|
|
496
515
|
enqueuedAt
|
|
497
516
|
};
|
|
@@ -525,7 +544,7 @@ var ActivationEnqueueService = class {
|
|
|
525
544
|
[args.request.nodeId]: queuedSnapshot
|
|
526
545
|
}
|
|
527
546
|
});
|
|
528
|
-
this.
|
|
547
|
+
await this.dispatchPreparedActivation(preparedDispatch);
|
|
529
548
|
return {
|
|
530
549
|
result: {
|
|
531
550
|
runId: args.runId,
|
|
@@ -537,8 +556,8 @@ var ActivationEnqueueService = class {
|
|
|
537
556
|
queuedSnapshot
|
|
538
557
|
};
|
|
539
558
|
}
|
|
540
|
-
|
|
541
|
-
|
|
559
|
+
async dispatchPreparedActivation(preparedDispatch) {
|
|
560
|
+
await preparedDispatch.dispatch();
|
|
542
561
|
}
|
|
543
562
|
};
|
|
544
563
|
|
|
@@ -959,6 +978,127 @@ var PersistedWorkflowTokenRegistry = class {
|
|
|
959
978
|
}
|
|
960
979
|
};
|
|
961
980
|
|
|
981
|
+
//#endregion
|
|
982
|
+
//#region src/workflowSnapshots/WorkflowSnapshotCodec.ts
|
|
983
|
+
var WorkflowSnapshotCodec = class {
|
|
984
|
+
constructor(tokenRegistry) {
|
|
985
|
+
this.tokenRegistry = tokenRegistry;
|
|
986
|
+
}
|
|
987
|
+
create(workflow) {
|
|
988
|
+
return {
|
|
989
|
+
id: workflow.id,
|
|
990
|
+
name: workflow.name,
|
|
991
|
+
workflowErrorHandlerConfigured: workflow.workflowErrorHandler !== void 0,
|
|
992
|
+
...workflow.connections !== void 0 && workflow.connections.length > 0 ? { connections: workflow.connections } : {},
|
|
993
|
+
nodes: workflow.nodes.map((node$1) => ({
|
|
994
|
+
id: node$1.id,
|
|
995
|
+
kind: node$1.kind,
|
|
996
|
+
name: node$1.name,
|
|
997
|
+
nodeTokenId: this.resolveTokenId(node$1.type),
|
|
998
|
+
configTokenId: this.resolveTokenId(node$1.config.type),
|
|
999
|
+
tokenName: this.resolveTokenName(node$1.type),
|
|
1000
|
+
configTokenName: this.resolveTokenName(node$1.config.type),
|
|
1001
|
+
config: this.serializeConfig(node$1.config)
|
|
1002
|
+
})),
|
|
1003
|
+
edges: workflow.edges.map((edge) => ({
|
|
1004
|
+
from: {
|
|
1005
|
+
nodeId: edge.from.nodeId,
|
|
1006
|
+
output: edge.from.output
|
|
1007
|
+
},
|
|
1008
|
+
to: {
|
|
1009
|
+
nodeId: edge.to.nodeId,
|
|
1010
|
+
input: edge.to.input
|
|
1011
|
+
}
|
|
1012
|
+
}))
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
hydrate(snapshotNode, liveConfig) {
|
|
1016
|
+
const hydrated = this.mergeValue(liveConfig, snapshotNode.config);
|
|
1017
|
+
const configToken = this.tokenRegistry.resolve(snapshotNode.configTokenId);
|
|
1018
|
+
Object.assign(hydrated, {
|
|
1019
|
+
type: configToken ?? liveConfig.type,
|
|
1020
|
+
kind: snapshotNode.kind
|
|
1021
|
+
});
|
|
1022
|
+
if (snapshotNode.name && !("name" in hydrated && hydrated.name)) Object.assign(hydrated, { name: snapshotNode.name });
|
|
1023
|
+
return hydrated;
|
|
1024
|
+
}
|
|
1025
|
+
serializeConfig(config) {
|
|
1026
|
+
try {
|
|
1027
|
+
const cloned = JSON.parse(JSON.stringify(config));
|
|
1028
|
+
this.injectTokenIds(cloned, config);
|
|
1029
|
+
return cloned;
|
|
1030
|
+
} catch {
|
|
1031
|
+
const fallback = {
|
|
1032
|
+
kind: config.kind,
|
|
1033
|
+
name: config.name,
|
|
1034
|
+
id: config.id,
|
|
1035
|
+
icon: config.icon,
|
|
1036
|
+
execution: config.execution
|
|
1037
|
+
};
|
|
1038
|
+
this.injectTokenIds(fallback, config);
|
|
1039
|
+
return fallback;
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
injectTokenIds(target, source) {
|
|
1043
|
+
const type = this.asTypeToken(source.type);
|
|
1044
|
+
if (type) target.tokenId = this.tokenRegistry.getTokenId(type) ?? this.resolveTokenName(type) ?? "unknown";
|
|
1045
|
+
for (const [key, value] of Object.entries(source)) {
|
|
1046
|
+
if (key === "type" || value == null) continue;
|
|
1047
|
+
if (Array.isArray(value)) {
|
|
1048
|
+
const targetArray = target[key];
|
|
1049
|
+
if (Array.isArray(targetArray)) value.forEach((item, index) => {
|
|
1050
|
+
if (item && typeof item === "object" && targetArray[index] && typeof targetArray[index] === "object") this.injectTokenIds(targetArray[index], item);
|
|
1051
|
+
});
|
|
1052
|
+
continue;
|
|
1053
|
+
}
|
|
1054
|
+
if (typeof value === "object") {
|
|
1055
|
+
const targetValue = target[key];
|
|
1056
|
+
if (targetValue && typeof targetValue === "object") this.injectTokenIds(targetValue, value);
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
mergeValue(liveValue, snapshotValue) {
|
|
1061
|
+
const liveRecord = this.asRecord(liveValue);
|
|
1062
|
+
const snapshotRecord = this.asRecord(snapshotValue);
|
|
1063
|
+
const hydrated = Object.create(liveValue && typeof liveValue === "object" ? Object.getPrototypeOf(liveValue) ?? Object.prototype : Object.prototype);
|
|
1064
|
+
for (const [key, value] of Object.entries(snapshotRecord)) hydrated[key] = this.mergeNestedValue(liveRecord[key], value);
|
|
1065
|
+
this.restoreNonSerializableProperties(liveRecord, hydrated);
|
|
1066
|
+
this.restoreTypeProperty(hydrated);
|
|
1067
|
+
return hydrated;
|
|
1068
|
+
}
|
|
1069
|
+
mergeNestedValue(liveValue, snapshotValue) {
|
|
1070
|
+
if (Array.isArray(snapshotValue)) {
|
|
1071
|
+
const liveArray = Array.isArray(liveValue) ? liveValue : [];
|
|
1072
|
+
return snapshotValue.map((entry, index) => this.mergeNestedValue(liveArray[index], entry));
|
|
1073
|
+
}
|
|
1074
|
+
if (snapshotValue && typeof snapshotValue === "object") return this.mergeValue(liveValue, snapshotValue);
|
|
1075
|
+
return snapshotValue;
|
|
1076
|
+
}
|
|
1077
|
+
restoreNonSerializableProperties(liveRecord, hydrated) {
|
|
1078
|
+
for (const [key, value] of Object.entries(liveRecord)) if (typeof value === "function" || typeof value === "symbol") hydrated[key] = value;
|
|
1079
|
+
}
|
|
1080
|
+
restoreTypeProperty(record) {
|
|
1081
|
+
const tokenId = typeof record.tokenId === "string" ? record.tokenId : void 0;
|
|
1082
|
+
if (!tokenId) return;
|
|
1083
|
+
const type = this.tokenRegistry.resolve(tokenId);
|
|
1084
|
+
if (type) record.type = type;
|
|
1085
|
+
}
|
|
1086
|
+
resolveTokenId(token) {
|
|
1087
|
+
return this.tokenRegistry.getTokenId(token) ?? this.resolveTokenName(token) ?? "unknown";
|
|
1088
|
+
}
|
|
1089
|
+
resolveTokenName(token) {
|
|
1090
|
+
if (typeof token === "function" && token.name) return token.name;
|
|
1091
|
+
if (typeof token === "string") return token;
|
|
1092
|
+
}
|
|
1093
|
+
asTypeToken(value) {
|
|
1094
|
+
if (typeof value === "function" || typeof value === "string" || typeof value === "symbol") return value;
|
|
1095
|
+
}
|
|
1096
|
+
asRecord(value) {
|
|
1097
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
1098
|
+
return { ...value };
|
|
1099
|
+
}
|
|
1100
|
+
};
|
|
1101
|
+
|
|
962
1102
|
//#endregion
|
|
963
1103
|
//#region src/workflowSnapshots/WorkflowSnapshotResolver.ts
|
|
964
1104
|
var WorkflowSnapshotResolver = class {
|
|
@@ -1208,7 +1348,8 @@ var PersistedRunStateTerminalBuilder = class {
|
|
|
1208
1348
|
pending: void 0,
|
|
1209
1349
|
queue: args.queue,
|
|
1210
1350
|
outputsByNode: args.outputsByNode,
|
|
1211
|
-
nodeSnapshotsByNodeId: args.nodeSnapshotsByNodeId
|
|
1351
|
+
nodeSnapshotsByNodeId: args.nodeSnapshotsByNodeId,
|
|
1352
|
+
finishedAt: args.finishedAtIso ?? args.state.finishedAt
|
|
1212
1353
|
};
|
|
1213
1354
|
}
|
|
1214
1355
|
};
|
|
@@ -1398,9 +1539,10 @@ var RunContinuationService = class {
|
|
|
1398
1539
|
this.executionLimitsPolicy = executionLimitsPolicy;
|
|
1399
1540
|
}
|
|
1400
1541
|
async markNodeRunning(args) {
|
|
1401
|
-
const state = await this.workflowExecutionRepository.load(args.runId);
|
|
1402
|
-
|
|
1403
|
-
if (state
|
|
1542
|
+
const [state, schedulingState] = await Promise.all([this.workflowExecutionRepository.load(args.runId), this.workflowExecutionRepository.loadSchedulingState(args.runId)]);
|
|
1543
|
+
const pendingExecution = schedulingState?.pending;
|
|
1544
|
+
if (!state || !pendingExecution) return;
|
|
1545
|
+
if (pendingExecution.activationId !== args.activationId || pendingExecution.nodeId !== args.nodeId) return;
|
|
1404
1546
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1405
1547
|
const previous = state.nodeSnapshotsByNodeId?.[args.nodeId];
|
|
1406
1548
|
const snapshot = NodeExecutionSnapshotFactory.running({
|
|
@@ -1423,11 +1565,11 @@ var RunContinuationService = class {
|
|
|
1423
1565
|
await this.nodeEventPublisher.publish("nodeStarted", snapshot);
|
|
1424
1566
|
}
|
|
1425
1567
|
async resumeFromNodeResult(args) {
|
|
1426
|
-
const state = await this.workflowExecutionRepository.load(args.runId);
|
|
1568
|
+
const [state, schedulingState] = await Promise.all([this.workflowExecutionRepository.load(args.runId), this.workflowExecutionRepository.loadSchedulingState(args.runId)]);
|
|
1427
1569
|
if (!state) throw new Error(`Unknown runId: ${args.runId}`);
|
|
1428
|
-
|
|
1429
|
-
if (
|
|
1430
|
-
if (
|
|
1570
|
+
const pendingExecution = this.requirePendingExecution(args.runId, args.activationId, args.nodeId, state, schedulingState);
|
|
1571
|
+
if (pendingExecution.activationId !== args.activationId) throw new Error(`activationId mismatch for run ${args.runId}`);
|
|
1572
|
+
if (pendingExecution.nodeId !== args.nodeId) throw new Error(`nodeId mismatch for run ${args.runId}`);
|
|
1431
1573
|
const wf = this.resolvePersistedWorkflow(state);
|
|
1432
1574
|
if (!wf) throw new Error(`Unknown workflowId: ${state.workflowId}`);
|
|
1433
1575
|
const { topology, planner } = this.planningFactory.create(wf);
|
|
@@ -1455,7 +1597,7 @@ var RunContinuationService = class {
|
|
|
1455
1597
|
activationId: args.activationId,
|
|
1456
1598
|
parent: state.parent,
|
|
1457
1599
|
finishedAt: completedAt,
|
|
1458
|
-
inputsByPort:
|
|
1600
|
+
inputsByPort: pendingExecution.inputsByPort,
|
|
1459
1601
|
outputs: args.outputs
|
|
1460
1602
|
});
|
|
1461
1603
|
const completedActivations = (state.engineCounters?.completedNodeActivations ?? 0) + 1;
|
|
@@ -1471,7 +1613,8 @@ var RunContinuationService = class {
|
|
|
1471
1613
|
nodeSnapshotsByNodeId: {
|
|
1472
1614
|
...state.nodeSnapshotsByNodeId ?? {},
|
|
1473
1615
|
[args.nodeId]: completedSnapshot
|
|
1474
|
-
}
|
|
1616
|
+
},
|
|
1617
|
+
finishedAtIso: completedAt
|
|
1475
1618
|
});
|
|
1476
1619
|
await this.workflowExecutionRepository.save(completedState);
|
|
1477
1620
|
await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
|
|
@@ -1491,8 +1634,8 @@ var RunContinuationService = class {
|
|
|
1491
1634
|
this.waiters.resolveRunCompletion(result$1);
|
|
1492
1635
|
return result$1;
|
|
1493
1636
|
}
|
|
1494
|
-
const batchId =
|
|
1495
|
-
const queue = (
|
|
1637
|
+
const batchId = pendingExecution.batchId ?? "batch_1";
|
|
1638
|
+
const queue = (schedulingState?.queue ?? []).map((q) => ({
|
|
1496
1639
|
...q,
|
|
1497
1640
|
batchId: q.batchId ?? batchId
|
|
1498
1641
|
}));
|
|
@@ -1537,7 +1680,8 @@ var RunContinuationService = class {
|
|
|
1537
1680
|
status: "completed",
|
|
1538
1681
|
queue: [],
|
|
1539
1682
|
outputsByNode: data.dump(),
|
|
1540
|
-
nodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId
|
|
1683
|
+
nodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId,
|
|
1684
|
+
finishedAtIso: completedAt
|
|
1541
1685
|
});
|
|
1542
1686
|
await this.workflowExecutionRepository.save(completedState);
|
|
1543
1687
|
await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
|
|
@@ -1565,7 +1709,8 @@ var RunContinuationService = class {
|
|
|
1565
1709
|
status: "failed",
|
|
1566
1710
|
queue: queue.map((q) => ({ ...q })),
|
|
1567
1711
|
outputsByNode: data.dump(),
|
|
1568
|
-
nodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId
|
|
1712
|
+
nodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId,
|
|
1713
|
+
finishedAtIso: completedAt
|
|
1569
1714
|
});
|
|
1570
1715
|
await this.workflowExecutionRepository.save(failedState);
|
|
1571
1716
|
await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
|
|
@@ -1619,17 +1764,19 @@ var RunContinuationService = class {
|
|
|
1619
1764
|
return result;
|
|
1620
1765
|
}
|
|
1621
1766
|
async resumeFromNodeError(args) {
|
|
1622
|
-
const state = await this.workflowExecutionRepository.load(args.runId);
|
|
1767
|
+
const [state, schedulingState] = await Promise.all([this.workflowExecutionRepository.load(args.runId), this.workflowExecutionRepository.loadSchedulingState(args.runId)]);
|
|
1623
1768
|
if (!state) throw new Error(`Unknown runId: ${args.runId}`);
|
|
1624
|
-
|
|
1625
|
-
if (
|
|
1626
|
-
if (
|
|
1769
|
+
const pendingExecution = this.requirePendingExecution(args.runId, args.activationId, args.nodeId, state, schedulingState);
|
|
1770
|
+
if (pendingExecution.activationId !== args.activationId) throw new Error(`activationId mismatch for run ${args.runId}`);
|
|
1771
|
+
if (pendingExecution.nodeId !== args.nodeId) throw new Error(`nodeId mismatch for run ${args.runId}`);
|
|
1627
1772
|
const wf = this.resolvePersistedWorkflow(state);
|
|
1628
1773
|
if (!wf) throw new Error(`Unknown workflowId: ${state.workflowId}`);
|
|
1629
1774
|
const failedDefinition = WorkflowTopology.fromWorkflow(wf).defsById.get(args.nodeId);
|
|
1630
1775
|
const webhookControlSignal = state.executionOptions?.webhook && failedDefinition?.kind === "trigger" ? this.asWebhookControlSignal(args.error) : void 0;
|
|
1631
1776
|
if (webhookControlSignal) return await this.resumeFromWebhookControl({
|
|
1632
1777
|
state,
|
|
1778
|
+
schedulingState,
|
|
1779
|
+
pendingExecution,
|
|
1633
1780
|
workflow: wf,
|
|
1634
1781
|
args,
|
|
1635
1782
|
signal: webhookControlSignal
|
|
@@ -1637,8 +1784,8 @@ var RunContinuationService = class {
|
|
|
1637
1784
|
if (failedDefinition && failedDefinition.kind === "node") {
|
|
1638
1785
|
const nodeHandler = this.policyErrorServices.resolveNodeErrorHandler(failedDefinition.config.nodeErrorHandler);
|
|
1639
1786
|
if (nodeHandler) try {
|
|
1640
|
-
const ctx = this.buildNodeExecutionContextForPending(state, wf, failedDefinition, args.nodeId);
|
|
1641
|
-
const inputsByPort =
|
|
1787
|
+
const ctx = this.buildNodeExecutionContextForPending(state, pendingExecution, wf, failedDefinition, args.nodeId);
|
|
1788
|
+
const inputsByPort = pendingExecution.inputsByPort;
|
|
1642
1789
|
const portKeys = Object.keys(inputsByPort);
|
|
1643
1790
|
const kind = portKeys.length === 1 && portKeys[0] === "in" ? "single" : "multi";
|
|
1644
1791
|
const items = inputsByPort.in ?? [];
|
|
@@ -1667,19 +1814,20 @@ var RunContinuationService = class {
|
|
|
1667
1814
|
activationId: args.activationId,
|
|
1668
1815
|
parent: state.parent,
|
|
1669
1816
|
finishedAt,
|
|
1670
|
-
inputsByPort:
|
|
1817
|
+
inputsByPort: pendingExecution.inputsByPort,
|
|
1671
1818
|
error: args.error
|
|
1672
1819
|
});
|
|
1673
1820
|
const failedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
|
|
1674
1821
|
state,
|
|
1675
1822
|
engineCounters: state.engineCounters ?? { completedNodeActivations: 0 },
|
|
1676
1823
|
status: "failed",
|
|
1677
|
-
queue: (
|
|
1824
|
+
queue: (schedulingState?.queue ?? []).map((q) => ({ ...q })),
|
|
1678
1825
|
outputsByNode: state.outputsByNode,
|
|
1679
1826
|
nodeSnapshotsByNodeId: {
|
|
1680
1827
|
...state.nodeSnapshotsByNodeId ?? {},
|
|
1681
1828
|
[args.nodeId]: failedSnapshot
|
|
1682
|
-
}
|
|
1829
|
+
},
|
|
1830
|
+
finishedAtIso: finishedAt
|
|
1683
1831
|
});
|
|
1684
1832
|
await this.workflowExecutionRepository.save(failedState);
|
|
1685
1833
|
await this.nodeEventPublisher.publish("nodeFailed", failedSnapshot);
|
|
@@ -1756,7 +1904,7 @@ var RunContinuationService = class {
|
|
|
1756
1904
|
activationId: args.args.activationId,
|
|
1757
1905
|
parent: args.state.parent,
|
|
1758
1906
|
finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1759
|
-
inputsByPort: args.
|
|
1907
|
+
inputsByPort: args.pendingExecution.inputsByPort,
|
|
1760
1908
|
outputs: triggerOutputs
|
|
1761
1909
|
});
|
|
1762
1910
|
const completedActivations = (args.state.engineCounters?.completedNodeActivations ?? 0) + 1;
|
|
@@ -1772,7 +1920,8 @@ var RunContinuationService = class {
|
|
|
1772
1920
|
nodeSnapshotsByNodeId: {
|
|
1773
1921
|
...args.state.nodeSnapshotsByNodeId ?? {},
|
|
1774
1922
|
[args.args.nodeId]: completedSnapshot
|
|
1775
|
-
}
|
|
1923
|
+
},
|
|
1924
|
+
finishedAtIso: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt
|
|
1776
1925
|
});
|
|
1777
1926
|
await this.workflowExecutionRepository.save(completedState);
|
|
1778
1927
|
await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
|
|
@@ -1809,7 +1958,8 @@ var RunContinuationService = class {
|
|
|
1809
1958
|
nodeSnapshotsByNodeId: {
|
|
1810
1959
|
...args.state.nodeSnapshotsByNodeId ?? {},
|
|
1811
1960
|
[args.args.nodeId]: completedSnapshot
|
|
1812
|
-
}
|
|
1961
|
+
},
|
|
1962
|
+
finishedAtIso: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt
|
|
1813
1963
|
});
|
|
1814
1964
|
await this.workflowExecutionRepository.save(completedState);
|
|
1815
1965
|
await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
|
|
@@ -1836,8 +1986,8 @@ var RunContinuationService = class {
|
|
|
1836
1986
|
this.waiters.resolveRunCompletion(result$1);
|
|
1837
1987
|
return result$1;
|
|
1838
1988
|
}
|
|
1839
|
-
const batchId = args.
|
|
1840
|
-
const queue = (args.
|
|
1989
|
+
const batchId = args.pendingExecution.batchId ?? "batch_1";
|
|
1990
|
+
const queue = (args.schedulingState?.queue ?? []).map((entry) => ({
|
|
1841
1991
|
...entry,
|
|
1842
1992
|
batchId: entry.batchId ?? batchId
|
|
1843
1993
|
}));
|
|
@@ -1859,7 +2009,8 @@ var RunContinuationService = class {
|
|
|
1859
2009
|
nodeSnapshotsByNodeId: {
|
|
1860
2010
|
...args.state.nodeSnapshotsByNodeId ?? {},
|
|
1861
2011
|
[args.args.nodeId]: completedSnapshot
|
|
1862
|
-
}
|
|
2012
|
+
},
|
|
2013
|
+
finishedAtIso: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt
|
|
1863
2014
|
});
|
|
1864
2015
|
await this.workflowExecutionRepository.save(completedState);
|
|
1865
2016
|
await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
|
|
@@ -1897,7 +2048,8 @@ var RunContinuationService = class {
|
|
|
1897
2048
|
nodeSnapshotsByNodeId: {
|
|
1898
2049
|
...args.state.nodeSnapshotsByNodeId ?? {},
|
|
1899
2050
|
[args.args.nodeId]: completedSnapshot
|
|
1900
|
-
}
|
|
2051
|
+
},
|
|
2052
|
+
finishedAtIso: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt
|
|
1901
2053
|
});
|
|
1902
2054
|
await this.workflowExecutionRepository.save(failedState);
|
|
1903
2055
|
await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
|
|
@@ -1992,7 +2144,7 @@ var RunContinuationService = class {
|
|
|
1992
2144
|
workflowSnapshot: state.workflowSnapshot
|
|
1993
2145
|
});
|
|
1994
2146
|
}
|
|
1995
|
-
buildNodeExecutionContextForPending(state, wf, def, nodeId) {
|
|
2147
|
+
buildNodeExecutionContextForPending(state, pendingExecution, wf, def, nodeId) {
|
|
1996
2148
|
const data = this.runDataFactory.create(state.outputsByNode);
|
|
1997
2149
|
const limits = this.resolveEngineLimitsFromState(state);
|
|
1998
2150
|
const base = this.runExecutionContextFactory.create({
|
|
@@ -2006,7 +2158,7 @@ var RunContinuationService = class {
|
|
|
2006
2158
|
data,
|
|
2007
2159
|
nodeState: this.nodeStatePublisherFactory.create(state.runId, state.workflowId, state.parent)
|
|
2008
2160
|
});
|
|
2009
|
-
const activationId =
|
|
2161
|
+
const activationId = pendingExecution.activationId;
|
|
2010
2162
|
return {
|
|
2011
2163
|
...base,
|
|
2012
2164
|
data,
|
|
@@ -2020,6 +2172,14 @@ var RunContinuationService = class {
|
|
|
2020
2172
|
getCredential: this.credentialResolverFactory.create(wf.id, nodeId, def.config)
|
|
2021
2173
|
};
|
|
2022
2174
|
}
|
|
2175
|
+
requirePendingExecution(runId, activationId, nodeId, state, schedulingState) {
|
|
2176
|
+
if (state.status !== "pending") throw new Error(`Run ${runId} is not pending`);
|
|
2177
|
+
const pendingExecution = schedulingState?.pending;
|
|
2178
|
+
if (!pendingExecution) throw new Error(`Run ${runId} is not pending`);
|
|
2179
|
+
if (pendingExecution.activationId !== activationId) throw new Error(`activationId mismatch for run ${runId}`);
|
|
2180
|
+
if (pendingExecution.nodeId !== nodeId) throw new Error(`nodeId mismatch for run ${runId}`);
|
|
2181
|
+
return pendingExecution;
|
|
2182
|
+
}
|
|
2023
2183
|
resolveEngineLimitsFromState(state) {
|
|
2024
2184
|
const fb = this.executionLimitsPolicy.createRootExecutionOptions();
|
|
2025
2185
|
return {
|
|
@@ -2676,7 +2836,7 @@ var DefaultDrivingScheduler = class {
|
|
|
2676
2836
|
setContinuation(continuation) {
|
|
2677
2837
|
this.inline.setContinuation(continuation);
|
|
2678
2838
|
}
|
|
2679
|
-
async
|
|
2839
|
+
async prepareDispatch(request) {
|
|
2680
2840
|
const selection = await this.selectScheduler(request);
|
|
2681
2841
|
if (selection.mode === "worker") {
|
|
2682
2842
|
if (request.kind === "multi") throw new Error(`Multi-input node ${request.nodeId} cannot be scheduled to worker (insert local placement)`);
|
|
@@ -2691,15 +2851,17 @@ var DefaultDrivingScheduler = class {
|
|
|
2691
2851
|
executionOptions: request.executionOptions
|
|
2692
2852
|
};
|
|
2693
2853
|
return {
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2854
|
+
receipt: {
|
|
2855
|
+
receiptId: request.activationId,
|
|
2856
|
+
mode: "worker",
|
|
2857
|
+
queue: selection.queue
|
|
2858
|
+
},
|
|
2859
|
+
dispatch: async () => {
|
|
2860
|
+
await this.workerScheduler.enqueue(workerRequest);
|
|
2861
|
+
}
|
|
2697
2862
|
};
|
|
2698
2863
|
}
|
|
2699
|
-
return await this.
|
|
2700
|
-
}
|
|
2701
|
-
notifyPendingStatePersisted(runId) {
|
|
2702
|
-
this.inline.notifyPendingStatePersisted(runId);
|
|
2864
|
+
return await this.prepareInlineDispatch(request);
|
|
2703
2865
|
}
|
|
2704
2866
|
/**
|
|
2705
2867
|
* Scheduler precedence is explicit:
|
|
@@ -2731,10 +2893,16 @@ var DefaultDrivingScheduler = class {
|
|
|
2731
2893
|
hasNodeSchedulingPreference(request) {
|
|
2732
2894
|
return request.ctx.config.execution?.hint !== void 0 || request.ctx.config.execution?.queue !== void 0;
|
|
2733
2895
|
}
|
|
2734
|
-
async
|
|
2896
|
+
async prepareInlineDispatch(request) {
|
|
2897
|
+
const prepared = await this.inline.prepareDispatch(request);
|
|
2735
2898
|
return {
|
|
2736
|
-
|
|
2737
|
-
|
|
2899
|
+
receipt: {
|
|
2900
|
+
...prepared.receipt,
|
|
2901
|
+
mode: "local"
|
|
2902
|
+
},
|
|
2903
|
+
dispatch: async () => {
|
|
2904
|
+
await prepared.dispatch();
|
|
2905
|
+
}
|
|
2738
2906
|
};
|
|
2739
2907
|
}
|
|
2740
2908
|
};
|
|
@@ -2758,29 +2926,29 @@ var InlineDrivingScheduler = class {
|
|
|
2758
2926
|
drainingRuns = /* @__PURE__ */ new Set();
|
|
2759
2927
|
queuesByRunId = /* @__PURE__ */ new Map();
|
|
2760
2928
|
scheduledRuns = /* @__PURE__ */ new Set();
|
|
2761
|
-
seq = 0;
|
|
2762
2929
|
constructor(nodeExecutor) {
|
|
2763
2930
|
this.nodeExecutor = nodeExecutor;
|
|
2764
2931
|
}
|
|
2765
2932
|
setContinuation(continuation) {
|
|
2766
2933
|
this.continuation = continuation;
|
|
2767
2934
|
}
|
|
2768
|
-
async
|
|
2935
|
+
async prepareDispatch(request) {
|
|
2769
2936
|
const receipt = {
|
|
2770
|
-
receiptId:
|
|
2937
|
+
receiptId: request.activationId,
|
|
2771
2938
|
mode: "local"
|
|
2772
2939
|
};
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2940
|
+
return {
|
|
2941
|
+
receipt,
|
|
2942
|
+
dispatch: async () => {
|
|
2943
|
+
const queue = this.queuesByRunId.get(request.runId) ?? [];
|
|
2944
|
+
queue.push({
|
|
2945
|
+
request,
|
|
2946
|
+
receipt
|
|
2947
|
+
});
|
|
2948
|
+
this.queuesByRunId.set(request.runId, queue);
|
|
2949
|
+
this.scheduleDrain(request.runId);
|
|
2950
|
+
}
|
|
2951
|
+
};
|
|
2784
2952
|
}
|
|
2785
2953
|
async drainRun(runId) {
|
|
2786
2954
|
if (this.drainingRuns.has(runId)) return;
|
|
@@ -3046,9 +3214,10 @@ var InMemoryRunDataFactory = class {
|
|
|
3046
3214
|
|
|
3047
3215
|
//#endregion
|
|
3048
3216
|
//#region src/contracts/runFinishedAtFactory.ts
|
|
3049
|
-
/** Derives workflow end time from node snapshots for run listings. */
|
|
3217
|
+
/** Derives workflow end time from persisted run root or node snapshots for run listings. */
|
|
3050
3218
|
var RunFinishedAtFactory = class {
|
|
3051
3219
|
static resolveIso(state) {
|
|
3220
|
+
if (state.finishedAt && state.status !== "running" && state.status !== "pending") return state.finishedAt;
|
|
3052
3221
|
if (state.status === "running" || state.status === "pending") return;
|
|
3053
3222
|
let max;
|
|
3054
3223
|
for (const snap of Object.values(state.nodeSnapshotsByNodeId)) if (snap?.finishedAt && (!max || snap.finishedAt > max)) max = snap.finishedAt;
|
|
@@ -3056,6 +3225,22 @@ var RunFinishedAtFactory = class {
|
|
|
3056
3225
|
}
|
|
3057
3226
|
};
|
|
3058
3227
|
|
|
3228
|
+
//#endregion
|
|
3229
|
+
//#region src/runtime/InMemoryLiveWorkflowRepository.ts
|
|
3230
|
+
var InMemoryLiveWorkflowRepository = class {
|
|
3231
|
+
workflowsById = /* @__PURE__ */ new Map();
|
|
3232
|
+
setWorkflows(workflows) {
|
|
3233
|
+
this.workflowsById.clear();
|
|
3234
|
+
for (const workflow of workflows) this.workflowsById.set(workflow.id, workflow);
|
|
3235
|
+
}
|
|
3236
|
+
list() {
|
|
3237
|
+
return [...this.workflowsById.values()];
|
|
3238
|
+
}
|
|
3239
|
+
get(workflowId) {
|
|
3240
|
+
return this.workflowsById.get(workflowId);
|
|
3241
|
+
}
|
|
3242
|
+
};
|
|
3243
|
+
|
|
3059
3244
|
//#endregion
|
|
3060
3245
|
//#region src/runtime/RunIntentService.ts
|
|
3061
3246
|
var RunIntentService = class {
|
|
@@ -3184,5 +3369,5 @@ var RunIntentService = class {
|
|
|
3184
3369
|
};
|
|
3185
3370
|
|
|
3186
3371
|
//#endregion
|
|
3187
|
-
export {
|
|
3188
|
-
//# sourceMappingURL=RunIntentService-
|
|
3372
|
+
export { delay as $, NodeExecutor as A, NodeEventPublisher as B, WorkflowSnapshotResolver as C, MissingRuntimeTriggerToken as D, MissingRuntimeFallbacks as E, DefaultAsyncSleeper as F, getPersistedRuntimeTypeMetadata as G, WorkflowExecutableNodeClassifier as H, CredentialResolverFactory as I, InjectableRuntimeDecoratorComposer as J, node as K, ActivationEnqueueService as L, InProcessRetryRunnerFactory as M, InProcessRetryRunner as N, MissingRuntimeExecutionMarker as O, DefaultExecutionContextFactory as P, container$1 as Q, DefaultExecutionBinaryService as R, NodeInstanceFactory as S, PersistedWorkflowTokenRegistry as T, ConnectionNodeIdFactory as U, WorkflowExecutableNodeClassifierFactory as V, chatModel as W, StackTraceCallSitePathResolver as X, PersistedRuntimeTypeMetadataStore as Y, PersistedRuntimeTypeNameResolver as Z, WorkflowRunExecutionContextFactory as _, InMemoryBinaryStorage as a, predicateAwareClassFactory as at, NodeRunStateWriterFactory as b, LocalOnlyScheduler as c, CoreTokens as ct, DefaultDrivingScheduler as d, inject as et, ConfigDrivenOffloadPolicy as f, WorkflowTopology as g, RunContinuationService as h, InMemoryRunDataFactory as i, instancePerContainerCachingFactory as it, NodeActivationRequestComposer as j, NodeExecutorFactory as k, InlineDrivingScheduler as l, RunPolicySnapshotFactory as m, InMemoryLiveWorkflowRepository as n, injectable as nt, ENGINE_EXECUTION_LIMITS_DEFAULTS as o, registry as ot, RunStartService as p, tool as q, RunFinishedAtFactory as r, instanceCachingFactory as rt, EngineExecutionLimitsPolicy as s, singleton as st, RunIntentService as t, injectAll as tt, HintOnlyOffloadPolicy as u, RunStateSemantics as v, WorkflowSnapshotCodec as w, NodeInstanceFactoryFactory as x, PersistedRunStateTerminalBuilder as y, UnavailableBinaryStorage as z };
|
|
3373
|
+
//# sourceMappingURL=RunIntentService-BFA48UpH.js.map
|