@oomol-lab/open-flow 0.1.0-beta.65 → 0.1.0-beta.67
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/dist/browser/{createResourceDialog-BAJXbzNH.js → createResourceDialog-BQVD8Rqb.js} +2 -2
- package/dist/browser/{icons-Db2Jb2iX.js → dialog-CS2Vt2if.js} +5736 -5621
- package/dist/browser/event-sources.d.ts +4 -1
- package/dist/browser/flow-authoring-node.d.ts +14 -3
- package/dist/browser/flow-authoring.js +120 -24
- package/dist/browser/flow-change-schema.d.ts +3 -1
- package/dist/browser/flow-change.d.ts +15 -3
- package/dist/browser/flow-change.js +117 -21
- package/dist/browser/{flowChanges-DkvG5uDq.js → flowChanges-VB9Y4iy7.js} +3423 -2380
- package/dist/browser/{flowRunInputEditorStore-B2Rw4VsT.js → flowRunInputEditorStore-DJqmR6Qh.js} +3 -2
- package/dist/browser/{flowWorkspace-BEp-lxqF.js → flowWorkspace-C1hlTnZq.js} +1410 -799
- package/dist/browser/preview.css +273 -119
- package/dist/browser/preview.js +17118 -15810
- package/dist/browser/theme.css +1 -0
- package/dist/browser/ui.css +119 -7
- package/dist/browser/ui.js +8 -5
- package/dist/browser/workbench-contract.d.ts +1 -1
- package/dist/browser/workbench.css +282 -162
- package/dist/browser/workbench.d.ts +0 -1
- package/dist/browser/workbench.js +503 -173
- package/dist/browser/{workbenchSelect-C-jf6NIM.js → workbenchSelect-CpXhjUou.js} +1 -1
- package/dist/command/index.js +49 -49
- package/dist/common/authoring.d.ts +7 -5
- package/dist/common/authoringExamples.d.ts +4 -4
- package/dist/common/authoringFields.d.ts +20 -0
- package/dist/common/authoringSchema.d.ts +404 -15
- package/dist/common/control-api-conformance.js +415 -146
- package/dist/common/control-api.d.ts +67 -8
- package/dist/common/control-api.js +3587 -3443
- package/dist/common/control-requests.d.ts +10 -3
- package/dist/common/control-requests.js +425 -49
- package/dist/common/decision.js +33 -7
- package/dist/common/flow-encoding.d.ts +4 -2
- package/dist/common/flow-encoding.js +151 -14
- package/dist/common/flow-graph.d.ts +1 -1
- package/dist/common/flow-semantics.d.ts +12 -2
- package/dist/common/flow-semantics.js +157 -41
- package/dist/common/integration-trigger.js +33 -7
- package/dist/common/liveDetails.d.ts +26 -11
- package/dist/common/mcp.d.ts +6 -3
- package/dist/common/mcp.js +219 -90
- package/dist/common/openapi.js +33 -7
- package/dist/common/poll-trigger.js +33 -7
- package/dist/common/run-events.d.ts +2 -0
- package/dist/common/run-events.js +9 -3
- package/dist/common/scheduler.d.ts +10 -1
- package/dist/common/scheduler.js +172 -49
- package/dist/common/trigger-contract.d.ts +2 -0
- package/dist/common/webhook-trigger.js +33 -7
- package/dist/common/workflow.d.ts +93 -0
- package/dist/common/workflow.js +10492 -0
- package/package.json +5 -1
- package/skills/open-flow/SKILL.md +9 -0
- package/skills/open-flow/references/flow-authoring.md +28 -16
package/dist/common/scheduler.js
CHANGED
|
@@ -9496,6 +9496,7 @@ function webhookSupportsBody(method) {
|
|
|
9496
9496
|
return method !== "GET";
|
|
9497
9497
|
}
|
|
9498
9498
|
var text = string();
|
|
9499
|
+
var actionConnection = text.describe("Account selection: omit while unconfigured; use an account ID to select it; use \"\" to explicitly defer configuration. Deferred Actions fail if called; deferred Agent tools are excluded from the callable tool set. Not supported by Triggers.");
|
|
9499
9500
|
var json = json$1();
|
|
9500
9501
|
var strings = array(text);
|
|
9501
9502
|
var port = object({
|
|
@@ -9504,6 +9505,7 @@ var port = object({
|
|
|
9504
9505
|
nullable: boolean(),
|
|
9505
9506
|
handle: text
|
|
9506
9507
|
});
|
|
9508
|
+
var workflowInputDefs = array(port.strict());
|
|
9507
9509
|
var input = port.extend({ value: json.optional() });
|
|
9508
9510
|
var group = object({
|
|
9509
9511
|
collapsed: boolean().optional(),
|
|
@@ -9550,7 +9552,7 @@ var capability = union([
|
|
|
9550
9552
|
mode: literal("independent"),
|
|
9551
9553
|
actions: array(strictObject({
|
|
9552
9554
|
action: text,
|
|
9553
|
-
connectionId:
|
|
9555
|
+
connectionId: actionConnection.optional()
|
|
9554
9556
|
}))
|
|
9555
9557
|
}),
|
|
9556
9558
|
strictObject({
|
|
@@ -9610,7 +9612,7 @@ var managedFields = object({
|
|
|
9610
9612
|
object({
|
|
9611
9613
|
kind: literal("connector"),
|
|
9612
9614
|
action: text,
|
|
9613
|
-
connectionId:
|
|
9615
|
+
connectionId: actionConnection.optional(),
|
|
9614
9616
|
outputMode: literal("value").optional()
|
|
9615
9617
|
}),
|
|
9616
9618
|
object({
|
|
@@ -9650,17 +9652,22 @@ var managedFields = object({
|
|
|
9650
9652
|
name: text,
|
|
9651
9653
|
description: text,
|
|
9652
9654
|
action: text,
|
|
9653
|
-
connectionId:
|
|
9655
|
+
connectionId: actionConnection.optional(),
|
|
9654
9656
|
approval: boolean(),
|
|
9655
9657
|
inputs: array(input.extend({ source: agentInput$1 }))
|
|
9656
9658
|
})),
|
|
9657
9659
|
notification: object({
|
|
9658
9660
|
action: text,
|
|
9659
|
-
connectionId:
|
|
9661
|
+
connectionId: actionConnection.optional(),
|
|
9660
9662
|
inputDefinitions: array(input),
|
|
9661
9663
|
messageHandle: text,
|
|
9662
9664
|
inputs: record$1(text, agentValue)
|
|
9663
9665
|
}).optional()
|
|
9666
|
+
}),
|
|
9667
|
+
strictObject({
|
|
9668
|
+
kind: literal("workflow"),
|
|
9669
|
+
flowId: text,
|
|
9670
|
+
revisionId: text
|
|
9664
9671
|
})
|
|
9665
9672
|
])
|
|
9666
9673
|
});
|
|
@@ -9769,6 +9776,12 @@ var base = {
|
|
|
9769
9776
|
timeoutMs: number().optional()
|
|
9770
9777
|
};
|
|
9771
9778
|
var node = union([
|
|
9779
|
+
strictObject({
|
|
9780
|
+
...base,
|
|
9781
|
+
kind: literal("outputs"),
|
|
9782
|
+
outputDefs: array(port.strict()),
|
|
9783
|
+
outputMappings: inputs
|
|
9784
|
+
}).omit({ inputs: true }),
|
|
9772
9785
|
object({
|
|
9773
9786
|
...base,
|
|
9774
9787
|
inputs: record$1(text, never()),
|
|
@@ -9801,6 +9814,11 @@ var node = union([
|
|
|
9801
9814
|
...trigger,
|
|
9802
9815
|
kind: literal("manual")
|
|
9803
9816
|
}),
|
|
9817
|
+
strictObject({
|
|
9818
|
+
...trigger,
|
|
9819
|
+
kind: literal("start"),
|
|
9820
|
+
inputDefs: workflowInputDefs
|
|
9821
|
+
}),
|
|
9804
9822
|
strictObject({
|
|
9805
9823
|
...trigger,
|
|
9806
9824
|
kind: literal("error"),
|
|
@@ -9865,7 +9883,7 @@ var module = object({
|
|
|
9865
9883
|
imports: strings,
|
|
9866
9884
|
source: text
|
|
9867
9885
|
});
|
|
9868
|
-
var document = preprocess(
|
|
9886
|
+
var document = preprocess(normalizeDocument, object({
|
|
9869
9887
|
bindings: record$1(text, binding),
|
|
9870
9888
|
graph
|
|
9871
9889
|
}));
|
|
@@ -9874,7 +9892,9 @@ object({
|
|
|
9874
9892
|
literal(2),
|
|
9875
9893
|
literal(4),
|
|
9876
9894
|
literal(5),
|
|
9877
|
-
literal(6)
|
|
9895
|
+
literal(6),
|
|
9896
|
+
literal(7),
|
|
9897
|
+
literal(8)
|
|
9878
9898
|
]),
|
|
9879
9899
|
document,
|
|
9880
9900
|
modules: record$1(text, module)
|
|
@@ -9882,13 +9902,19 @@ object({
|
|
|
9882
9902
|
kind: literal("open-flow-flow-revision"),
|
|
9883
9903
|
version: literal(1)
|
|
9884
9904
|
});
|
|
9885
|
-
function
|
|
9905
|
+
function normalizeDocument(value) {
|
|
9886
9906
|
const candidate = record(value);
|
|
9887
9907
|
if (candidate.tasks !== void 0 && (candidate.tasks === null || typeof candidate.tasks !== "object" || Array.isArray(candidate.tasks) || Object.keys(candidate.tasks).length > 0)) throw new TypeError("Independent Task definitions are no longer supported.");
|
|
9888
9908
|
if (Object.values(record(record(candidate.graph).nodes)).some((candidateNode) => Object.hasOwn(record(candidateNode), "taskId"))) throw new TypeError("Task references are no longer supported.");
|
|
9889
9909
|
const subflows = candidate.subflows;
|
|
9890
9910
|
if (subflows !== void 0 && (subflows === null || typeof subflows !== "object" || Array.isArray(subflows) || Object.keys(subflows).length > 0)) throw new TypeError("Subflows are no longer supported.");
|
|
9891
9911
|
if (Object.values(record(record(candidate.graph).nodes)).some((candidateNode) => record(candidateNode).kind === "subflow")) throw new TypeError("Subflow nodes are no longer supported.");
|
|
9912
|
+
if ([
|
|
9913
|
+
"inputDefs",
|
|
9914
|
+
"outputDefs",
|
|
9915
|
+
"outputMappings"
|
|
9916
|
+
].some((field) => Object.hasOwn(candidate, field))) throw new TypeError("Workflow interface configuration must belong to Start and Outputs nodes.");
|
|
9917
|
+
if (Object.values(record(record(candidate.graph).nodes)).some((candidateNode) => record(candidateNode).kind == "start" && Object.hasOwn(record(candidateNode), "parameters"))) throw new TypeError("Legacy Start.parameters is unsupported; configure node.inputDefs.");
|
|
9892
9918
|
return value;
|
|
9893
9919
|
}
|
|
9894
9920
|
function record(value) {
|
|
@@ -10088,6 +10114,7 @@ function conditionOperands(node) {
|
|
|
10088
10114
|
}] : []])));
|
|
10089
10115
|
}
|
|
10090
10116
|
function nodeInputMappings(node) {
|
|
10117
|
+
if (node.kind == "outputs") return node.outputMappings;
|
|
10091
10118
|
if (node.kind != "condition") return "inputs" in node ? node.inputs : {};
|
|
10092
10119
|
return Object.fromEntries(conditionOperands(node).flatMap(({ handle, operand }) => operand.kind == "source" ? [[handle, {
|
|
10093
10120
|
kind: "sources",
|
|
@@ -10243,6 +10270,17 @@ function selectConditionBranches(node, values) {
|
|
|
10243
10270
|
function portsByHandle(ports) {
|
|
10244
10271
|
return Object.fromEntries(ports.flatMap((port) => "handle" in port ? [[port.handle, port]] : []));
|
|
10245
10272
|
}
|
|
10273
|
+
function isTriggerNode(node) {
|
|
10274
|
+
return [
|
|
10275
|
+
"manual",
|
|
10276
|
+
"start",
|
|
10277
|
+
"error",
|
|
10278
|
+
"webhook",
|
|
10279
|
+
"cron",
|
|
10280
|
+
"poll",
|
|
10281
|
+
"integration"
|
|
10282
|
+
].includes(node.kind);
|
|
10283
|
+
}
|
|
10246
10284
|
//#endregion
|
|
10247
10285
|
//#region src/flow/common/agent.ts
|
|
10248
10286
|
var schema = lazy(() => union([boolean(), strictObject({
|
|
@@ -10515,6 +10553,7 @@ function triggerOutputDefinitions(trigger) {
|
|
|
10515
10553
|
switch (trigger.kind) {
|
|
10516
10554
|
case "error": return errorOutputs;
|
|
10517
10555
|
case "manual": return [];
|
|
10556
|
+
case "start": return trigger.inputDefs;
|
|
10518
10557
|
case "cron": return cronOutputs;
|
|
10519
10558
|
case "poll":
|
|
10520
10559
|
case "integration": return trigger.definition.outputs;
|
|
@@ -10534,11 +10573,37 @@ function matchesTriggerOutputs(trigger, outputs) {
|
|
|
10534
10573
|
const ports = triggerOutputDefinitions(trigger);
|
|
10535
10574
|
return new Set(ports.map((port) => port.handle)).size === ports.length && Object.keys(outputs).length === ports.length && ports.every((port) => Object.hasOwn(outputs, port.handle) && (outputs[port.handle] === null && port.nullable || matchesSchema(outputs[port.handle], port.jsonSchema)));
|
|
10536
10575
|
}
|
|
10576
|
+
/** Resolve caller-supplied Start parameters into the complete output snapshot used by execution. */
|
|
10577
|
+
function normalizeTriggerOutputs(trigger, outputs) {
|
|
10578
|
+
if (!isJsonObject(outputs)) return;
|
|
10579
|
+
const normalized = trigger.kind == "start" ? {
|
|
10580
|
+
...outputs,
|
|
10581
|
+
...Object.fromEntries(trigger.inputDefs.filter((port) => port.nullable && !Object.hasOwn(outputs, port.handle)).map((port) => [port.handle, null]))
|
|
10582
|
+
} : outputs;
|
|
10583
|
+
return matchesTriggerOutputs(trigger, normalized) ? normalized : void 0;
|
|
10584
|
+
}
|
|
10537
10585
|
//#endregion
|
|
10538
10586
|
//#region src/flow/common/graph.ts
|
|
10539
10587
|
function isResolutionNode(node) {
|
|
10540
10588
|
return node?.kind == "approval" || node?.kind == "wait";
|
|
10541
10589
|
}
|
|
10590
|
+
function nodeInputPorts(node) {
|
|
10591
|
+
switch (node.kind) {
|
|
10592
|
+
case "outputs": return portsByHandle(node.outputDefs);
|
|
10593
|
+
case "condition": return conditionInputPorts(node);
|
|
10594
|
+
case "value": return {};
|
|
10595
|
+
case "task": return portsByHandle([...node.task.inputs, ...node.additionalInputs ?? []]);
|
|
10596
|
+
case "approval":
|
|
10597
|
+
case "wait": return portsByHandle(node.inputDefinitions);
|
|
10598
|
+
case "cron":
|
|
10599
|
+
case "integration":
|
|
10600
|
+
case "poll":
|
|
10601
|
+
case "error":
|
|
10602
|
+
case "manual":
|
|
10603
|
+
case "start":
|
|
10604
|
+
case "webhook": return {};
|
|
10605
|
+
}
|
|
10606
|
+
}
|
|
10542
10607
|
function resolutionActions(node) {
|
|
10543
10608
|
return node.kind == "wait" ? ["continue"] : ["approve", "reject"];
|
|
10544
10609
|
}
|
|
@@ -10582,6 +10647,7 @@ function resolutionOutputPorts(node) {
|
|
|
10582
10647
|
}
|
|
10583
10648
|
function nodeOutputPorts(node) {
|
|
10584
10649
|
switch (node.kind) {
|
|
10650
|
+
case "outputs":
|
|
10585
10651
|
case "condition": return {};
|
|
10586
10652
|
case "value": return portsByHandle(node.values);
|
|
10587
10653
|
case "task": return portsByHandle(node.task.outputs);
|
|
@@ -10592,6 +10658,7 @@ function nodeOutputPorts(node) {
|
|
|
10592
10658
|
case "poll":
|
|
10593
10659
|
case "error":
|
|
10594
10660
|
case "manual":
|
|
10661
|
+
case "start":
|
|
10595
10662
|
case "webhook": return triggerOutputPorts(node);
|
|
10596
10663
|
}
|
|
10597
10664
|
}
|
|
@@ -10658,7 +10725,7 @@ var Dependencies = class {
|
|
|
10658
10725
|
stack.delete(id);
|
|
10659
10726
|
};
|
|
10660
10727
|
const ids = Object.keys(graph.nodes).toSorted();
|
|
10661
|
-
for (const triggerId of ids.filter((id) =>
|
|
10728
|
+
for (const triggerId of ids.filter((id) => isTriggerNode(graph.nodes[id]))) visit(triggerId);
|
|
10662
10729
|
for (const id of ids) visit(id);
|
|
10663
10730
|
for (const edge of this.forward) {
|
|
10664
10731
|
const edges = this.incoming.get(edge.target) ?? [];
|
|
@@ -10733,7 +10800,7 @@ var Dependencies = class {
|
|
|
10733
10800
|
}
|
|
10734
10801
|
start(nodeId, outputs) {
|
|
10735
10802
|
for (const [id, node] of Object.entries(this.graph.nodes)) {
|
|
10736
|
-
if (
|
|
10803
|
+
if (!isTriggerNode(node)) continue;
|
|
10737
10804
|
const state = this.state.nodes[id];
|
|
10738
10805
|
state.status = id == nodeId ? "completed" : "skipped";
|
|
10739
10806
|
if (id == nodeId) {
|
|
@@ -10902,7 +10969,7 @@ var withWaitNotificationMessage = withWaitNotificationMessage$1;
|
|
|
10902
10969
|
var normalizeWaitComment = normalizeWaitComment$1;
|
|
10903
10970
|
var PortValidationError = class extends Error {};
|
|
10904
10971
|
function usesPending(graph, nodeId) {
|
|
10905
|
-
return graph.edges.some((edge) => edge.source == nodeId && edge.sourceHandle == "pending") || Object.values(graph.nodes).some((node) =>
|
|
10972
|
+
return graph.edges.some((edge) => edge.source == nodeId && edge.sourceHandle == "pending") || Object.values(graph.nodes).some((node) => !isTriggerNode(node) && Object.values(nodeInputMappings(node)).some((mapping) => mapping.kind == "sources" && mapping.sources.some((source) => source.kind == "node" && source.nodeId == nodeId && source.output == "pending")));
|
|
10906
10973
|
}
|
|
10907
10974
|
var waitRetentionMs = 12e4;
|
|
10908
10975
|
function nodeFailure(error, project) {
|
|
@@ -10911,19 +10978,11 @@ function nodeFailure(error, project) {
|
|
|
10911
10978
|
message: error instanceof Error ? error.message : String(error)
|
|
10912
10979
|
};
|
|
10913
10980
|
}
|
|
10914
|
-
function nodePorts(node) {
|
|
10915
|
-
switch (node.kind) {
|
|
10916
|
-
case "condition": return conditionInputPorts(node);
|
|
10917
|
-
case "value": return {};
|
|
10918
|
-
case "task": return portsByHandle([...node.task.inputs, ...node.additionalInputs ?? []]);
|
|
10919
|
-
case "approval":
|
|
10920
|
-
case "wait": return portsByHandle(node.inputDefinitions);
|
|
10921
|
-
}
|
|
10922
|
-
}
|
|
10923
10981
|
function nodeTitle(node) {
|
|
10924
10982
|
if (node.name != null) return node.name;
|
|
10925
10983
|
switch (node.kind) {
|
|
10926
10984
|
case "condition": return;
|
|
10985
|
+
case "outputs": return "Workflow Outputs";
|
|
10927
10986
|
case "value": return "Fixed Values";
|
|
10928
10987
|
case "task": return node.task.name;
|
|
10929
10988
|
case "approval": return "Approval";
|
|
@@ -10979,7 +11038,8 @@ function decodeFlowRunCheckpoint(input) {
|
|
|
10979
11038
|
"inputs",
|
|
10980
11039
|
"results",
|
|
10981
11040
|
"version",
|
|
10982
|
-
"waits"
|
|
11041
|
+
"waits",
|
|
11042
|
+
...source.calls === void 0 ? [] : ["calls"]
|
|
10983
11043
|
], "Flow Run checkpoint");
|
|
10984
11044
|
if (source.version != 5) throw new Error("Flow Run checkpoint version is unsupported.");
|
|
10985
11045
|
const bindingValues = Object.fromEntries(Object.entries(checkpointRecord(source.bindingValues, "Checkpoint bindings")).map(([id, value]) => {
|
|
@@ -11003,7 +11063,14 @@ function decodeFlowRunCheckpoint(input) {
|
|
|
11003
11063
|
value: json$1(),
|
|
11004
11064
|
waitId: string().min(1),
|
|
11005
11065
|
pending: json$1().optional()
|
|
11006
|
-
})).
|
|
11066
|
+
})).parse(source.waits);
|
|
11067
|
+
const calls = array(strictObject({
|
|
11068
|
+
jobId: string().min(1),
|
|
11069
|
+
nodeId: string().min(1),
|
|
11070
|
+
childRunId: string().min(1),
|
|
11071
|
+
input: record$1(string(), json$1())
|
|
11072
|
+
})).parse(source.calls ?? []);
|
|
11073
|
+
if (pendingWaits.length + calls.length == 0) throw new Error("Checkpoint has no pending execution.");
|
|
11007
11074
|
const agents = record$1(string(), strictObject({
|
|
11008
11075
|
invocationId: string().min(1),
|
|
11009
11076
|
input: record$1(string(), json$1()),
|
|
@@ -11017,6 +11084,10 @@ function decodeFlowRunCheckpoint(input) {
|
|
|
11017
11084
|
jobs.add(pending.jobId);
|
|
11018
11085
|
waits.add(pending.waitId);
|
|
11019
11086
|
}
|
|
11087
|
+
for (const call of calls) {
|
|
11088
|
+
if (jobs.has(call.jobId) || dependencies.nodes[call.nodeId]?.status != "running" || dependencies.nodes[call.nodeId]?.jobId != call.jobId || Object.values(results).some((result) => result.jobId == call.jobId)) throw new Error("Checkpoint call execution conflicts.");
|
|
11089
|
+
jobs.add(call.jobId);
|
|
11090
|
+
}
|
|
11020
11091
|
if (Object.values(dependencies.nodes).some((state) => state.status == "running" && !jobs.has(state.jobId))) throw new Error("Checkpoint dependency has no waiting execution.");
|
|
11021
11092
|
if (Object.keys(agents).some((id) => !jobs.has(id))) throw new Error("Checkpoint Agent has no waiting execution.");
|
|
11022
11093
|
return {
|
|
@@ -11027,7 +11098,8 @@ function decodeFlowRunCheckpoint(input) {
|
|
|
11027
11098
|
inputs,
|
|
11028
11099
|
results,
|
|
11029
11100
|
version: 5,
|
|
11030
|
-
waits: pendingWaits
|
|
11101
|
+
waits: pendingWaits,
|
|
11102
|
+
...source.calls === void 0 ? {} : { calls }
|
|
11031
11103
|
};
|
|
11032
11104
|
}
|
|
11033
11105
|
function jsonEqual(left, right) {
|
|
@@ -11079,14 +11151,14 @@ function agentApproval(config, checkpoint, inputs) {
|
|
|
11079
11151
|
}
|
|
11080
11152
|
function validateOutputs(nodeId, node, value) {
|
|
11081
11153
|
const raw = outputRecord(value, nodeId);
|
|
11082
|
-
const discardUndeclared = node.kind == "task" && "executor" in node.task && node.task.executor.kind == "connector";
|
|
11083
|
-
const ports = isResolutionNode(node) ? resolutionOutputPorts(node) : node.kind == "task" ? portsByHandle(node.task.outputs) : node.kind == "value" ? portsByHandle(node.values) : {};
|
|
11154
|
+
const discardUndeclared = node.kind == "task" && "executor" in node.task && (node.task.executor.kind == "connector" || node.task.executor.kind == "workflow");
|
|
11155
|
+
const ports = node.kind == "outputs" ? nodeInputPorts(node) : isResolutionNode(node) ? resolutionOutputPorts(node) : node.kind == "task" ? portsByHandle(node.task.outputs) : node.kind == "value" ? portsByHandle(node.values) : {};
|
|
11084
11156
|
const outputs = outputRecord(checkpointJson(Object.fromEntries(Object.entries(raw).map(([handle, item]) => [handle, Object.hasOwn(ports, handle) && item === void 0 ? null : item])), `Node "${nodeId}" outputs`), nodeId);
|
|
11085
11157
|
const complete = node.kind == "condition" || isResolutionNode(node) ? outputs : {
|
|
11086
11158
|
...Object.fromEntries(Object.keys(ports).map((handle) => [handle, null])),
|
|
11087
11159
|
...outputs
|
|
11088
11160
|
};
|
|
11089
|
-
const validated =
|
|
11161
|
+
const validated = [];
|
|
11090
11162
|
for (const [handle, output] of Object.entries(complete)) {
|
|
11091
11163
|
const port = ports[handle];
|
|
11092
11164
|
if (port == null) {
|
|
@@ -11094,9 +11166,9 @@ function validateOutputs(nodeId, node, value) {
|
|
|
11094
11166
|
throw new PortValidationError(`Node "${nodeId}" output "${handle}" does not match its declaration.`);
|
|
11095
11167
|
}
|
|
11096
11168
|
if (!(output === null && port.nullable) && !matchesSchema(output, port.jsonSchema)) throw new PortValidationError(`Node "${nodeId}" output "${handle}" does not match its declaration.`);
|
|
11097
|
-
validated[handle
|
|
11169
|
+
validated.push([handle, output]);
|
|
11098
11170
|
}
|
|
11099
|
-
return validated;
|
|
11171
|
+
return Object.fromEntries(validated);
|
|
11100
11172
|
}
|
|
11101
11173
|
function validateCheckpoint(target, checkpoint, resolveInputs) {
|
|
11102
11174
|
const launch = checkpoint.inputs;
|
|
@@ -11107,14 +11179,14 @@ function validateCheckpoint(target, checkpoint, resolveInputs) {
|
|
|
11107
11179
|
if (graph == null) throw new Error("Checkpoint execution counts reference an unknown graph.");
|
|
11108
11180
|
for (const [id, count] of Object.entries(counts)) {
|
|
11109
11181
|
const node = graph.nodes[id];
|
|
11110
|
-
if (node == null ||
|
|
11182
|
+
if (node == null || isTriggerNode(node) || count > (node.maxExecutions ?? 1e3)) throw new Error("Checkpoint execution count is invalid.");
|
|
11111
11183
|
}
|
|
11112
11184
|
}
|
|
11113
11185
|
const validateResults = (results, frame = false) => {
|
|
11114
11186
|
for (const [id, outputs] of Object.entries(results)) {
|
|
11115
11187
|
const node = target.graph.nodes[id];
|
|
11116
11188
|
if (node == null) throw new Error("Checkpoint result node is missing.");
|
|
11117
|
-
if (
|
|
11189
|
+
if (isTriggerNode(node)) {
|
|
11118
11190
|
if (!matchesTriggerOutputs(node, outputs)) throw new Error("Checkpoint Trigger output is invalid.");
|
|
11119
11191
|
} else {
|
|
11120
11192
|
if (checkpoint.counts[""]?.[id] == null) throw new Error("Checkpoint execution count is missing.");
|
|
@@ -11125,20 +11197,20 @@ function validateCheckpoint(target, checkpoint, resolveInputs) {
|
|
|
11125
11197
|
}
|
|
11126
11198
|
};
|
|
11127
11199
|
validateResults(Object.fromEntries(Object.entries(checkpoint.results).map(([id, result]) => [id, result.outputs])));
|
|
11128
|
-
const triggerIds = Object.keys(checkpoint.results).filter((id) =>
|
|
11200
|
+
const triggerIds = Object.keys(checkpoint.results).filter((id) => isTriggerNode(target.graph.nodes[id]));
|
|
11129
11201
|
if (triggerIds.length != 1) throw new Error("Checkpoint must contain exactly one selected Trigger.");
|
|
11130
11202
|
const pendingCounts = /* @__PURE__ */ new Map();
|
|
11131
|
-
for (const waiting of checkpoint.waits) pendingCounts.set(waiting.nodeId, (pendingCounts.get(waiting.nodeId) ?? 0) + 1);
|
|
11203
|
+
for (const waiting of [...checkpoint.waits, ...checkpoint.calls ?? []]) pendingCounts.set(waiting.nodeId, (pendingCounts.get(waiting.nodeId) ?? 0) + 1);
|
|
11132
11204
|
for (const [id, count] of pendingCounts) if ((checkpoint.counts[""]?.[id] ?? 0) < count + (checkpoint.results[id] == null ? 0 : 1)) throw new Error("Checkpoint waiting execution count is incomplete.");
|
|
11133
11205
|
for (const [id, values] of Object.entries(launch)) {
|
|
11134
11206
|
const node = target.graph.nodes[id];
|
|
11135
|
-
if (
|
|
11207
|
+
if (isTriggerNode(node) || Object.keys(values).some((handle) => nodeInputPorts(node)[handle] == null)) throw new Error("Checkpoint launch inputs do not match the prepared graph.");
|
|
11136
11208
|
}
|
|
11137
11209
|
for (const [nodeId, state] of Object.entries(checkpoint.dependencies.nodes)) {
|
|
11138
11210
|
const frame = dependencyValues(state.input);
|
|
11139
11211
|
validateResults(frame, true);
|
|
11140
|
-
if (
|
|
11141
|
-
const triggers = Object.keys(frame).filter((id) =>
|
|
11212
|
+
if (!isTriggerNode(target.graph.nodes[nodeId]) && (state.status == "running" || state.status == "completed")) {
|
|
11213
|
+
const triggers = Object.keys(frame).filter((id) => isTriggerNode(target.graph.nodes[id]));
|
|
11142
11214
|
if (triggers.length != 1 || triggers[0] != triggerIds[0] || !jsonEqual(frame[triggers[0]], checkpoint.results[triggers[0]].outputs)) throw new Error("Checkpoint input Trigger does not match the Run.");
|
|
11143
11215
|
}
|
|
11144
11216
|
if (state.output != null) validateResults({ [nodeId]: state.output }, state.status == "running");
|
|
@@ -11147,9 +11219,13 @@ function validateCheckpoint(target, checkpoint, resolveInputs) {
|
|
|
11147
11219
|
if (result == null || state.jobId != null && state.jobId != result.jobId || !jsonEqual(state.output, result.outputs)) throw new Error("Checkpoint completed dependency conflicts with its result.");
|
|
11148
11220
|
}
|
|
11149
11221
|
}
|
|
11222
|
+
for (const call of checkpoint.calls ?? []) {
|
|
11223
|
+
const node = target.graph.nodes[call.nodeId];
|
|
11224
|
+
if (node?.kind != "task" || !("executor" in node.task) || node.task.executor.kind != "workflow" || !jsonEqual(resolveInputs(call.nodeId, node), call.input) || checkpoint.agents[call.jobId] != null || checkpoint.dependencies.nodes[call.nodeId]?.output != null) throw new Error("Checkpoint workflow call does not match its node.");
|
|
11225
|
+
}
|
|
11150
11226
|
for (const waiting of checkpoint.waits) {
|
|
11151
11227
|
const node = target.graph.nodes[waiting.nodeId];
|
|
11152
|
-
if (node == null ||
|
|
11228
|
+
if (node == null || isTriggerNode(node)) throw new Error("Checkpoint waiting node is missing.");
|
|
11153
11229
|
const state = checkpoint.dependencies.nodes[waiting.nodeId];
|
|
11154
11230
|
const expectedOutput = waiting.pending == null ? void 0 : { pending: waiting.pending };
|
|
11155
11231
|
if (state.output == null != (expectedOutput == null) || state.output != null && !jsonEqual(state.output, expectedOutput)) throw new Error("Checkpoint waiting dependency output is inconsistent.");
|
|
@@ -11178,7 +11254,7 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11178
11254
|
runId,
|
|
11179
11255
|
type: "run.started"
|
|
11180
11256
|
});
|
|
11181
|
-
const order = Object.keys(target.graph.nodes).filter((id) =>
|
|
11257
|
+
const order = Object.keys(target.graph.nodes).filter((id) => !isTriggerNode(target.graph.nodes[id]));
|
|
11182
11258
|
const outgoing = /* @__PURE__ */ new Map();
|
|
11183
11259
|
for (const edge of target.graph.edges) {
|
|
11184
11260
|
const targets = outgoing.get(edge.source) ?? [];
|
|
@@ -11193,10 +11269,10 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11193
11269
|
if (resume == null) {
|
|
11194
11270
|
if (trigger != null) {
|
|
11195
11271
|
const node = target.graph.nodes[trigger.nodeId];
|
|
11196
|
-
if (node == null ||
|
|
11272
|
+
if (node == null || !isTriggerNode(node) || !matchesTriggerOutputs(node, trigger.outputs)) throw new Error("Trigger outputs are invalid.");
|
|
11197
11273
|
}
|
|
11198
11274
|
for (const [id, node] of Object.entries(target.graph.nodes)) {
|
|
11199
|
-
if (
|
|
11275
|
+
if (!isTriggerNode(node)) continue;
|
|
11200
11276
|
if (trigger?.nodeId == id) completed.set(id, {
|
|
11201
11277
|
jobId: id,
|
|
11202
11278
|
outputs: trigger.outputs
|
|
@@ -11207,6 +11283,7 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11207
11283
|
const runNode = yield* FiberSet.runtime(active)();
|
|
11208
11284
|
let firstCause;
|
|
11209
11285
|
let firstFailure;
|
|
11286
|
+
const pendingCalls = new Map((resume?.checkpoint.calls ?? []).map((call) => [call.jobId, call]));
|
|
11210
11287
|
const pendingWaits = new Map((resume?.checkpoint.waits ?? []).map((wait) => [wait.jobId, wait]));
|
|
11211
11288
|
const changes = yield* Queue.unbounded();
|
|
11212
11289
|
let remainingMs = context.remainingMs;
|
|
@@ -11236,7 +11313,7 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11236
11313
|
const resolveInputs = (nodeId, node) => {
|
|
11237
11314
|
const mappings = nodeInputMappings(node);
|
|
11238
11315
|
const frame = dependencies.inputValues(nodeId);
|
|
11239
|
-
return Object.fromEntries(Object.entries(
|
|
11316
|
+
return Object.fromEntries(Object.entries(nodeInputPorts(node)).map(([handle, port]) => [handle, resolveInput(mappings[handle], port, launch[nodeId]?.[handle], `Node "${nodeId}" input "${handle}"`, frame, node.kind == "condition")]));
|
|
11240
11317
|
};
|
|
11241
11318
|
const commit = (nodeId, jobId, outputs, releasedHandles = Object.keys(outputs)) => Effect.uninterruptible(Effect.gen(function* () {
|
|
11242
11319
|
yield* context.emit({
|
|
@@ -11265,7 +11342,7 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11265
11342
|
const mapping = nodeInputMappings(node)[handle];
|
|
11266
11343
|
return mapping?.kind != "sources" || mapping.sources.every((source) => source.kind != "binding");
|
|
11267
11344
|
}));
|
|
11268
|
-
if (resolution == null) yield* context.emit({
|
|
11345
|
+
if (resolution == null && !pendingCalls.has(jobId)) yield* context.emit({
|
|
11269
11346
|
inputs: projectedInputs,
|
|
11270
11347
|
jobId,
|
|
11271
11348
|
nodeId,
|
|
@@ -11276,6 +11353,9 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11276
11353
|
});
|
|
11277
11354
|
let outputs;
|
|
11278
11355
|
switch (node.kind) {
|
|
11356
|
+
case "outputs":
|
|
11357
|
+
outputs = nodeInputs;
|
|
11358
|
+
break;
|
|
11279
11359
|
case "condition": return {
|
|
11280
11360
|
kind: "completed",
|
|
11281
11361
|
outputs: {},
|
|
@@ -11289,6 +11369,7 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11289
11369
|
const previousIds = dependencies.state.nodes[nodeId].previous;
|
|
11290
11370
|
const additional = new Set((node.additionalInputs ?? []).map((port) => port.handle));
|
|
11291
11371
|
const result = yield* context.invokeTask({
|
|
11372
|
+
...pendingCalls.has(jobId) ? { workflowRunId: pendingCalls.get(jobId).childRunId } : {},
|
|
11292
11373
|
additionalInputs: Object.fromEntries(Object.entries(nodeInputs).filter(([handle]) => additional.has(handle))),
|
|
11293
11374
|
blockId: "moduleId" in node.task ? node.task.moduleId : nodeId,
|
|
11294
11375
|
flowId: target.flowId,
|
|
@@ -11315,7 +11396,7 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11315
11396
|
const previous = target.graph.nodes[previousId];
|
|
11316
11397
|
return {
|
|
11317
11398
|
id: previousId,
|
|
11318
|
-
name: previous.name ?? (
|
|
11399
|
+
name: previous.name ?? (!isTriggerNode(previous) ? nodeTitle(previous) : void 0) ?? previousId,
|
|
11319
11400
|
outputs: frame[previousId],
|
|
11320
11401
|
outputDefs: Object.entries(nodeOutputPorts(previous)).map(([handle, definition]) => Object.assign({
|
|
11321
11402
|
handle,
|
|
@@ -11327,7 +11408,21 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11327
11408
|
}
|
|
11328
11409
|
} : { kind: "managed" }
|
|
11329
11410
|
});
|
|
11330
|
-
if (
|
|
11411
|
+
if ("executor" in node.task && node.task.executor.kind == "workflow") {
|
|
11412
|
+
const response = discriminatedUnion("kind", [strictObject({
|
|
11413
|
+
kind: literal("calling"),
|
|
11414
|
+
childRunId: string().min(1)
|
|
11415
|
+
}), strictObject({
|
|
11416
|
+
kind: literal("completed"),
|
|
11417
|
+
outputs: record$1(string(), json$1())
|
|
11418
|
+
})]).parse(result);
|
|
11419
|
+
if (response.kind == "calling") return {
|
|
11420
|
+
kind: "calling",
|
|
11421
|
+
childRunId: response.childRunId,
|
|
11422
|
+
input: nodeInputs
|
|
11423
|
+
};
|
|
11424
|
+
outputs = response.outputs;
|
|
11425
|
+
} else if (config != null) {
|
|
11331
11426
|
const response = agentResultSchema.parse(result);
|
|
11332
11427
|
if (response.kind == "suspended") {
|
|
11333
11428
|
const checkpoint = response.checkpoint;
|
|
@@ -11396,6 +11491,16 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11396
11491
|
yield* Queue.offer(changes, void 0);
|
|
11397
11492
|
});
|
|
11398
11493
|
const settleNode = (nodeId, jobId, result) => {
|
|
11494
|
+
if (result.kind == "calling") {
|
|
11495
|
+
pendingCalls.set(jobId, {
|
|
11496
|
+
jobId,
|
|
11497
|
+
nodeId,
|
|
11498
|
+
childRunId: result.childRunId,
|
|
11499
|
+
input: result.input
|
|
11500
|
+
});
|
|
11501
|
+
return Effect.void;
|
|
11502
|
+
}
|
|
11503
|
+
pendingCalls.delete(jobId);
|
|
11399
11504
|
if (result.kind == "completed") {
|
|
11400
11505
|
delete agents[jobId];
|
|
11401
11506
|
return commit(nodeId, jobId, result.outputs, result.releasedHandles);
|
|
@@ -11423,7 +11528,7 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11423
11528
|
const executeReady = (nodeId) => {
|
|
11424
11529
|
if (firstCause != null) return;
|
|
11425
11530
|
const node = target.graph.nodes[nodeId];
|
|
11426
|
-
if (
|
|
11531
|
+
if (isTriggerNode(node)) return;
|
|
11427
11532
|
const jobId = context.createId();
|
|
11428
11533
|
const count = counts[nodeId] ?? 0;
|
|
11429
11534
|
const limit = node.maxExecutions ?? 1e3;
|
|
@@ -11511,18 +11616,22 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11511
11616
|
return yield* Effect.failCause(firstCause);
|
|
11512
11617
|
}
|
|
11513
11618
|
if (pendingWaits.size > 0 && context.waits != null) applyResolutions(yield* context.waits.resolutions([...pendingWaits.values()].map((wait) => wait.waitId), false), now);
|
|
11619
|
+
for (const call of pendingCalls.values()) yield* observe(call.nodeId, call.jobId, Effect.gen(function* () {
|
|
11620
|
+
const result = yield* executeNode(call.nodeId, target.graph.nodes[call.nodeId], call.jobId, call.input);
|
|
11621
|
+
yield* settleNode(call.nodeId, call.jobId, result);
|
|
11622
|
+
})).pipe(Effect.catch(() => Effect.void));
|
|
11514
11623
|
const ready = dependencies.ready();
|
|
11515
11624
|
for (const nodeId of ready) executeReady(nodeId);
|
|
11516
11625
|
const running = yield* FiberSet.size(active);
|
|
11517
11626
|
if (firstCause != null) continue;
|
|
11518
|
-
if (running == 0 && pendingWaits.size == 0 && ready.length == 0) {
|
|
11627
|
+
if (running == 0 && pendingWaits.size == 0 && pendingCalls.size == 0 && ready.length == 0) {
|
|
11519
11628
|
if (dependencies.incomplete) return yield* Effect.fail(/* @__PURE__ */ new Error("Execution graph contains unresolved dependencies."));
|
|
11520
11629
|
break;
|
|
11521
11630
|
}
|
|
11522
11631
|
if (running > 0 || ready.length > 0) idleSince = void 0;
|
|
11523
11632
|
else idleSince ??= now;
|
|
11524
11633
|
const left = idleSince == null ? remainingMs : waitRetentionMs - (now - idleSince);
|
|
11525
|
-
if (idleSince != null && left <= 0) {
|
|
11634
|
+
if (idleSince != null && (left <= 0 || pendingCalls.size > 0)) {
|
|
11526
11635
|
const checkpoint = {
|
|
11527
11636
|
bindingValues: context.bindingValues,
|
|
11528
11637
|
inputs: launch,
|
|
@@ -11531,7 +11640,8 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11531
11640
|
dependencies: dependencies.state,
|
|
11532
11641
|
version: 5,
|
|
11533
11642
|
agents,
|
|
11534
|
-
waits: [...pendingWaits.values()]
|
|
11643
|
+
waits: [...pendingWaits.values()],
|
|
11644
|
+
...pendingCalls.size == 0 ? {} : { calls: [...pendingCalls.values()] }
|
|
11535
11645
|
};
|
|
11536
11646
|
const encoded = JSON.stringify(checkpoint);
|
|
11537
11647
|
if (new TextEncoder().encode(encoded).byteLength > 16777216) return yield* Effect.fail(/* @__PURE__ */ new Error("Flow Run checkpoint exceeds 16 MiB."));
|
|
@@ -11544,6 +11654,7 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11544
11654
|
const activity = Queue.take(changes).pipe(Effect.as({}));
|
|
11545
11655
|
const decision = pendingWaits.size == 0 || context.waits == null ? Effect.never : context.waits.resolutions([...pendingWaits.values()].map((wait) => wait.waitId), true);
|
|
11546
11656
|
let next = Effect.raceFirst(activity, decision);
|
|
11657
|
+
if (pendingCalls.size > 0) next = Effect.raceFirst(next, Effect.sleep(1e3).pipe(Effect.as({})));
|
|
11547
11658
|
if (left != null) next = Effect.raceFirst(next, Effect.sleep(Math.max(0, left)).pipe(Effect.as({})));
|
|
11548
11659
|
applyResolutions(yield* next, yield* Clock.currentTimeMillis);
|
|
11549
11660
|
}
|
|
@@ -11552,8 +11663,11 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11552
11663
|
runId,
|
|
11553
11664
|
type: "run.progress"
|
|
11554
11665
|
});
|
|
11666
|
+
const outputNodeId = order.find((nodeId) => target.graph.nodes[nodeId]?.kind == "outputs");
|
|
11667
|
+
const businessOutputs = outputNodeId == null ? void 0 : completed.get(outputNodeId)?.outputs;
|
|
11555
11668
|
const result = {
|
|
11556
11669
|
kind: "node-results",
|
|
11670
|
+
...businessOutputs == null ? {} : { outputs: businessOutputs },
|
|
11557
11671
|
nodes: resultNodes.flatMap((nodeId) => {
|
|
11558
11672
|
const saved = completed.get(nodeId);
|
|
11559
11673
|
return saved == null ? [] : [{
|
|
@@ -11603,7 +11717,13 @@ function runFlow(prepared, options) {
|
|
|
11603
11717
|
if (checkpoint != null && new TextEncoder().encode(JSON.stringify(checkpoint)).byteLength > 16777216) return yield* Effect.fail(/* @__PURE__ */ new Error("Flow Run checkpoint exceeds 16 MiB."));
|
|
11604
11718
|
if (checkpoint == null && options.trigger == null) return yield* Effect.fail(/* @__PURE__ */ new Error("A Flow Run requires a Trigger seed."));
|
|
11605
11719
|
const triggerNode = options.trigger == null ? void 0 : prepared.graph.nodes[options.trigger.nodeId];
|
|
11606
|
-
if (options.trigger != null && (triggerNode == null ||
|
|
11720
|
+
if (options.trigger != null && (triggerNode == null || !isTriggerNode(triggerNode))) return yield* Effect.fail(/* @__PURE__ */ new Error(`Node "${options.trigger.nodeId}" is not a TriggerNode in Flow "${options.flowId}".`));
|
|
11721
|
+
const triggerOutputs = triggerNode == null || !isTriggerNode(triggerNode) ? void 0 : normalizeTriggerOutputs(triggerNode, options.trigger.outputs);
|
|
11722
|
+
if (options.trigger != null && triggerOutputs == null) return yield* Effect.fail(/* @__PURE__ */ new Error("Trigger outputs are invalid."));
|
|
11723
|
+
const trigger = options.trigger == null ? void 0 : {
|
|
11724
|
+
nodeId: options.trigger.nodeId,
|
|
11725
|
+
outputs: triggerOutputs
|
|
11726
|
+
};
|
|
11607
11727
|
return yield* runGraph({
|
|
11608
11728
|
failures: /* @__PURE__ */ new WeakMap(),
|
|
11609
11729
|
counts: Object.fromEntries(Object.entries(checkpoint?.counts ?? {}).map(([scope, counts]) => [scope, { ...counts }])),
|
|
@@ -11617,8 +11737,11 @@ function runFlow(prepared, options) {
|
|
|
11617
11737
|
remainingMs: options.remainingMs
|
|
11618
11738
|
}, {
|
|
11619
11739
|
flowId: options.flowId,
|
|
11620
|
-
graph: prepared.graph
|
|
11621
|
-
|
|
11740
|
+
graph: prepared.graph,
|
|
11741
|
+
inputDefs: prepared.inputDefs,
|
|
11742
|
+
outputDefs: prepared.outputDefs,
|
|
11743
|
+
outputMappings: prepared.outputMappings
|
|
11744
|
+
}, options.runId, options.inputs, trigger, checkpoint == null ? void 0 : { checkpoint });
|
|
11622
11745
|
});
|
|
11623
11746
|
}
|
|
11624
11747
|
//#endregion
|
|
@@ -7,3 +7,5 @@ export declare const webhookOutputs: readonly Port[];
|
|
|
7
7
|
export declare function triggerOutputDefinitions(trigger: TriggerNode): readonly Port[];
|
|
8
8
|
export declare function triggerOutputPorts(trigger: TriggerNode): Readonly<Record<string, PortDefinition>>;
|
|
9
9
|
export declare function matchesTriggerOutputs(trigger: TriggerNode, outputs: unknown): outputs is Readonly<Record<string, JsonValue>>;
|
|
10
|
+
/** Resolve caller-supplied Start parameters into the complete output snapshot used by execution. */
|
|
11
|
+
export declare function normalizeTriggerOutputs(trigger: TriggerNode, outputs: unknown): Readonly<Record<string, JsonValue>> | undefined;
|