@oomol-lab/open-flow 0.1.0-beta.71 → 0.1.0-beta.72
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/{flowChanges-9Ir2rdLx.js → flowChanges-CgSnSqqP.js} +1007 -997
- package/dist/browser/{flowWorkspace-LvZ6HuMM.js → flowWorkspace-Bf7H-r0t.js} +1 -1
- package/dist/browser/preview.js +1007 -997
- package/dist/browser/workbench.js +2 -2
- package/dist/command/index.js +1 -1
- package/dist/common/scheduler-checkpoint.d.ts +42 -0
- package/dist/common/scheduler-dependencies.d.ts +80 -0
- package/dist/common/scheduler-node-execution.d.ts +75 -0
- package/dist/common/scheduler.d.ts +5 -58
- package/dist/common/scheduler.js +575 -471
- package/package.json +1 -1
package/dist/common/scheduler.js
CHANGED
|
@@ -14,6 +14,37 @@ var nanoid$1 = (size = 21) => {
|
|
|
14
14
|
return id;
|
|
15
15
|
};
|
|
16
16
|
//#endregion
|
|
17
|
+
//#region src/flow/common/inputValue.ts
|
|
18
|
+
/** An explicit clear suppresses the default; absent mappings still inherit it. */
|
|
19
|
+
function inputValue(mapping, fallback) {
|
|
20
|
+
if (mapping?.kind === "unset") return void 0;
|
|
21
|
+
return mapping?.kind === "value" ? mapping.value : fallback;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region ../../node_modules/.bun/dequal@2.0.3/node_modules/dequal/lite/index.mjs
|
|
25
|
+
var has = Object.prototype.hasOwnProperty;
|
|
26
|
+
function dequal(foo, bar) {
|
|
27
|
+
var ctor, len;
|
|
28
|
+
if (foo === bar) return true;
|
|
29
|
+
if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
|
|
30
|
+
if (ctor === Date) return foo.getTime() === bar.getTime();
|
|
31
|
+
if (ctor === RegExp) return foo.toString() === bar.toString();
|
|
32
|
+
if (ctor === Array) {
|
|
33
|
+
if ((len = foo.length) === bar.length) while (len-- && dequal(foo[len], bar[len]));
|
|
34
|
+
return len === -1;
|
|
35
|
+
}
|
|
36
|
+
if (!ctor || typeof foo === "object") {
|
|
37
|
+
len = 0;
|
|
38
|
+
for (ctor in foo) {
|
|
39
|
+
if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;
|
|
40
|
+
if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false;
|
|
41
|
+
}
|
|
42
|
+
return Object.keys(bar).length === len;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return foo !== foo && bar !== bar;
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
17
48
|
//#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/core/util.js
|
|
18
49
|
function getEnumValues(entries) {
|
|
19
50
|
const numericValues = Object.values(entries).filter((v) => typeof v === "number");
|
|
@@ -6568,37 +6599,6 @@ var Validator = class {
|
|
|
6568
6599
|
}
|
|
6569
6600
|
};
|
|
6570
6601
|
//#endregion
|
|
6571
|
-
//#region src/flow/common/inputValue.ts
|
|
6572
|
-
/** An explicit clear suppresses the default; absent mappings still inherit it. */
|
|
6573
|
-
function inputValue(mapping, fallback) {
|
|
6574
|
-
if (mapping?.kind === "unset") return void 0;
|
|
6575
|
-
return mapping?.kind === "value" ? mapping.value : fallback;
|
|
6576
|
-
}
|
|
6577
|
-
//#endregion
|
|
6578
|
-
//#region ../../node_modules/.bun/dequal@2.0.3/node_modules/dequal/lite/index.mjs
|
|
6579
|
-
var has = Object.prototype.hasOwnProperty;
|
|
6580
|
-
function dequal(foo, bar) {
|
|
6581
|
-
var ctor, len;
|
|
6582
|
-
if (foo === bar) return true;
|
|
6583
|
-
if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
|
|
6584
|
-
if (ctor === Date) return foo.getTime() === bar.getTime();
|
|
6585
|
-
if (ctor === RegExp) return foo.toString() === bar.toString();
|
|
6586
|
-
if (ctor === Array) {
|
|
6587
|
-
if ((len = foo.length) === bar.length) while (len-- && dequal(foo[len], bar[len]));
|
|
6588
|
-
return len === -1;
|
|
6589
|
-
}
|
|
6590
|
-
if (!ctor || typeof foo === "object") {
|
|
6591
|
-
len = 0;
|
|
6592
|
-
for (ctor in foo) {
|
|
6593
|
-
if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;
|
|
6594
|
-
if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false;
|
|
6595
|
-
}
|
|
6596
|
-
return Object.keys(bar).length === len;
|
|
6597
|
-
}
|
|
6598
|
-
}
|
|
6599
|
-
return foo !== foo && bar !== bar;
|
|
6600
|
-
}
|
|
6601
|
-
//#endregion
|
|
6602
6602
|
//#region src/json-schema-subset/utils.ts
|
|
6603
6603
|
var nextId = 0;
|
|
6604
6604
|
function createId() {
|
|
@@ -10492,100 +10492,6 @@ function isTriggerNode(node) {
|
|
|
10492
10492
|
].includes(node.kind);
|
|
10493
10493
|
}
|
|
10494
10494
|
//#endregion
|
|
10495
|
-
//#region src/flow/common/agent.ts
|
|
10496
|
-
var schema = lazy(() => union([boolean(), strictObject({
|
|
10497
|
-
type: union([_enum([
|
|
10498
|
-
"array",
|
|
10499
|
-
"boolean",
|
|
10500
|
-
"integer",
|
|
10501
|
-
"null",
|
|
10502
|
-
"number",
|
|
10503
|
-
"object",
|
|
10504
|
-
"string"
|
|
10505
|
-
]), array(_enum([
|
|
10506
|
-
"array",
|
|
10507
|
-
"boolean",
|
|
10508
|
-
"integer",
|
|
10509
|
-
"null",
|
|
10510
|
-
"number",
|
|
10511
|
-
"object",
|
|
10512
|
-
"string"
|
|
10513
|
-
])).min(1)]).optional(),
|
|
10514
|
-
const: json$1().optional(),
|
|
10515
|
-
allOf: array(schema).min(1).optional(),
|
|
10516
|
-
anyOf: array(schema).min(1).optional(),
|
|
10517
|
-
oneOf: array(schema).min(1).optional(),
|
|
10518
|
-
not: schema.optional(),
|
|
10519
|
-
if: schema.optional(),
|
|
10520
|
-
then: schema.optional(),
|
|
10521
|
-
else: schema.optional(),
|
|
10522
|
-
$ref: string$1().optional(),
|
|
10523
|
-
$schema: _enum([
|
|
10524
|
-
"http://json-schema.org/draft-07/schema#",
|
|
10525
|
-
"https://json-schema.org/draft-07/schema",
|
|
10526
|
-
"https://json-schema.org/draft/2019-09/schema",
|
|
10527
|
-
"https://json-schema.org/draft/2020-12/schema"
|
|
10528
|
-
]).optional(),
|
|
10529
|
-
$defs: record$1(string$1(), schema).optional(),
|
|
10530
|
-
definitions: record$1(string$1(), schema).optional(),
|
|
10531
|
-
pattern: string$1().refine((value) => {
|
|
10532
|
-
try {
|
|
10533
|
-
return new RegExp(value, "u").source.length > 0;
|
|
10534
|
-
} catch {
|
|
10535
|
-
return false;
|
|
10536
|
-
}
|
|
10537
|
-
}, "Invalid regular expression.").optional(),
|
|
10538
|
-
format: string$1().refine((value) => Object.hasOwn(format, value), "Unsupported string format.").optional(),
|
|
10539
|
-
multipleOf: number().positive().optional(),
|
|
10540
|
-
uniqueItems: boolean().optional(),
|
|
10541
|
-
contains: schema.optional(),
|
|
10542
|
-
minContains: number().int().nonnegative().optional(),
|
|
10543
|
-
maxContains: number().int().nonnegative().optional(),
|
|
10544
|
-
minProperties: number().int().nonnegative().optional(),
|
|
10545
|
-
maxProperties: number().int().nonnegative().optional(),
|
|
10546
|
-
propertyNames: schema.optional(),
|
|
10547
|
-
patternProperties: record$1(string$1().refine((value) => {
|
|
10548
|
-
try {
|
|
10549
|
-
return new RegExp(value, "u").source.length > 0;
|
|
10550
|
-
} catch {
|
|
10551
|
-
return false;
|
|
10552
|
-
}
|
|
10553
|
-
}, "Invalid regular expression."), schema).optional(),
|
|
10554
|
-
dependentRequired: record$1(string$1(), array(string$1())).optional(),
|
|
10555
|
-
dependentSchemas: record$1(string$1(), schema).optional(),
|
|
10556
|
-
dependencies: record$1(string$1(), union([schema, array(string$1())])).optional(),
|
|
10557
|
-
prefixItems: array(schema).optional(),
|
|
10558
|
-
additionalItems: schema.optional(),
|
|
10559
|
-
unevaluatedItems: schema.optional(),
|
|
10560
|
-
unevaluatedProperties: schema.optional(),
|
|
10561
|
-
description: string$1().optional(),
|
|
10562
|
-
title: string$1().optional(),
|
|
10563
|
-
default: json$1().optional(),
|
|
10564
|
-
examples: array(json$1()).optional(),
|
|
10565
|
-
readOnly: boolean().optional(),
|
|
10566
|
-
writeOnly: boolean().optional(),
|
|
10567
|
-
deprecated: boolean().optional(),
|
|
10568
|
-
$comment: string$1().optional(),
|
|
10569
|
-
enum: array(json$1()).min(1).optional(),
|
|
10570
|
-
properties: record$1(string$1(), schema).optional(),
|
|
10571
|
-
required: array(string$1()).optional(),
|
|
10572
|
-
additionalProperties: schema.optional(),
|
|
10573
|
-
items: union([schema, array(schema)]).optional(),
|
|
10574
|
-
minItems: number().int().nonnegative().optional(),
|
|
10575
|
-
maxItems: number().int().nonnegative().optional(),
|
|
10576
|
-
minLength: number().int().nonnegative().optional(),
|
|
10577
|
-
maxLength: number().int().nonnegative().optional(),
|
|
10578
|
-
minimum: number().optional(),
|
|
10579
|
-
maximum: number().optional(),
|
|
10580
|
-
exclusiveMinimum: number().optional(),
|
|
10581
|
-
exclusiveMaximum: number().optional()
|
|
10582
|
-
}).transform(({ title: _title, default: _default, examples: _examples, readOnly: _readOnly, writeOnly: _writeOnly, deprecated: _deprecated, $comment: _comment, ...value }) => value)]));
|
|
10583
|
-
function agentInput(source, input) {
|
|
10584
|
-
if (source.kind == "value") return source.value;
|
|
10585
|
-
if (!Object.hasOwn(input, source.input)) throw new Error(`Agent input ${source.input} is missing.`);
|
|
10586
|
-
return input[source.input];
|
|
10587
|
-
}
|
|
10588
|
-
//#endregion
|
|
10589
10495
|
//#region src/base/common/json.ts
|
|
10590
10496
|
function hasJsonShape(root) {
|
|
10591
10497
|
if (root === null || typeof root == "boolean" || typeof root == "string") return true;
|
|
@@ -10914,6 +10820,8 @@ var Dependencies = class {
|
|
|
10914
10820
|
this.loops = /* @__PURE__ */ new Map();
|
|
10915
10821
|
this.outgoing = /* @__PURE__ */ new Map();
|
|
10916
10822
|
this.incoming = /* @__PURE__ */ new Map();
|
|
10823
|
+
this.candidates = /* @__PURE__ */ new Set();
|
|
10824
|
+
this.frames = /* @__PURE__ */ new Map();
|
|
10917
10825
|
this.graph = graph;
|
|
10918
10826
|
const feedback = /* @__PURE__ */ new Map();
|
|
10919
10827
|
const visited = /* @__PURE__ */ new Set();
|
|
@@ -10982,6 +10890,10 @@ var Dependencies = class {
|
|
|
10982
10890
|
} : structuredClone(saved);
|
|
10983
10891
|
if (saved == null) for (const id of ids) this.state.nodes[id] = this.fresh();
|
|
10984
10892
|
else this.validate();
|
|
10893
|
+
for (const id of ids) {
|
|
10894
|
+
if (this.state.nodes[id].status == "pending") this.candidates.add(id);
|
|
10895
|
+
this.frames.set(id, { values: this.state.nodes[id].input });
|
|
10896
|
+
}
|
|
10985
10897
|
}
|
|
10986
10898
|
fresh() {
|
|
10987
10899
|
return {
|
|
@@ -11031,12 +10943,59 @@ var Dependencies = class {
|
|
|
11031
10943
|
if (source.status != "completed") return "pending";
|
|
11032
10944
|
return edge.sourceHandle == null ? "selected" : "skipped";
|
|
11033
10945
|
}
|
|
10946
|
+
edgeResult(edge) {
|
|
10947
|
+
const source = this.state.nodes[edge.source];
|
|
10948
|
+
const outputs = edge.sourceHandle != null && this.graph.nodes[edge.source].kind != "condition" ? Object.fromEntries(Object.entries(source.output).filter(([handle]) => handle == edge.sourceHandle)) : source.output;
|
|
10949
|
+
return {
|
|
10950
|
+
execution: source.id,
|
|
10951
|
+
outputs,
|
|
10952
|
+
...source.systemOutputs == null ? {} : { systemOutputs: source.systemOutputs }
|
|
10953
|
+
};
|
|
10954
|
+
}
|
|
10955
|
+
input(nodeId, sourceId) {
|
|
10956
|
+
if (this.loops.size != 0) return this.state.nodes[nodeId].input[sourceId];
|
|
10957
|
+
let frame = this.frames.get(nodeId);
|
|
10958
|
+
const visited = [];
|
|
10959
|
+
let result;
|
|
10960
|
+
for (;;) {
|
|
10961
|
+
if (!("source" in frame) || frame.values != null) {
|
|
10962
|
+
result = frame.values[sourceId];
|
|
10963
|
+
break;
|
|
10964
|
+
}
|
|
10965
|
+
if (frame.source == sourceId) {
|
|
10966
|
+
result = frame.result;
|
|
10967
|
+
break;
|
|
10968
|
+
}
|
|
10969
|
+
if (frame.cache.has(sourceId)) {
|
|
10970
|
+
result = frame.cache.get(sourceId);
|
|
10971
|
+
break;
|
|
10972
|
+
}
|
|
10973
|
+
visited.push(frame);
|
|
10974
|
+
frame = frame.parent;
|
|
10975
|
+
}
|
|
10976
|
+
for (const ancestor of visited) ancestor.cache.set(sourceId, result);
|
|
10977
|
+
return result;
|
|
10978
|
+
}
|
|
10979
|
+
snapshot(frame) {
|
|
10980
|
+
const pending = [];
|
|
10981
|
+
while ("source" in frame && frame.values == null) {
|
|
10982
|
+
pending.push(frame);
|
|
10983
|
+
frame = frame.parent;
|
|
10984
|
+
}
|
|
10985
|
+
let values = frame.values;
|
|
10986
|
+
for (const current of pending.toReversed()) {
|
|
10987
|
+
values = Object.assign({}, values, { [current.source]: current.result });
|
|
10988
|
+
current.values = values;
|
|
10989
|
+
current.cache.clear();
|
|
10990
|
+
}
|
|
10991
|
+
return values;
|
|
10992
|
+
}
|
|
11034
10993
|
collectInputs(edges) {
|
|
11035
10994
|
const input = {};
|
|
11036
10995
|
const merge = (id, result) => {
|
|
11037
10996
|
const previous = input[id];
|
|
11038
10997
|
if (previous == null || result.execution > previous.execution) input[id] = result;
|
|
11039
|
-
else if (result.execution == previous.execution) input[id] = {
|
|
10998
|
+
else if (result !== previous && result.execution == previous.execution) input[id] = {
|
|
11040
10999
|
execution: result.execution,
|
|
11041
11000
|
outputs: {
|
|
11042
11001
|
...previous.outputs,
|
|
@@ -11050,23 +11009,12 @@ var Dependencies = class {
|
|
|
11050
11009
|
};
|
|
11051
11010
|
for (const edge of edges) {
|
|
11052
11011
|
const source = this.state.nodes[edge.source];
|
|
11053
|
-
for (const
|
|
11054
|
-
|
|
11055
|
-
merge(edge.source, {
|
|
11056
|
-
execution: source.id,
|
|
11057
|
-
outputs,
|
|
11058
|
-
...source.systemOutputs == null ? {} : { systemOutputs: source.systemOutputs }
|
|
11059
|
-
});
|
|
11012
|
+
for (const id in source.input) merge(id, source.input[id]);
|
|
11013
|
+
merge(edge.source, this.edgeResult(edge));
|
|
11060
11014
|
}
|
|
11061
11015
|
for (const id of Object.keys(input)) if (this.state.nodes[id].status == "skipped") delete input[id];
|
|
11062
11016
|
return input;
|
|
11063
11017
|
}
|
|
11064
|
-
systemInputValues(nodeId) {
|
|
11065
|
-
return Object.fromEntries(Object.entries(this.state.nodes[nodeId].input).flatMap(([id, value]) => value.systemOutputs == null ? [] : [[id, value.systemOutputs]]));
|
|
11066
|
-
}
|
|
11067
|
-
inputValues(nodeId) {
|
|
11068
|
-
return dependencyValues(this.state.nodes[nodeId].input);
|
|
11069
|
-
}
|
|
11070
11018
|
loopSettled(loop) {
|
|
11071
11019
|
return [...loop.body].every((id) => {
|
|
11072
11020
|
const state = this.state.nodes[id];
|
|
@@ -11108,8 +11056,52 @@ var Dependencies = class {
|
|
|
11108
11056
|
if (edges.some((edge) => this.edge(edge) == "pending" || this.blockedByLoop(edge))) return void 0;
|
|
11109
11057
|
return edges.filter((edge) => this.edge(edge) == "selected");
|
|
11110
11058
|
}
|
|
11059
|
+
readyAcyclic() {
|
|
11060
|
+
const ready = /* @__PURE__ */ new Set();
|
|
11061
|
+
for (const id of this.candidates) {
|
|
11062
|
+
this.candidates.delete(id);
|
|
11063
|
+
const state = this.state.nodes[id];
|
|
11064
|
+
if (state.status != "pending") continue;
|
|
11065
|
+
const selected = this.selectedIncoming(id);
|
|
11066
|
+
if (selected == null) continue;
|
|
11067
|
+
if (selected.length == 0) {
|
|
11068
|
+
state.status = "skipped";
|
|
11069
|
+
for (const edge of this.outgoing.get(id) ?? []) this.candidates.add(edge.target);
|
|
11070
|
+
} else {
|
|
11071
|
+
if (selected.length == 1) {
|
|
11072
|
+
const edge = selected[0];
|
|
11073
|
+
const frame = {
|
|
11074
|
+
source: edge.source,
|
|
11075
|
+
result: this.edgeResult(edge),
|
|
11076
|
+
parent: this.frames.get(edge.source),
|
|
11077
|
+
cache: /* @__PURE__ */ new Map()
|
|
11078
|
+
};
|
|
11079
|
+
this.frames.set(id, frame);
|
|
11080
|
+
Object.defineProperty(state, "input", {
|
|
11081
|
+
configurable: true,
|
|
11082
|
+
enumerable: true,
|
|
11083
|
+
get: () => this.snapshot(frame)
|
|
11084
|
+
});
|
|
11085
|
+
} else {
|
|
11086
|
+
const input = this.collectInputs(selected);
|
|
11087
|
+
Object.defineProperty(state, "input", {
|
|
11088
|
+
configurable: true,
|
|
11089
|
+
enumerable: true,
|
|
11090
|
+
writable: true,
|
|
11091
|
+
value: input
|
|
11092
|
+
});
|
|
11093
|
+
this.frames.set(id, { values: input });
|
|
11094
|
+
}
|
|
11095
|
+
state.previous = [...new Set(selected.map((edge) => edge.source))].toSorted();
|
|
11096
|
+
ready.add(id);
|
|
11097
|
+
}
|
|
11098
|
+
}
|
|
11099
|
+
for (const id of ready) this.candidates.add(id);
|
|
11100
|
+
return [...ready].toSorted();
|
|
11101
|
+
}
|
|
11111
11102
|
/** Resolve skips and iteration boundaries before admitting another invocation. */
|
|
11112
11103
|
ready() {
|
|
11104
|
+
if (this.loops.size == 0) return this.readyAcyclic();
|
|
11113
11105
|
let changed = true;
|
|
11114
11106
|
while (changed) {
|
|
11115
11107
|
changed = false;
|
|
@@ -11153,6 +11145,7 @@ var Dependencies = class {
|
|
|
11153
11145
|
const state = this.state.nodes[nodeId];
|
|
11154
11146
|
state.status = "running";
|
|
11155
11147
|
state.jobId = jobId;
|
|
11148
|
+
this.candidates.delete(nodeId);
|
|
11156
11149
|
}
|
|
11157
11150
|
release(nodeId, outputs, handles, complete, systemOutputs) {
|
|
11158
11151
|
const state = this.state.nodes[nodeId];
|
|
@@ -11160,76 +11153,120 @@ var Dependencies = class {
|
|
|
11160
11153
|
state.systemOutputs = systemOutputs;
|
|
11161
11154
|
state.released = [.../* @__PURE__ */ new Set([...state.released, ...handles])];
|
|
11162
11155
|
if (complete) state.status = "completed";
|
|
11156
|
+
if (this.loops.size == 0) for (const edge of this.outgoing.get(nodeId) ?? []) this.candidates.add(edge.target);
|
|
11163
11157
|
}
|
|
11164
11158
|
get incomplete() {
|
|
11165
11159
|
return Object.values(this.state.nodes).some((state) => state.status == "pending" || state.status == "running");
|
|
11166
11160
|
}
|
|
11167
11161
|
};
|
|
11168
11162
|
//#endregion
|
|
11169
|
-
//#region src/
|
|
11170
|
-
var
|
|
11171
|
-
|
|
11172
|
-
|
|
11173
|
-
|
|
11174
|
-
|
|
11175
|
-
|
|
11176
|
-
|
|
11177
|
-
|
|
11178
|
-
|
|
11179
|
-
|
|
11180
|
-
|
|
11181
|
-
|
|
11182
|
-
|
|
11183
|
-
|
|
11184
|
-
|
|
11185
|
-
|
|
11186
|
-
|
|
11187
|
-
|
|
11188
|
-
|
|
11189
|
-
|
|
11190
|
-
|
|
11191
|
-
|
|
11192
|
-
|
|
11193
|
-
|
|
11194
|
-
|
|
11195
|
-
|
|
11196
|
-
|
|
11197
|
-
|
|
11198
|
-
|
|
11199
|
-
|
|
11200
|
-
|
|
11201
|
-
|
|
11202
|
-
|
|
11203
|
-
|
|
11204
|
-
|
|
11205
|
-
|
|
11206
|
-
|
|
11207
|
-
|
|
11208
|
-
|
|
11209
|
-
|
|
11210
|
-
|
|
11211
|
-
|
|
11212
|
-
|
|
11213
|
-
|
|
11214
|
-
|
|
11215
|
-
|
|
11216
|
-
|
|
11217
|
-
|
|
11218
|
-
|
|
11219
|
-
|
|
11220
|
-
|
|
11221
|
-
|
|
11222
|
-
|
|
11223
|
-
|
|
11224
|
-
|
|
11225
|
-
|
|
11226
|
-
|
|
11227
|
-
|
|
11228
|
-
|
|
11229
|
-
|
|
11230
|
-
|
|
11231
|
-
|
|
11232
|
-
|
|
11163
|
+
//#region src/flow/common/agent.ts
|
|
11164
|
+
var schema = lazy(() => union([boolean(), strictObject({
|
|
11165
|
+
type: union([_enum([
|
|
11166
|
+
"array",
|
|
11167
|
+
"boolean",
|
|
11168
|
+
"integer",
|
|
11169
|
+
"null",
|
|
11170
|
+
"number",
|
|
11171
|
+
"object",
|
|
11172
|
+
"string"
|
|
11173
|
+
]), array(_enum([
|
|
11174
|
+
"array",
|
|
11175
|
+
"boolean",
|
|
11176
|
+
"integer",
|
|
11177
|
+
"null",
|
|
11178
|
+
"number",
|
|
11179
|
+
"object",
|
|
11180
|
+
"string"
|
|
11181
|
+
])).min(1)]).optional(),
|
|
11182
|
+
const: json$1().optional(),
|
|
11183
|
+
allOf: array(schema).min(1).optional(),
|
|
11184
|
+
anyOf: array(schema).min(1).optional(),
|
|
11185
|
+
oneOf: array(schema).min(1).optional(),
|
|
11186
|
+
not: schema.optional(),
|
|
11187
|
+
if: schema.optional(),
|
|
11188
|
+
then: schema.optional(),
|
|
11189
|
+
else: schema.optional(),
|
|
11190
|
+
$ref: string$1().optional(),
|
|
11191
|
+
$schema: _enum([
|
|
11192
|
+
"http://json-schema.org/draft-07/schema#",
|
|
11193
|
+
"https://json-schema.org/draft-07/schema",
|
|
11194
|
+
"https://json-schema.org/draft/2019-09/schema",
|
|
11195
|
+
"https://json-schema.org/draft/2020-12/schema"
|
|
11196
|
+
]).optional(),
|
|
11197
|
+
$defs: record$1(string$1(), schema).optional(),
|
|
11198
|
+
definitions: record$1(string$1(), schema).optional(),
|
|
11199
|
+
pattern: string$1().refine((value) => {
|
|
11200
|
+
try {
|
|
11201
|
+
return new RegExp(value, "u").source.length > 0;
|
|
11202
|
+
} catch {
|
|
11203
|
+
return false;
|
|
11204
|
+
}
|
|
11205
|
+
}, "Invalid regular expression.").optional(),
|
|
11206
|
+
format: string$1().refine((value) => Object.hasOwn(format, value), "Unsupported string format.").optional(),
|
|
11207
|
+
multipleOf: number().positive().optional(),
|
|
11208
|
+
uniqueItems: boolean().optional(),
|
|
11209
|
+
contains: schema.optional(),
|
|
11210
|
+
minContains: number().int().nonnegative().optional(),
|
|
11211
|
+
maxContains: number().int().nonnegative().optional(),
|
|
11212
|
+
minProperties: number().int().nonnegative().optional(),
|
|
11213
|
+
maxProperties: number().int().nonnegative().optional(),
|
|
11214
|
+
propertyNames: schema.optional(),
|
|
11215
|
+
patternProperties: record$1(string$1().refine((value) => {
|
|
11216
|
+
try {
|
|
11217
|
+
return new RegExp(value, "u").source.length > 0;
|
|
11218
|
+
} catch {
|
|
11219
|
+
return false;
|
|
11220
|
+
}
|
|
11221
|
+
}, "Invalid regular expression."), schema).optional(),
|
|
11222
|
+
dependentRequired: record$1(string$1(), array(string$1())).optional(),
|
|
11223
|
+
dependentSchemas: record$1(string$1(), schema).optional(),
|
|
11224
|
+
dependencies: record$1(string$1(), union([schema, array(string$1())])).optional(),
|
|
11225
|
+
prefixItems: array(schema).optional(),
|
|
11226
|
+
additionalItems: schema.optional(),
|
|
11227
|
+
unevaluatedItems: schema.optional(),
|
|
11228
|
+
unevaluatedProperties: schema.optional(),
|
|
11229
|
+
description: string$1().optional(),
|
|
11230
|
+
title: string$1().optional(),
|
|
11231
|
+
default: json$1().optional(),
|
|
11232
|
+
examples: array(json$1()).optional(),
|
|
11233
|
+
readOnly: boolean().optional(),
|
|
11234
|
+
writeOnly: boolean().optional(),
|
|
11235
|
+
deprecated: boolean().optional(),
|
|
11236
|
+
$comment: string$1().optional(),
|
|
11237
|
+
enum: array(json$1()).min(1).optional(),
|
|
11238
|
+
properties: record$1(string$1(), schema).optional(),
|
|
11239
|
+
required: array(string$1()).optional(),
|
|
11240
|
+
additionalProperties: schema.optional(),
|
|
11241
|
+
items: union([schema, array(schema)]).optional(),
|
|
11242
|
+
minItems: number().int().nonnegative().optional(),
|
|
11243
|
+
maxItems: number().int().nonnegative().optional(),
|
|
11244
|
+
minLength: number().int().nonnegative().optional(),
|
|
11245
|
+
maxLength: number().int().nonnegative().optional(),
|
|
11246
|
+
minimum: number().optional(),
|
|
11247
|
+
maximum: number().optional(),
|
|
11248
|
+
exclusiveMinimum: number().optional(),
|
|
11249
|
+
exclusiveMaximum: number().optional()
|
|
11250
|
+
}).transform(({ title: _title, default: _default, examples: _examples, readOnly: _readOnly, writeOnly: _writeOnly, deprecated: _deprecated, $comment: _comment, ...value }) => value)]));
|
|
11251
|
+
function agentInput(source, input) {
|
|
11252
|
+
if (source.kind == "value") return source.value;
|
|
11253
|
+
if (!Object.hasOwn(input, source.input)) throw new Error(`Agent input ${source.input} is missing.`);
|
|
11254
|
+
return input[source.input];
|
|
11255
|
+
}
|
|
11256
|
+
//#endregion
|
|
11257
|
+
//#region src/execution/common/node-execution.ts
|
|
11258
|
+
var PortValidationError = class extends Error {};
|
|
11259
|
+
function usesPending(graph, nodeId) {
|
|
11260
|
+
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")));
|
|
11261
|
+
}
|
|
11262
|
+
var NodeValidationError = class extends PortValidationError {
|
|
11263
|
+
constructor(code, error) {
|
|
11264
|
+
super(error instanceof Error ? error.message : String(error));
|
|
11265
|
+
this.code = code;
|
|
11266
|
+
}
|
|
11267
|
+
};
|
|
11268
|
+
function nodeFailure(error, project) {
|
|
11269
|
+
if (error instanceof NodeValidationError) return {
|
|
11233
11270
|
code: error.code,
|
|
11234
11271
|
message: error.message,
|
|
11235
11272
|
catchable: true
|
|
@@ -11277,25 +11314,13 @@ function nodeKind(node) {
|
|
|
11277
11314
|
if (node.kind != "task") return node.kind;
|
|
11278
11315
|
return "moduleId" in node.task ? "javascript" : node.task.executor.kind;
|
|
11279
11316
|
}
|
|
11280
|
-
function
|
|
11281
|
-
if (value == null || typeof value != "object" || Array.isArray(value)) throw new Error(`${description} must be an object.`);
|
|
11282
|
-
return value;
|
|
11283
|
-
}
|
|
11284
|
-
function checkpointExact(value, fields, description) {
|
|
11285
|
-
const keys = Object.keys(value);
|
|
11286
|
-
if (keys.length != fields.length || keys.some((key) => !fields.includes(key))) throw new Error(`${description} contains unsupported fields.`);
|
|
11287
|
-
}
|
|
11288
|
-
function checkpointString(value, description) {
|
|
11289
|
-
if (typeof value != "string" || value.length == 0) throw new Error(`${description} must be a non-empty string.`);
|
|
11290
|
-
return value;
|
|
11291
|
-
}
|
|
11292
|
-
function checkpointJson(value, description, depth = 0) {
|
|
11317
|
+
function jsonValue(value, description, depth = 0) {
|
|
11293
11318
|
if (depth > 64) throw new Error(`${description} exceeds the maximum JSON depth.`);
|
|
11294
11319
|
if (value === null || typeof value == "boolean" || typeof value == "string") return value;
|
|
11295
11320
|
if (typeof value == "number" && Number.isFinite(value)) return value;
|
|
11296
|
-
if (Array.isArray(value)) return value.map((item) =>
|
|
11297
|
-
|
|
11298
|
-
return Object.fromEntries(Object.entries(
|
|
11321
|
+
if (Array.isArray(value)) return value.map((item) => jsonValue(item, description, depth + 1));
|
|
11322
|
+
if (value == null || typeof value != "object") throw new Error(`${description} must be an object.`);
|
|
11323
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, jsonValue(item, description, depth + 1)]));
|
|
11299
11324
|
}
|
|
11300
11325
|
var agentCheckpointSchema = strictObject({
|
|
11301
11326
|
state: json$1(),
|
|
@@ -11312,6 +11337,263 @@ var agentResultSchema = union([strictObject({
|
|
|
11312
11337
|
kind: literal("suspended"),
|
|
11313
11338
|
checkpoint: agentCheckpointSchema
|
|
11314
11339
|
})]);
|
|
11340
|
+
function jsonEqual(left, right) {
|
|
11341
|
+
if (left === right) return true;
|
|
11342
|
+
if (left == null || right == null || typeof left != "object" || typeof right != "object") return false;
|
|
11343
|
+
if (Array.isArray(left) || Array.isArray(right)) return Array.isArray(left) && Array.isArray(right) && left.length == right.length && left.every((value, index) => jsonEqual(value, right[index]));
|
|
11344
|
+
const leftEntries = Object.entries(left);
|
|
11345
|
+
const rightEntries = Object.entries(right);
|
|
11346
|
+
const rightRecord = right;
|
|
11347
|
+
return leftEntries.length == rightEntries.length && leftEntries.every(([key, value]) => Object.hasOwn(rightRecord, key) && jsonEqual(value, rightRecord[key]));
|
|
11348
|
+
}
|
|
11349
|
+
function outputRecord(value, nodeId) {
|
|
11350
|
+
if (value === void 0) return {};
|
|
11351
|
+
if (value == null || typeof value != "object" || Array.isArray(value)) throw new Error(`Node "${nodeId}" must return an object.`);
|
|
11352
|
+
return value;
|
|
11353
|
+
}
|
|
11354
|
+
function agentConfig(node) {
|
|
11355
|
+
const task = node.kind == "task" && "executor" in node.task ? node.task : void 0;
|
|
11356
|
+
return task?.executor.kind == "agent" ? task.executor : void 0;
|
|
11357
|
+
}
|
|
11358
|
+
function agentNotice(node, values) {
|
|
11359
|
+
const notification = agentConfig(node)?.notification;
|
|
11360
|
+
if (notification == null) return void 0;
|
|
11361
|
+
return {
|
|
11362
|
+
messageHandle: notification.messageHandle,
|
|
11363
|
+
input: Object.fromEntries(notification.inputDefinitions.flatMap((port) => {
|
|
11364
|
+
if (!("handle" in port) || port.handle == notification.messageHandle) return [];
|
|
11365
|
+
const source = notification.inputs[port.handle];
|
|
11366
|
+
return [[port.handle, source == null ? port.value ?? null : agentInput(source, values)]];
|
|
11367
|
+
}))
|
|
11368
|
+
};
|
|
11369
|
+
}
|
|
11370
|
+
function agentApproval(config, checkpoint, inputs) {
|
|
11371
|
+
const tool = config.tools.find((item) => item.id == checkpoint.toolId);
|
|
11372
|
+
if (tool == null || !tool.approval || checkpoint.rounds > config.maxRounds) throw new Error("Agent pause does not match its tool declaration.");
|
|
11373
|
+
for (const port of tool.inputs) {
|
|
11374
|
+
const value = checkpoint.input[port.handle];
|
|
11375
|
+
if (value === void 0 || !(value === null && port.nullable) && !matchesSchema(value, port.jsonSchema)) throw new Error("Agent pause arguments are invalid.");
|
|
11376
|
+
if (port.source.kind != "model" && !jsonEqual(value, agentInput(port.source, inputs))) throw new Error("Agent pause changed fixed arguments.");
|
|
11377
|
+
}
|
|
11378
|
+
if (Object.keys(checkpoint.input).length != tool.inputs.length) throw new Error("Agent pause contains undeclared arguments.");
|
|
11379
|
+
return {
|
|
11380
|
+
callId: checkpoint.callId,
|
|
11381
|
+
toolId: tool.id,
|
|
11382
|
+
action: tool.action,
|
|
11383
|
+
...tool.connectionId == null ? {} : { connectionId: tool.connectionId },
|
|
11384
|
+
input: checkpoint.input
|
|
11385
|
+
};
|
|
11386
|
+
}
|
|
11387
|
+
function validateOutputs(nodeId, node, value) {
|
|
11388
|
+
const raw = outputRecord(value, nodeId);
|
|
11389
|
+
const discardUndeclared = node.kind == "task" && "executor" in node.task && (node.task.executor.kind == "connector" || node.task.executor.kind == "workflow");
|
|
11390
|
+
const ports = node.kind == "outputs" ? nodeInputPorts(node) : isResolutionNode(node) ? resolutionOutputPorts(node) : node.kind == "task" ? portsByHandle(node.task.outputs) : node.kind == "value" ? portsByHandle(node.values) : {};
|
|
11391
|
+
const outputs = outputRecord(jsonValue(Object.fromEntries(Object.entries(raw).map(([handle, item]) => [handle, Object.hasOwn(ports, handle) && item === void 0 ? null : item])), `Node "${nodeId}" outputs`), nodeId);
|
|
11392
|
+
const complete = node.kind == "condition" || isResolutionNode(node) ? outputs : {
|
|
11393
|
+
...Object.fromEntries(Object.keys(ports).map((handle) => [handle, null])),
|
|
11394
|
+
...outputs
|
|
11395
|
+
};
|
|
11396
|
+
const validated = [];
|
|
11397
|
+
for (const [handle, output] of Object.entries(complete)) {
|
|
11398
|
+
const port = ports[handle];
|
|
11399
|
+
if (port == null) {
|
|
11400
|
+
if (discardUndeclared) continue;
|
|
11401
|
+
throw new PortValidationError(`Node "${nodeId}" output "${handle}" does not match its declaration.`);
|
|
11402
|
+
}
|
|
11403
|
+
if (!(output === null && port.nullable) && !matchesSchema(output, port.jsonSchema)) throw new PortValidationError(`Node "${nodeId}" output "${handle}" does not match its declaration.`);
|
|
11404
|
+
validated.push([handle, output]);
|
|
11405
|
+
}
|
|
11406
|
+
return Object.fromEntries(validated);
|
|
11407
|
+
}
|
|
11408
|
+
function resolveNodeInputs(nodeId, node, dependencies, bindingValues, launchInputs) {
|
|
11409
|
+
const resolveInput = (mapping, port, supplied, description, required = false) => {
|
|
11410
|
+
let value = inputValue(mapping, supplied === void 0 ? port.value : supplied);
|
|
11411
|
+
if (mapping?.kind == "sources") {
|
|
11412
|
+
const values = mapping.sources.flatMap((source) => {
|
|
11413
|
+
if (source.kind == "binding") return Object.hasOwn(bindingValues, source.bindingId) ? [bindingValues[source.bindingId]] : [];
|
|
11414
|
+
const result = dependencies.input(nodeId, source.nodeId);
|
|
11415
|
+
const outputs = source.system ? result?.systemOutputs : result?.outputs;
|
|
11416
|
+
if (outputs == null || !Object.hasOwn(outputs, source.output)) return [];
|
|
11417
|
+
const output = outputs[source.output];
|
|
11418
|
+
if (source.field === void 0 || output === null) return [output];
|
|
11419
|
+
return output != null && typeof output === "object" && !Array.isArray(output) && Object.hasOwn(output, source.field) ? [output[source.field]] : [];
|
|
11420
|
+
});
|
|
11421
|
+
if (values.length > 1) throw new Error(`${description} has multiple available sources.`);
|
|
11422
|
+
if (required && values.length == 0) throw new Error(`${description} Source has no value.`);
|
|
11423
|
+
value = values[0] ?? null;
|
|
11424
|
+
}
|
|
11425
|
+
if (required && value === void 0) throw new Error(`${description} is incomplete.`);
|
|
11426
|
+
if (value === void 0) value = null;
|
|
11427
|
+
if (!(value === null && port.nullable) && !matchesSchema(value, port.jsonSchema)) throw new PortValidationError(`${description} does not match its declared schema.`);
|
|
11428
|
+
return value;
|
|
11429
|
+
};
|
|
11430
|
+
const mappings = nodeInputMappings(node);
|
|
11431
|
+
return Object.fromEntries(Object.entries(nodeInputPorts(node)).map(([handle, port]) => [handle, resolveInput(mappings[handle], port, launchInputs?.[handle], `Node "${nodeId}" input "${handle}"`, node.kind == "condition")]));
|
|
11432
|
+
}
|
|
11433
|
+
function executeNode(context, input) {
|
|
11434
|
+
const { nodeId, node, jobId, nodeInputs, flowId, runId, graph, dependencies, previousIds, saved, workflowRunId, resolution } = input;
|
|
11435
|
+
const config = agentConfig(node);
|
|
11436
|
+
const nodeRemainingMs = saved?.remainingMs ?? node.timeoutMs;
|
|
11437
|
+
const startedAt = performance.now();
|
|
11438
|
+
const execution = Effect.gen(function* () {
|
|
11439
|
+
const kind = nodeKind(node);
|
|
11440
|
+
const title = nodeTitle(node);
|
|
11441
|
+
const projectedInputs = Object.fromEntries(Object.entries(nodeInputs).filter(([handle]) => {
|
|
11442
|
+
if (node.kind == "task" && "executor" in node.task && node.task?.executor.kind == "openapi" && handle.startsWith("auth.")) return false;
|
|
11443
|
+
const mapping = nodeInputMappings(node)[handle];
|
|
11444
|
+
return mapping?.kind != "sources" || mapping.sources.every((source) => source.kind != "binding");
|
|
11445
|
+
}));
|
|
11446
|
+
if (resolution == null && workflowRunId == null) yield* context.emit({
|
|
11447
|
+
inputs: projectedInputs,
|
|
11448
|
+
jobId,
|
|
11449
|
+
nodeId,
|
|
11450
|
+
nodeKind: kind,
|
|
11451
|
+
...title == null ? {} : { nodeTitle: title },
|
|
11452
|
+
runId,
|
|
11453
|
+
type: "node.started"
|
|
11454
|
+
});
|
|
11455
|
+
let outputs;
|
|
11456
|
+
switch (node.kind) {
|
|
11457
|
+
case "webhook-response": {
|
|
11458
|
+
const status = nodeInputs.statusCode;
|
|
11459
|
+
if (!validWebhookStatus(status)) return yield* Effect.fail(new NodeValidationError("webhook.response-status-invalid", "Invalid HTTP response status."));
|
|
11460
|
+
const headers = webhookHeaderValues(nodeInputs.headers);
|
|
11461
|
+
if (headers == null) return yield* Effect.fail(new NodeValidationError("webhook.response-headers-invalid", "Invalid HTTP response headers."));
|
|
11462
|
+
return {
|
|
11463
|
+
kind: "completed",
|
|
11464
|
+
outputs: {},
|
|
11465
|
+
response: {
|
|
11466
|
+
...encodeWebhookBody(nodeInputs.body),
|
|
11467
|
+
status,
|
|
11468
|
+
headers
|
|
11469
|
+
}
|
|
11470
|
+
};
|
|
11471
|
+
}
|
|
11472
|
+
case "outputs":
|
|
11473
|
+
outputs = nodeInputs;
|
|
11474
|
+
break;
|
|
11475
|
+
case "condition": return {
|
|
11476
|
+
kind: "completed",
|
|
11477
|
+
outputs: {},
|
|
11478
|
+
releasedHandles: selectConditionBranches(node, nodeInputs)
|
|
11479
|
+
};
|
|
11480
|
+
case "value":
|
|
11481
|
+
outputs = Object.fromEntries(node.values.map((port) => [port.handle, port.value ?? null]));
|
|
11482
|
+
break;
|
|
11483
|
+
case "task": {
|
|
11484
|
+
const additional = new Set((node.additionalInputs ?? []).map((port) => port.handle));
|
|
11485
|
+
const result = yield* invokeWithRetry(context, node, {
|
|
11486
|
+
...workflowRunId == null ? {} : { workflowRunId },
|
|
11487
|
+
additionalInputs: Object.fromEntries(Object.entries(nodeInputs).filter(([handle]) => additional.has(handle))),
|
|
11488
|
+
blockId: "moduleId" in node.task ? node.task.moduleId : nodeId,
|
|
11489
|
+
flowId,
|
|
11490
|
+
input: Object.fromEntries(Object.entries(nodeInputs).filter(([handle]) => {
|
|
11491
|
+
if (additional.has(handle)) return false;
|
|
11492
|
+
const task = "executor" in node.task ? node.task : void 0;
|
|
11493
|
+
if (task?.executor.kind != "openapi") return true;
|
|
11494
|
+
const mapping = node.inputs[handle];
|
|
11495
|
+
return mapping?.kind != "unset" && (mapping != null || task.inputs.some((port) => "handle" in port && port.handle == handle && port.value !== void 0));
|
|
11496
|
+
})),
|
|
11497
|
+
invocationId: saved?.invocationId ?? (config == null ? context.createId() : jobId),
|
|
11498
|
+
...resolution == null || saved == null ? {} : { agent: {
|
|
11499
|
+
action: resolution,
|
|
11500
|
+
checkpoint: saved.checkpoint
|
|
11501
|
+
} },
|
|
11502
|
+
jobId,
|
|
11503
|
+
nodeId,
|
|
11504
|
+
runId,
|
|
11505
|
+
..."moduleId" in node.task ? {
|
|
11506
|
+
capabilities: node.task.capabilities ?? [],
|
|
11507
|
+
moduleId: node.task.moduleId,
|
|
11508
|
+
getPrevious: () => {
|
|
11509
|
+
return previousIds.map((previousId) => {
|
|
11510
|
+
const previous = graph.nodes[previousId];
|
|
11511
|
+
const previousResult = dependencies.input(nodeId, previousId);
|
|
11512
|
+
const systemOutputs = previousResult.systemOutputs;
|
|
11513
|
+
return Object.assign({
|
|
11514
|
+
id: previousId,
|
|
11515
|
+
name: nodeTitle(previous) ?? previousId,
|
|
11516
|
+
outputs: previousResult.outputs,
|
|
11517
|
+
outputDefs: Object.entries(nodeOutputPorts(previous)).map(([handle, definition]) => Object.assign({
|
|
11518
|
+
handle,
|
|
11519
|
+
jsonSchema: definition.jsonSchema,
|
|
11520
|
+
nullable: definition.nullable
|
|
11521
|
+
}, definition.description == null ? {} : { description: definition.description }))
|
|
11522
|
+
}, systemOutputs == null ? {} : { systemOutputs });
|
|
11523
|
+
});
|
|
11524
|
+
}
|
|
11525
|
+
} : { kind: "managed" }
|
|
11526
|
+
});
|
|
11527
|
+
if ("executor" in node.task && node.task.executor.kind == "workflow") {
|
|
11528
|
+
const response = discriminatedUnion("kind", [strictObject({
|
|
11529
|
+
kind: literal("calling"),
|
|
11530
|
+
childRunId: string$1().min(1)
|
|
11531
|
+
}), strictObject({
|
|
11532
|
+
kind: literal("completed"),
|
|
11533
|
+
outputs: record$1(string$1(), json$1())
|
|
11534
|
+
})]).parse(result);
|
|
11535
|
+
if (response.kind == "calling") return {
|
|
11536
|
+
kind: "calling",
|
|
11537
|
+
childRunId: response.childRunId,
|
|
11538
|
+
input: nodeInputs
|
|
11539
|
+
};
|
|
11540
|
+
outputs = response.outputs;
|
|
11541
|
+
} else if (config != null) {
|
|
11542
|
+
const response = agentResultSchema.parse(result);
|
|
11543
|
+
if (response.kind == "suspended") {
|
|
11544
|
+
const checkpoint = response.checkpoint;
|
|
11545
|
+
const value = agentApproval(config, checkpoint, nodeInputs);
|
|
11546
|
+
const left = nodeRemainingMs == null ? void 0 : nodeRemainingMs - (performance.now() - startedAt);
|
|
11547
|
+
if (left != null && left <= 0) throw new Error(`Node "${nodeId}" timed out.`);
|
|
11548
|
+
return {
|
|
11549
|
+
kind: "suspended",
|
|
11550
|
+
value,
|
|
11551
|
+
agent: {
|
|
11552
|
+
invocationId: saved?.invocationId ?? jobId,
|
|
11553
|
+
input: nodeInputs,
|
|
11554
|
+
...left == null ? {} : { remainingMs: left },
|
|
11555
|
+
checkpoint
|
|
11556
|
+
}
|
|
11557
|
+
};
|
|
11558
|
+
}
|
|
11559
|
+
outputs = { output: response.output };
|
|
11560
|
+
} else if ("executor" in node.task && node.task.executor.kind == "connector" && node.task.executor.outputMode == "value") outputs = { output: jsonValue(result, `Node "${nodeId}" output`) };
|
|
11561
|
+
else outputs = yield* Effect.try({
|
|
11562
|
+
try: () => outputRecord(result, nodeId),
|
|
11563
|
+
catch: (error) => new NodeValidationError("node.output-invalid", error)
|
|
11564
|
+
});
|
|
11565
|
+
break;
|
|
11566
|
+
}
|
|
11567
|
+
case "approval":
|
|
11568
|
+
case "wait": return yield* Effect.fail(/* @__PURE__ */ new Error("Resolution jobs are handled by the Scheduler suspension boundary."));
|
|
11569
|
+
}
|
|
11570
|
+
return yield* Effect.try({
|
|
11571
|
+
try: () => ({
|
|
11572
|
+
kind: "completed",
|
|
11573
|
+
outputs: validateOutputs(nodeId, node, outputs)
|
|
11574
|
+
}),
|
|
11575
|
+
catch: (error) => new NodeValidationError("node.output-invalid", error)
|
|
11576
|
+
});
|
|
11577
|
+
});
|
|
11578
|
+
return nodeRemainingMs == null ? execution : execution.pipe(Effect.timeoutOrElse({
|
|
11579
|
+
duration: nodeRemainingMs,
|
|
11580
|
+
orElse: () => Effect.fail(/* @__PURE__ */ new Error(`Node "${nodeId}" timed out.`))
|
|
11581
|
+
}));
|
|
11582
|
+
}
|
|
11583
|
+
//#endregion
|
|
11584
|
+
//#region src/execution/common/checkpoint.ts
|
|
11585
|
+
function checkpointRecord(value, description) {
|
|
11586
|
+
if (value == null || typeof value != "object" || Array.isArray(value)) throw new Error(`${description} must be an object.`);
|
|
11587
|
+
return value;
|
|
11588
|
+
}
|
|
11589
|
+
function checkpointExact(value, fields, description) {
|
|
11590
|
+
const keys = Object.keys(value);
|
|
11591
|
+
if (keys.length != fields.length || keys.some((key) => !fields.includes(key))) throw new Error(`${description} contains unsupported fields.`);
|
|
11592
|
+
}
|
|
11593
|
+
function checkpointString(value, description) {
|
|
11594
|
+
if (typeof value != "string" || value.length == 0) throw new Error(`${description} must be a non-empty string.`);
|
|
11595
|
+
return value;
|
|
11596
|
+
}
|
|
11315
11597
|
function decodeFlowRunCheckpoint(input) {
|
|
11316
11598
|
const source = checkpointRecord(input, "Flow Run checkpoint");
|
|
11317
11599
|
checkpointExact(source, [
|
|
@@ -11330,7 +11612,7 @@ function decodeFlowRunCheckpoint(input) {
|
|
|
11330
11612
|
if (typeof value != "string") throw new Error("Checkpoint binding must be a string.");
|
|
11331
11613
|
return [id, value];
|
|
11332
11614
|
}));
|
|
11333
|
-
const inputs = Object.fromEntries(Object.entries(checkpointRecord(source.inputs, "Checkpoint inputs")).map(([id, value]) => [id, Object.fromEntries(Object.entries(checkpointRecord(value, "Checkpoint node inputs")).map(([handle, item]) => [handle,
|
|
11615
|
+
const inputs = Object.fromEntries(Object.entries(checkpointRecord(source.inputs, "Checkpoint inputs")).map(([id, value]) => [id, Object.fromEntries(Object.entries(checkpointRecord(value, "Checkpoint node inputs")).map(([handle, item]) => [handle, jsonValue(item, "Checkpoint input")]))]));
|
|
11334
11616
|
const results = Object.fromEntries(Object.entries(checkpointRecord(source.results, "Checkpoint results")).map(([id, value]) => {
|
|
11335
11617
|
const result = checkpointRecord(value, "Checkpoint result");
|
|
11336
11618
|
if (result.handled !== void 0 && result.handled !== true) throw new Error("Checkpoint handled flag is invalid.");
|
|
@@ -11342,9 +11624,9 @@ function decodeFlowRunCheckpoint(input) {
|
|
|
11342
11624
|
], "Checkpoint result");
|
|
11343
11625
|
return [id, {
|
|
11344
11626
|
jobId: checkpointString(result.jobId, "Checkpoint job ID"),
|
|
11345
|
-
...result.systemOutputs === void 0 ? {} : { systemOutputs: outputRecord(
|
|
11627
|
+
...result.systemOutputs === void 0 ? {} : { systemOutputs: outputRecord(jsonValue(result.systemOutputs, "Checkpoint system outputs"), id) },
|
|
11346
11628
|
...result.handled === true ? { handled: true } : {},
|
|
11347
|
-
outputs: Object.fromEntries(Object.entries(checkpointRecord(result.outputs, "Checkpoint outputs")).map(([handle, item]) => [handle,
|
|
11629
|
+
outputs: Object.fromEntries(Object.entries(checkpointRecord(result.outputs, "Checkpoint outputs")).map(([handle, item]) => [handle, jsonValue(item, "Checkpoint output")]))
|
|
11348
11630
|
}];
|
|
11349
11631
|
}));
|
|
11350
11632
|
const counts = record$1(string$1(), record$1(string$1(), number().int().positive().max(Number.MAX_SAFE_INTEGER))).parse(source.counts);
|
|
@@ -11394,74 +11676,6 @@ function decodeFlowRunCheckpoint(input) {
|
|
|
11394
11676
|
...source.calls === void 0 ? {} : { calls }
|
|
11395
11677
|
};
|
|
11396
11678
|
}
|
|
11397
|
-
function jsonEqual(left, right) {
|
|
11398
|
-
if (left === right) return true;
|
|
11399
|
-
if (left == null || right == null || typeof left != "object" || typeof right != "object") return false;
|
|
11400
|
-
if (Array.isArray(left) || Array.isArray(right)) return Array.isArray(left) && Array.isArray(right) && left.length == right.length && left.every((value, index) => jsonEqual(value, right[index]));
|
|
11401
|
-
const leftEntries = Object.entries(left);
|
|
11402
|
-
const rightEntries = Object.entries(right);
|
|
11403
|
-
const rightRecord = right;
|
|
11404
|
-
return leftEntries.length == rightEntries.length && leftEntries.every(([key, value]) => Object.hasOwn(rightRecord, key) && jsonEqual(value, rightRecord[key]));
|
|
11405
|
-
}
|
|
11406
|
-
function outputRecord(value, nodeId) {
|
|
11407
|
-
if (value === void 0) return {};
|
|
11408
|
-
if (value == null || typeof value != "object" || Array.isArray(value)) throw new Error(`Node "${nodeId}" must return an object.`);
|
|
11409
|
-
return value;
|
|
11410
|
-
}
|
|
11411
|
-
function agentConfig(node) {
|
|
11412
|
-
const task = node.kind == "task" && "executor" in node.task ? node.task : void 0;
|
|
11413
|
-
return task?.executor.kind == "agent" ? task.executor : void 0;
|
|
11414
|
-
}
|
|
11415
|
-
function agentNotice(node, values) {
|
|
11416
|
-
const notification = agentConfig(node)?.notification;
|
|
11417
|
-
if (notification == null) return void 0;
|
|
11418
|
-
return {
|
|
11419
|
-
messageHandle: notification.messageHandle,
|
|
11420
|
-
input: Object.fromEntries(notification.inputDefinitions.flatMap((port) => {
|
|
11421
|
-
if (!("handle" in port) || port.handle == notification.messageHandle) return [];
|
|
11422
|
-
const source = notification.inputs[port.handle];
|
|
11423
|
-
return [[port.handle, source == null ? port.value ?? null : agentInput(source, values)]];
|
|
11424
|
-
}))
|
|
11425
|
-
};
|
|
11426
|
-
}
|
|
11427
|
-
function agentApproval(config, checkpoint, inputs) {
|
|
11428
|
-
const tool = config.tools.find((item) => item.id == checkpoint.toolId);
|
|
11429
|
-
if (tool == null || !tool.approval || checkpoint.rounds > config.maxRounds) throw new Error("Agent pause does not match its tool declaration.");
|
|
11430
|
-
for (const port of tool.inputs) {
|
|
11431
|
-
const value = checkpoint.input[port.handle];
|
|
11432
|
-
if (value === void 0 || !(value === null && port.nullable) && !matchesSchema(value, port.jsonSchema)) throw new Error("Agent pause arguments are invalid.");
|
|
11433
|
-
if (port.source.kind != "model" && !jsonEqual(value, agentInput(port.source, inputs))) throw new Error("Agent pause changed fixed arguments.");
|
|
11434
|
-
}
|
|
11435
|
-
if (Object.keys(checkpoint.input).length != tool.inputs.length) throw new Error("Agent pause contains undeclared arguments.");
|
|
11436
|
-
return {
|
|
11437
|
-
callId: checkpoint.callId,
|
|
11438
|
-
toolId: tool.id,
|
|
11439
|
-
action: tool.action,
|
|
11440
|
-
...tool.connectionId == null ? {} : { connectionId: tool.connectionId },
|
|
11441
|
-
input: checkpoint.input
|
|
11442
|
-
};
|
|
11443
|
-
}
|
|
11444
|
-
function validateOutputs(nodeId, node, value) {
|
|
11445
|
-
const raw = outputRecord(value, nodeId);
|
|
11446
|
-
const discardUndeclared = node.kind == "task" && "executor" in node.task && (node.task.executor.kind == "connector" || node.task.executor.kind == "workflow");
|
|
11447
|
-
const ports = node.kind == "outputs" ? nodeInputPorts(node) : isResolutionNode(node) ? resolutionOutputPorts(node) : node.kind == "task" ? portsByHandle(node.task.outputs) : node.kind == "value" ? portsByHandle(node.values) : {};
|
|
11448
|
-
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);
|
|
11449
|
-
const complete = node.kind == "condition" || isResolutionNode(node) ? outputs : {
|
|
11450
|
-
...Object.fromEntries(Object.keys(ports).map((handle) => [handle, null])),
|
|
11451
|
-
...outputs
|
|
11452
|
-
};
|
|
11453
|
-
const validated = [];
|
|
11454
|
-
for (const [handle, output] of Object.entries(complete)) {
|
|
11455
|
-
const port = ports[handle];
|
|
11456
|
-
if (port == null) {
|
|
11457
|
-
if (discardUndeclared) continue;
|
|
11458
|
-
throw new PortValidationError(`Node "${nodeId}" output "${handle}" does not match its declaration.`);
|
|
11459
|
-
}
|
|
11460
|
-
if (!(output === null && port.nullable) && !matchesSchema(output, port.jsonSchema)) throw new PortValidationError(`Node "${nodeId}" output "${handle}" does not match its declaration.`);
|
|
11461
|
-
validated.push([handle, output]);
|
|
11462
|
-
}
|
|
11463
|
-
return Object.fromEntries(validated);
|
|
11464
|
-
}
|
|
11465
11679
|
function validateCheckpoint(target, checkpoint, resolveInputs) {
|
|
11466
11680
|
const launch = checkpoint.inputs;
|
|
11467
11681
|
const agents = checkpoint.agents;
|
|
@@ -11552,6 +11766,59 @@ function validateCheckpoint(target, checkpoint, resolveInputs) {
|
|
|
11552
11766
|
if (checkpoint.counts[""]?.[waiting.nodeId] == null) throw new Error("Checkpoint waiting execution count is missing.");
|
|
11553
11767
|
}
|
|
11554
11768
|
}
|
|
11769
|
+
//#endregion
|
|
11770
|
+
//#region src/execution/common/events.ts
|
|
11771
|
+
var encoder = new TextEncoder();
|
|
11772
|
+
function string(value, description) {
|
|
11773
|
+
if (typeof value != "string" || value.length == 0) throw new TypeError(`${description} must be a non-empty string.`);
|
|
11774
|
+
return value;
|
|
11775
|
+
}
|
|
11776
|
+
/** Stable public identity shared by events and durable workflow-call provenance. */
|
|
11777
|
+
function projectExecutionId(platformRunId, rawRunId, jobId) {
|
|
11778
|
+
return opaqueId("execution", platformRunId, rawRunId, jobId);
|
|
11779
|
+
}
|
|
11780
|
+
async function opaqueId(prefix, ...parts) {
|
|
11781
|
+
const bytes = encoder.encode(JSON.stringify([
|
|
11782
|
+
1,
|
|
11783
|
+
prefix,
|
|
11784
|
+
...parts
|
|
11785
|
+
]));
|
|
11786
|
+
const input = new Uint8Array(bytes.byteLength);
|
|
11787
|
+
input.set(bytes);
|
|
11788
|
+
return `${prefix}_${[...new Uint8Array(await crypto.subtle.digest("SHA-256", input))].slice(0, 16).map((byte) => byte.toString(16).padStart(2, "0")).join("")}`;
|
|
11789
|
+
}
|
|
11790
|
+
function message(value) {
|
|
11791
|
+
return string(value, "Runtime event message").replace(/Bearer\s+\S+/gi, "Bearer [REDACTED]").replace(/\b(api[-_ ]?key|authorization|password|secret|token)\s*[:=]\s*\S+/gi, "$1=[REDACTED]");
|
|
11792
|
+
}
|
|
11793
|
+
//#endregion
|
|
11794
|
+
//#region src/execution/common/wait.ts
|
|
11795
|
+
/** Shared by decision entry points, the editor, and durable decision storage. */
|
|
11796
|
+
var waitCommentSchema = string$1().trim().refine((value) => [...value].length <= 2e3, "Wait comment must contain at most 2,000 Unicode code points.").nullable().optional();
|
|
11797
|
+
function normalizeWaitComment$1(value) {
|
|
11798
|
+
return waitCommentSchema.parse(value) || null;
|
|
11799
|
+
}
|
|
11800
|
+
function withWaitNotificationMessage$1(value) {
|
|
11801
|
+
const source = schemaObject(value);
|
|
11802
|
+
if (source == null || source.pageUrl !== void 0 && source.message !== void 0) return value;
|
|
11803
|
+
const pageUrl = source.pageUrl === void 0 ? source.continueUrl ?? source.approveUrl : source.pageUrl;
|
|
11804
|
+
if (typeof pageUrl != "string" || typeof source.prompt != "string" || typeof source.expiresAt != "string") return value;
|
|
11805
|
+
return {
|
|
11806
|
+
...source,
|
|
11807
|
+
pageUrl,
|
|
11808
|
+
message: source.message === void 0 ? [
|
|
11809
|
+
source.prompt,
|
|
11810
|
+
...typeof source.autoContinueAt == "string" ? [`Automatically continues at: ${source.autoContinueAt}`] : [],
|
|
11811
|
+
`Expires at: ${source.expiresAt}`,
|
|
11812
|
+
`Review request: ${pageUrl}`
|
|
11813
|
+
].join("\n\n") : source.message
|
|
11814
|
+
};
|
|
11815
|
+
}
|
|
11816
|
+
//#endregion
|
|
11817
|
+
//#region src/execution/common/scheduler.ts
|
|
11818
|
+
var withWaitNotificationMessage = withWaitNotificationMessage$1;
|
|
11819
|
+
var normalizeWaitComment = normalizeWaitComment$1;
|
|
11820
|
+
var waitAutoContinueAt = waitAutoContinueAt$1;
|
|
11821
|
+
var waitRetentionMs = 12e4;
|
|
11555
11822
|
function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
11556
11823
|
return Effect.scoped(Effect.gen(function* () {
|
|
11557
11824
|
if (resume == null) yield* context.emit({
|
|
@@ -11595,32 +11862,7 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11595
11862
|
let measuredAt = yield* Clock.currentTimeMillis;
|
|
11596
11863
|
let idleSince;
|
|
11597
11864
|
const agents = { ...resume?.checkpoint.agents };
|
|
11598
|
-
const
|
|
11599
|
-
let value = inputValue(mapping, supplied === void 0 ? port.value : supplied);
|
|
11600
|
-
if (mapping?.kind == "sources") {
|
|
11601
|
-
const values = mapping.sources.flatMap((source) => {
|
|
11602
|
-
if (source.kind == "binding") return Object.hasOwn(context.bindingValues, source.bindingId) ? [context.bindingValues[source.bindingId]] : [];
|
|
11603
|
-
const outputs = (source.system ? systemByNode : valuesByNode)[source.nodeId];
|
|
11604
|
-
if (outputs == null || !Object.hasOwn(outputs, source.output)) return [];
|
|
11605
|
-
const output = outputs[source.output];
|
|
11606
|
-
if (source.field === void 0 || output === null) return [output];
|
|
11607
|
-
return output != null && typeof output === "object" && !Array.isArray(output) && Object.hasOwn(output, source.field) ? [output[source.field]] : [];
|
|
11608
|
-
});
|
|
11609
|
-
if (values.length > 1) throw new Error(`${description} has multiple available sources.`);
|
|
11610
|
-
if (required && values.length == 0) throw new Error(`${description} Source has no value.`);
|
|
11611
|
-
value = values[0] ?? null;
|
|
11612
|
-
}
|
|
11613
|
-
if (required && value === void 0) throw new Error(`${description} is incomplete.`);
|
|
11614
|
-
if (value === void 0) value = null;
|
|
11615
|
-
if (!(value === null && port.nullable) && !matchesSchema(value, port.jsonSchema)) throw new PortValidationError(`${description} does not match its declared schema.`);
|
|
11616
|
-
return value;
|
|
11617
|
-
};
|
|
11618
|
-
const resolveInputs = (nodeId, node) => {
|
|
11619
|
-
const mappings = nodeInputMappings(node);
|
|
11620
|
-
const frame = dependencies.inputValues(nodeId);
|
|
11621
|
-
const systemFrame = dependencies.systemInputValues(nodeId);
|
|
11622
|
-
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", systemFrame)]));
|
|
11623
|
-
};
|
|
11865
|
+
const resolveInputs = (nodeId, node) => resolveNodeInputs(nodeId, node, dependencies, context.bindingValues, launch[nodeId]);
|
|
11624
11866
|
const commit = (nodeId, jobId, outputs, releasedHandles = Object.keys(outputs), failure, response) => Effect.uninterruptible(Effect.gen(function* () {
|
|
11625
11867
|
const node = target.graph.nodes[nodeId];
|
|
11626
11868
|
const systemOutputs = nodeSystemOutputPorts(node).error == null ? void 0 : { error: failure == null ? null : {
|
|
@@ -11658,158 +11900,20 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11658
11900
|
});
|
|
11659
11901
|
dependencies.release(nodeId, outputs, releasedHandles, true, systemOutputs);
|
|
11660
11902
|
}));
|
|
11661
|
-
const
|
|
11662
|
-
|
|
11663
|
-
|
|
11664
|
-
|
|
11665
|
-
|
|
11666
|
-
|
|
11667
|
-
|
|
11668
|
-
|
|
11669
|
-
|
|
11670
|
-
|
|
11671
|
-
|
|
11672
|
-
|
|
11673
|
-
|
|
11674
|
-
|
|
11675
|
-
inputs: projectedInputs,
|
|
11676
|
-
jobId,
|
|
11677
|
-
nodeId,
|
|
11678
|
-
nodeKind: kind,
|
|
11679
|
-
...title == null ? {} : { nodeTitle: title },
|
|
11680
|
-
runId,
|
|
11681
|
-
type: "node.started"
|
|
11682
|
-
});
|
|
11683
|
-
let outputs;
|
|
11684
|
-
switch (node.kind) {
|
|
11685
|
-
case "webhook-response": {
|
|
11686
|
-
const status = nodeInputs.statusCode;
|
|
11687
|
-
if (!validWebhookStatus(status)) return yield* Effect.fail(new NodeValidationError("webhook.response-status-invalid", "Invalid HTTP response status."));
|
|
11688
|
-
const headers = webhookHeaderValues(nodeInputs.headers);
|
|
11689
|
-
if (headers == null) return yield* Effect.fail(new NodeValidationError("webhook.response-headers-invalid", "Invalid HTTP response headers."));
|
|
11690
|
-
return {
|
|
11691
|
-
kind: "completed",
|
|
11692
|
-
outputs: {},
|
|
11693
|
-
response: {
|
|
11694
|
-
...encodeWebhookBody(nodeInputs.body),
|
|
11695
|
-
status,
|
|
11696
|
-
headers
|
|
11697
|
-
}
|
|
11698
|
-
};
|
|
11699
|
-
}
|
|
11700
|
-
case "outputs":
|
|
11701
|
-
outputs = nodeInputs;
|
|
11702
|
-
break;
|
|
11703
|
-
case "condition": return {
|
|
11704
|
-
kind: "completed",
|
|
11705
|
-
outputs: {},
|
|
11706
|
-
releasedHandles: selectConditionBranches(node, nodeInputs)
|
|
11707
|
-
};
|
|
11708
|
-
case "value":
|
|
11709
|
-
outputs = Object.fromEntries(node.values.map((port) => [port.handle, port.value ?? null]));
|
|
11710
|
-
break;
|
|
11711
|
-
case "task": {
|
|
11712
|
-
const frame = dependencies.inputValues(nodeId);
|
|
11713
|
-
const systemFrame = dependencies.systemInputValues(nodeId);
|
|
11714
|
-
const previousIds = dependencies.state.nodes[nodeId].previous;
|
|
11715
|
-
const additional = new Set((node.additionalInputs ?? []).map((port) => port.handle));
|
|
11716
|
-
const result = yield* invokeWithRetry(context, node, {
|
|
11717
|
-
...pendingCalls.has(jobId) ? { workflowRunId: pendingCalls.get(jobId).childRunId } : {},
|
|
11718
|
-
additionalInputs: Object.fromEntries(Object.entries(nodeInputs).filter(([handle]) => additional.has(handle))),
|
|
11719
|
-
blockId: "moduleId" in node.task ? node.task.moduleId : nodeId,
|
|
11720
|
-
flowId: target.flowId,
|
|
11721
|
-
input: Object.fromEntries(Object.entries(nodeInputs).filter(([handle]) => {
|
|
11722
|
-
if (additional.has(handle)) return false;
|
|
11723
|
-
const task = "executor" in node.task ? node.task : void 0;
|
|
11724
|
-
if (task?.executor.kind != "openapi") return true;
|
|
11725
|
-
const mapping = node.inputs[handle];
|
|
11726
|
-
return mapping?.kind != "unset" && (mapping != null || task.inputs.some((port) => "handle" in port && port.handle == handle && port.value !== void 0));
|
|
11727
|
-
})),
|
|
11728
|
-
invocationId: saved?.invocationId ?? (config == null ? context.createId() : jobId),
|
|
11729
|
-
...resolution == null || saved == null ? {} : { agent: {
|
|
11730
|
-
action: resolution,
|
|
11731
|
-
checkpoint: saved.checkpoint
|
|
11732
|
-
} },
|
|
11733
|
-
jobId,
|
|
11734
|
-
nodeId,
|
|
11735
|
-
runId,
|
|
11736
|
-
..."moduleId" in node.task ? {
|
|
11737
|
-
capabilities: node.task.capabilities ?? [],
|
|
11738
|
-
moduleId: node.task.moduleId,
|
|
11739
|
-
getPrevious: () => {
|
|
11740
|
-
return previousIds.map((previousId) => {
|
|
11741
|
-
const previous = target.graph.nodes[previousId];
|
|
11742
|
-
const systemOutputs = systemFrame[previousId];
|
|
11743
|
-
return Object.assign({
|
|
11744
|
-
id: previousId,
|
|
11745
|
-
name: nodeTitle(previous) ?? previousId,
|
|
11746
|
-
outputs: frame[previousId],
|
|
11747
|
-
outputDefs: Object.entries(nodeOutputPorts(previous)).map(([handle, definition]) => Object.assign({
|
|
11748
|
-
handle,
|
|
11749
|
-
jsonSchema: definition.jsonSchema,
|
|
11750
|
-
nullable: definition.nullable
|
|
11751
|
-
}, definition.description == null ? {} : { description: definition.description }))
|
|
11752
|
-
}, systemOutputs == null ? {} : { systemOutputs });
|
|
11753
|
-
});
|
|
11754
|
-
}
|
|
11755
|
-
} : { kind: "managed" }
|
|
11756
|
-
});
|
|
11757
|
-
if ("executor" in node.task && node.task.executor.kind == "workflow") {
|
|
11758
|
-
const response = discriminatedUnion("kind", [strictObject({
|
|
11759
|
-
kind: literal("calling"),
|
|
11760
|
-
childRunId: string$1().min(1)
|
|
11761
|
-
}), strictObject({
|
|
11762
|
-
kind: literal("completed"),
|
|
11763
|
-
outputs: record$1(string$1(), json$1())
|
|
11764
|
-
})]).parse(result);
|
|
11765
|
-
if (response.kind == "calling") return {
|
|
11766
|
-
kind: "calling",
|
|
11767
|
-
childRunId: response.childRunId,
|
|
11768
|
-
input: nodeInputs
|
|
11769
|
-
};
|
|
11770
|
-
outputs = response.outputs;
|
|
11771
|
-
} else if (config != null) {
|
|
11772
|
-
const response = agentResultSchema.parse(result);
|
|
11773
|
-
if (response.kind == "suspended") {
|
|
11774
|
-
const checkpoint = response.checkpoint;
|
|
11775
|
-
const value = agentApproval(config, checkpoint, nodeInputs);
|
|
11776
|
-
const left = nodeRemainingMs == null ? void 0 : nodeRemainingMs - (performance.now() - startedAt);
|
|
11777
|
-
if (left != null && left <= 0) throw new Error(`Node "${nodeId}" timed out.`);
|
|
11778
|
-
return {
|
|
11779
|
-
kind: "suspended",
|
|
11780
|
-
value,
|
|
11781
|
-
agent: {
|
|
11782
|
-
invocationId: saved?.invocationId ?? jobId,
|
|
11783
|
-
input: nodeInputs,
|
|
11784
|
-
...left == null ? {} : { remainingMs: left },
|
|
11785
|
-
checkpoint
|
|
11786
|
-
}
|
|
11787
|
-
};
|
|
11788
|
-
}
|
|
11789
|
-
outputs = { output: response.output };
|
|
11790
|
-
} else if ("executor" in node.task && node.task.executor.kind == "connector" && node.task.executor.outputMode == "value") outputs = { output: checkpointJson(result, `Node "${nodeId}" output`) };
|
|
11791
|
-
else outputs = yield* Effect.try({
|
|
11792
|
-
try: () => outputRecord(result, nodeId),
|
|
11793
|
-
catch: (error) => new NodeValidationError("node.output-invalid", error)
|
|
11794
|
-
});
|
|
11795
|
-
break;
|
|
11796
|
-
}
|
|
11797
|
-
case "approval":
|
|
11798
|
-
case "wait": return yield* Effect.fail(/* @__PURE__ */ new Error("Resolution jobs are handled by the Scheduler suspension boundary."));
|
|
11799
|
-
}
|
|
11800
|
-
return yield* Effect.try({
|
|
11801
|
-
try: () => ({
|
|
11802
|
-
kind: "completed",
|
|
11803
|
-
outputs: validateOutputs(nodeId, node, outputs)
|
|
11804
|
-
}),
|
|
11805
|
-
catch: (error) => new NodeValidationError("node.output-invalid", error)
|
|
11806
|
-
});
|
|
11807
|
-
});
|
|
11808
|
-
return nodeRemainingMs == null ? execution : execution.pipe(Effect.timeoutOrElse({
|
|
11809
|
-
duration: nodeRemainingMs,
|
|
11810
|
-
orElse: () => Effect.fail(/* @__PURE__ */ new Error(`Node "${nodeId}" timed out.`))
|
|
11811
|
-
}));
|
|
11812
|
-
};
|
|
11903
|
+
const execute = (nodeId, node, jobId, nodeInputs, resolution) => executeNode(context, {
|
|
11904
|
+
nodeId,
|
|
11905
|
+
node,
|
|
11906
|
+
jobId,
|
|
11907
|
+
nodeInputs,
|
|
11908
|
+
resolution,
|
|
11909
|
+
flowId: target.flowId,
|
|
11910
|
+
runId,
|
|
11911
|
+
graph: target.graph,
|
|
11912
|
+
dependencies,
|
|
11913
|
+
previousIds: dependencies.state.nodes[nodeId].previous,
|
|
11914
|
+
saved: agents[jobId],
|
|
11915
|
+
workflowRunId: pendingCalls.get(jobId)?.childRunId
|
|
11916
|
+
});
|
|
11813
11917
|
const createWait = (nodeId, jobId, value) => Effect.gen(function* () {
|
|
11814
11918
|
if (context.waits == null) return yield* Effect.fail(/* @__PURE__ */ new Error("Wait host is unavailable."));
|
|
11815
11919
|
const node = target.graph.nodes[nodeId];
|
|
@@ -11910,7 +12014,7 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11910
12014
|
yield* createWait(nodeId, jobId, nodeInputs);
|
|
11911
12015
|
return;
|
|
11912
12016
|
}
|
|
11913
|
-
return yield*
|
|
12017
|
+
return yield* execute(nodeId, node, jobId, nodeInputs);
|
|
11914
12018
|
}).pipe(Effect.catch((error) => {
|
|
11915
12019
|
const failure = nodeFailure(error, context.projectFailure);
|
|
11916
12020
|
if (!supportsNodeErrorHandling(node) || node.onError != "error" || failure.catchable !== true) return Effect.fail(error);
|
|
@@ -11951,7 +12055,7 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11951
12055
|
}), [action]);
|
|
11952
12056
|
} else {
|
|
11953
12057
|
if (action == "continue") return yield* Effect.fail(/* @__PURE__ */ new Error("Agent requires approve or reject."));
|
|
11954
|
-
yield* settleNode(saved.nodeId, saved.jobId, yield*
|
|
12058
|
+
yield* settleNode(saved.nodeId, saved.jobId, yield* execute(saved.nodeId, node, saved.jobId, agents[saved.jobId].input, action));
|
|
11955
12059
|
}
|
|
11956
12060
|
})).pipe(Effect.ensuring(Queue.offer(changes, void 0))));
|
|
11957
12061
|
}
|
|
@@ -11973,7 +12077,7 @@ function runGraph(context, target, runId, launchInputs = {}, trigger, resume) {
|
|
|
11973
12077
|
}
|
|
11974
12078
|
if (pendingWaits.size > 0 && context.waits != null) applyResolutions(yield* context.waits.resolutions([...pendingWaits.values()].map((wait) => wait.waitId), false), now);
|
|
11975
12079
|
for (const call of pendingCalls.values()) yield* observe(call.nodeId, call.jobId, Effect.gen(function* () {
|
|
11976
|
-
const result = yield*
|
|
12080
|
+
const result = yield* execute(call.nodeId, target.graph.nodes[call.nodeId], call.jobId, call.input);
|
|
11977
12081
|
yield* settleNode(call.nodeId, call.jobId, result);
|
|
11978
12082
|
})).pipe(Effect.catch(() => Effect.void));
|
|
11979
12083
|
const ready = dependencies.ready();
|