@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.
@@ -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 [id, result] of Object.entries(source.input)) merge(id, result);
11054
- 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;
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/execution/common/events.ts
11170
- var encoder = new TextEncoder();
11171
- function string(value, description) {
11172
- if (typeof value != "string" || value.length == 0) throw new TypeError(`${description} must be a non-empty string.`);
11173
- return value;
11174
- }
11175
- /** Stable public identity shared by events and durable workflow-call provenance. */
11176
- function projectExecutionId(platformRunId, rawRunId, jobId) {
11177
- return opaqueId("execution", platformRunId, rawRunId, jobId);
11178
- }
11179
- async function opaqueId(prefix, ...parts) {
11180
- const bytes = encoder.encode(JSON.stringify([
11181
- 1,
11182
- prefix,
11183
- ...parts
11184
- ]));
11185
- const input = new Uint8Array(bytes.byteLength);
11186
- input.set(bytes);
11187
- return `${prefix}_${[...new Uint8Array(await crypto.subtle.digest("SHA-256", input))].slice(0, 16).map((byte) => byte.toString(16).padStart(2, "0")).join("")}`;
11188
- }
11189
- function message(value) {
11190
- 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]");
11191
- }
11192
- //#endregion
11193
- //#region src/execution/common/wait.ts
11194
- /** Shared by decision entry points, the editor, and durable decision storage. */
11195
- var waitCommentSchema = string$1().trim().refine((value) => [...value].length <= 2e3, "Wait comment must contain at most 2,000 Unicode code points.").nullable().optional();
11196
- function normalizeWaitComment$1(value) {
11197
- return waitCommentSchema.parse(value) || null;
11198
- }
11199
- function withWaitNotificationMessage$1(value) {
11200
- const source = schemaObject(value);
11201
- if (source == null || source.pageUrl !== void 0 && source.message !== void 0) return value;
11202
- const pageUrl = source.pageUrl === void 0 ? source.continueUrl ?? source.approveUrl : source.pageUrl;
11203
- if (typeof pageUrl != "string" || typeof source.prompt != "string" || typeof source.expiresAt != "string") return value;
11204
- return {
11205
- ...source,
11206
- pageUrl,
11207
- message: source.message === void 0 ? [
11208
- source.prompt,
11209
- ...typeof source.autoContinueAt == "string" ? [`Automatically continues at: ${source.autoContinueAt}`] : [],
11210
- `Expires at: ${source.expiresAt}`,
11211
- `Review request: ${pageUrl}`
11212
- ].join("\n\n") : source.message
11213
- };
11214
- }
11215
- //#endregion
11216
- //#region src/execution/common/scheduler.ts
11217
- var withWaitNotificationMessage = withWaitNotificationMessage$1;
11218
- var normalizeWaitComment = normalizeWaitComment$1;
11219
- var waitAutoContinueAt = waitAutoContinueAt$1;
11220
- var PortValidationError = class extends Error {};
11221
- function usesPending(graph, nodeId) {
11222
- 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")));
11223
- }
11224
- var waitRetentionMs = 12e4;
11225
- var NodeValidationError = class extends PortValidationError {
11226
- constructor(code, error) {
11227
- super(error instanceof Error ? error.message : String(error));
11228
- this.code = code;
11229
- }
11230
- };
11231
- function nodeFailure(error, project) {
11232
- if (error instanceof NodeValidationError) return {
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 checkpointRecord(value, description) {
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) => checkpointJson(item, description, depth + 1));
11297
- const source = checkpointRecord(value, description);
11298
- return Object.fromEntries(Object.entries(source).map(([key, item]) => [key, checkpointJson(item, description, depth + 1)]));
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, checkpointJson(item, "Checkpoint input")]))]));
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(checkpointJson(result.systemOutputs, "Checkpoint system outputs"), id) },
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, checkpointJson(item, "Checkpoint output")]))
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 resolveInput = (mapping, port, supplied, description, valuesByNode, required = false, systemByNode = {}) => {
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 executeNode = (nodeId, node, jobId, nodeInputs, resolution) => {
11662
- const config = agentConfig(node);
11663
- const saved = agents[jobId];
11664
- const nodeRemainingMs = saved?.remainingMs ?? node.timeoutMs;
11665
- const startedAt = performance.now();
11666
- const execution = Effect.gen(function* () {
11667
- const kind = nodeKind(node);
11668
- const title = nodeTitle(node);
11669
- const projectedInputs = Object.fromEntries(Object.entries(nodeInputs).filter(([handle]) => {
11670
- if (node.kind == "task" && "executor" in node.task && node.task?.executor.kind == "openapi" && handle.startsWith("auth.")) return false;
11671
- const mapping = nodeInputMappings(node)[handle];
11672
- return mapping?.kind != "sources" || mapping.sources.every((source) => source.kind != "binding");
11673
- }));
11674
- if (resolution == null && !pendingCalls.has(jobId)) yield* context.emit({
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* executeNode(nodeId, node, jobId, nodeInputs);
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* executeNode(saved.nodeId, node, saved.jobId, agents[saved.jobId].input, action));
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* executeNode(call.nodeId, target.graph.nodes[call.nodeId], call.jobId, call.input);
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();