@oomol-lab/open-flow 0.1.0-beta.50 → 0.1.0-beta.52

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.
Files changed (44) hide show
  1. package/dist/browser/{createResourceDialog-CSltk-qY.js → createResourceDialog-BsaBMf7_.js} +2 -1
  2. package/dist/browser/flow-authoring-node.d.ts +3 -1
  3. package/dist/browser/flow-authoring.js +82 -3
  4. package/dist/browser/flow-change-schema.d.ts +1 -1
  5. package/dist/browser/flow-change.d.ts +15 -2
  6. package/dist/browser/flow-change.js +81 -3
  7. package/dist/browser/{flowChanges-DbYrpHnS.js → flowChanges-DtraMpva.js} +3858 -1921
  8. package/dist/browser/{flowWorkspace-CjwpbVBR.js → flowWorkspace-DLgti4Lk.js} +1353 -513
  9. package/dist/browser/{workbenchSelect-oVujN2z6.js → icons-0s-Q_3lp.js} +92 -35
  10. package/dist/browser/licenses.md +204 -0
  11. package/dist/browser/preview.css +302 -179
  12. package/dist/browser/preview.js +4829 -2198
  13. package/dist/browser/theme.css +2 -0
  14. package/dist/browser/ui-hostNavigationActions.d.ts +13 -0
  15. package/dist/browser/ui-hostTooltip.d.ts +8 -0
  16. package/dist/browser/ui-logo.d.ts +5 -0
  17. package/dist/browser/ui.css +102 -8
  18. package/dist/browser/ui.d.ts +3 -0
  19. package/dist/browser/ui.js +176 -11
  20. package/dist/browser/workbench-contract.d.ts +5 -11
  21. package/dist/browser/workbench.css +366 -200
  22. package/dist/browser/workbench.d.ts +1 -1
  23. package/dist/browser/workbench.js +1154 -379
  24. package/dist/browser/workbenchSelect-BqUPacsr.js +31 -0
  25. package/dist/common/authoringExamples.d.ts +4 -2
  26. package/dist/common/control-api-conformance.js +129 -11
  27. package/dist/common/control-api.d.ts +38 -5
  28. package/dist/common/control-api.js +198 -12
  29. package/dist/common/control-requests.d.ts +4 -0
  30. package/dist/common/control-requests.js +1320 -67
  31. package/dist/common/flow-encoding.js +64 -5
  32. package/dist/common/flow-semantics.js +823 -316
  33. package/dist/common/integration-trigger.js +39 -1
  34. package/dist/common/mcp.js +129 -11
  35. package/dist/common/openapi.d.ts +53 -0
  36. package/dist/common/openapi.js +10390 -0
  37. package/dist/common/poll-trigger.js +39 -1
  38. package/dist/common/provider-triggers.js +39 -1
  39. package/dist/common/run-events.js +26 -1
  40. package/dist/common/scheduler.d.ts +4 -1
  41. package/dist/common/scheduler.js +122 -6
  42. package/dist/common/trigger-contract.d.ts +2 -0
  43. package/dist/common/webhook-trigger.js +39 -1
  44. package/package.json +5 -1
@@ -1,196 +1,25 @@
1
- //#region src/flow/common/promptTemplate.ts
2
- var promptReferencePattern = /\{\{\s*([^{}\s]+)\s*\}\}/g;
3
- function renderPrompt(template, input) {
4
- return template.replace(promptReferencePattern, (match, name) => {
5
- if (!Object.hasOwn(input, name)) return match;
6
- const value = input[name];
7
- return typeof value == "string" ? value : JSON.stringify(value);
8
- });
9
- }
10
- //#endregion
11
- //#region src/flow/common/connectionUsage.ts
12
- function connectionUsage(document) {
13
- const uses = [];
14
- const graphs = [{
15
- graph: document.graph,
16
- target: { kind: "flow" },
17
- name: ""
18
- }, ...Object.entries(document.subflows).map(([id, subflow]) => ({
19
- graph: subflow.graph,
20
- target: {
21
- kind: "subflow",
22
- id
23
- },
24
- name: subflow.name
25
- }))];
26
- for (const { graph, target, name: graphName } of graphs) for (const [nodeId, node] of Object.entries(graph.nodes)) {
27
- const task = node.kind == "task" && node.taskId != null ? document.tasks[node.taskId] : void 0;
28
- const name = [graphName, node.name ?? task?.name ?? nodeId].filter(Boolean).join(" / ");
29
- const add = (kind, actionId, connectionId) => {
30
- uses.push({
31
- kind,
32
- providerId: actionId.split(".")[0],
33
- actionId,
34
- connectionId,
35
- nodeId,
36
- name,
37
- target
38
- });
39
- };
40
- if (node.kind == "poll" || node.kind == "integration") uses.push({
41
- kind: "trigger",
42
- providerId: node.definition.provider,
43
- connectionId: node.connectionId,
44
- nodeId,
45
- name,
46
- target
47
- });
48
- if (task?.executor.kind == "connector") add("connector", task.executor.action, task.executor.connectionId);
49
- if (node.kind == "task" && node.task != null) {
50
- for (const capability of node.task.capabilities ?? []) if ("mode" in capability && capability.mode == "independent") for (const action of capability.actions) add("code", action.action, action.connectionId);
51
- }
52
- if (task?.executor.kind == "agent") {
53
- for (const tool of task.executor.tools) add("agent", tool.action, tool.connectionId);
54
- const notification = task.executor.notification == null ? void 0 : document.tasks[task.executor.notification.taskId]?.executor;
55
- if (notification?.kind == "connector") add("notification", notification.action, notification.connectionId);
56
- }
57
- }
58
- return uses;
59
- }
60
- function removeConnectionUsage(content, connectionId) {
61
- const document = content.document;
62
- return {
63
- ...content,
64
- document: {
65
- ...document,
66
- tasks: Object.fromEntries(Object.entries(document.tasks).map(([id, task]) => {
67
- const executor = task.executor;
68
- if (executor.kind == "connector" && executor.connectionId == connectionId) {
69
- const { connectionId: _, ...next } = executor;
70
- return [id, {
71
- ...task,
72
- executor: next
73
- }];
74
- }
75
- if (executor.kind == "agent") return [id, {
76
- ...task,
77
- executor: {
78
- ...executor,
79
- tools: executor.tools.map((tool) => {
80
- if (tool.connectionId != connectionId) return tool;
81
- const { connectionId: _, ...next } = tool;
82
- return next;
83
- })
84
- }
85
- }];
86
- return [id, task];
87
- })),
88
- graph: clearNodeConnections(document.graph, connectionId),
89
- subflows: Object.fromEntries(Object.entries(document.subflows).map(([id, subflow]) => [id, {
90
- ...subflow,
91
- graph: clearNodeConnections(subflow.graph, connectionId)
92
- }]))
1
+ //#region ../../node_modules/.bun/dequal@2.0.3/node_modules/dequal/lite/index.mjs
2
+ var has = Object.prototype.hasOwnProperty;
3
+ function dequal(foo, bar) {
4
+ var ctor, len;
5
+ if (foo === bar) return true;
6
+ if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
7
+ if (ctor === Date) return foo.getTime() === bar.getTime();
8
+ if (ctor === RegExp) return foo.toString() === bar.toString();
9
+ if (ctor === Array) {
10
+ if ((len = foo.length) === bar.length) while (len-- && dequal(foo[len], bar[len]));
11
+ return len === -1;
93
12
  }
94
- };
95
- }
96
- function clearNodeConnections(graph, connectionId) {
97
- return {
98
- ...graph,
99
- nodes: Object.fromEntries(Object.entries(graph.nodes).map(([id, node]) => {
100
- if ((node.kind == "poll" || node.kind == "integration") && node.connectionId == connectionId) {
101
- const { connectionId: _, ...remaining } = node;
102
- return [id, remaining];
103
- }
104
- if (node.kind != "task" || node.task == null) return [id, node];
105
- const capabilities = node.task.capabilities?.map((capability) => {
106
- if (!("mode" in capability) || capability.mode != "independent") return capability;
107
- return {
108
- ...capability,
109
- actions: capability.actions.map((action) => {
110
- if (action.connectionId != connectionId) return action;
111
- const { connectionId: _, ...remaining } = action;
112
- return remaining;
113
- })
114
- };
115
- });
116
- return [id, capabilities == null ? node : {
117
- ...node,
118
- task: {
119
- ...node.task,
120
- capabilities
121
- }
122
- }];
123
- }))
124
- };
125
- }
126
- //#endregion
127
- //#region src/base/common/json.ts
128
- function hasJsonShape(root) {
129
- if (root === null || typeof root == "boolean" || typeof root == "string") return true;
130
- if (typeof root == "number") return Number.isFinite(root);
131
- if (typeof root != "object") return false;
132
- const ancestors = /* @__PURE__ */ new Set();
133
- const pending = [];
134
- let value = root;
135
- traversal: while (true) {
136
- let keys;
137
- let arrayLength;
138
- if (Array.isArray(value)) {
139
- arrayLength = value.length;
140
- keys = Reflect.ownKeys(value);
141
- if (keys.length != arrayLength + 1) return false;
142
- } else {
143
- const prototype = Reflect.getPrototypeOf(value);
144
- if (prototype != Object.prototype && prototype != null) return false;
145
- keys = Reflect.ownKeys(value);
146
- arrayLength = void 0;
147
- }
148
- ancestors.add(value);
149
- let index = 0;
150
- while (true) {
151
- if (index >= keys.length) {
152
- ancestors.delete(value);
153
- const parent = pending.pop();
154
- if (parent === void 0) return true;
155
- value = parent.value;
156
- keys = parent.keys;
157
- arrayLength = parent.arrayLength;
158
- index = parent.index;
159
- continue;
160
- }
161
- const key = keys[index++];
162
- if (arrayLength !== void 0) {
163
- if (key == "length") continue;
164
- if (typeof key != "string") return false;
165
- const arrayIndex = Number(key);
166
- if (!Number.isSafeInteger(arrayIndex) || arrayIndex < 0 || arrayIndex >= arrayLength || String(arrayIndex) != key) return false;
167
- } else if (typeof key != "string") return false;
168
- const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
169
- if (descriptor?.enumerable != true || !Object.hasOwn(descriptor, "value")) return false;
170
- const child = descriptor.value;
171
- if (child === null || typeof child == "boolean" || typeof child == "string") continue;
172
- if (typeof child == "number") {
173
- if (!Number.isFinite(child)) return false;
174
- continue;
13
+ if (!ctor || typeof foo === "object") {
14
+ len = 0;
15
+ for (ctor in foo) {
16
+ if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;
17
+ if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false;
175
18
  }
176
- if (typeof child != "object" || ancestors.has(child)) return false;
177
- pending.push({
178
- value,
179
- keys,
180
- arrayLength,
181
- index
182
- });
183
- value = child;
184
- continue traversal;
19
+ return Object.keys(bar).length === len;
185
20
  }
186
21
  }
187
- }
188
- function isJsonObject(value) {
189
- try {
190
- return value != null && typeof value == "object" && !Array.isArray(value) && hasJsonShape(value);
191
- } catch {
192
- return false;
193
- }
22
+ return foo !== foo && bar !== bar;
194
23
  }
195
24
  //#endregion
196
25
  //#region ../../node_modules/.bun/@cfworker+json-schema@4.1.1/node_modules/@cfworker/json-schema/dist/esm/deep-compare-strict.js
@@ -9263,7 +9092,7 @@ var ZodObject = /*@__PURE__*/ $constructor("ZodObject", (inst, def) => {
9263
9092
  return required(ZodNonOptional, this, args[0]);
9264
9093
  }
9265
9094
  });
9266
- function object(shape, params) {
9095
+ function object$1(shape, params) {
9267
9096
  return new ZodObject({
9268
9097
  type: "object",
9269
9098
  shape: shape ?? {},
@@ -9574,11 +9403,11 @@ function checkJsonDepth(value, depth = 0) {
9574
9403
  }
9575
9404
  //#endregion
9576
9405
  //#region src/flow/common/triggerScheduleSchema.ts
9577
- var triggerScheduleSchema = array(union([object({
9406
+ var triggerScheduleSchema = array(union([object$1({
9578
9407
  type: literal("cron"),
9579
9408
  expression: string(),
9580
9409
  timezone: string()
9581
- }), object({
9410
+ }), object$1({
9582
9411
  type: literal("every"),
9583
9412
  unit: _enum([
9584
9413
  "day",
@@ -9604,40 +9433,40 @@ function webhookSupportsBody(method) {
9604
9433
  var text = string();
9605
9434
  var json = json$1();
9606
9435
  var strings = array(text);
9607
- var port = object({
9436
+ var port = object$1({
9608
9437
  description: text.optional(),
9609
9438
  jsonSchema: json,
9610
9439
  nullable: boolean(),
9611
9440
  handle: text
9612
9441
  });
9613
9442
  var input = port.extend({ value: json.optional() });
9614
- var group = object({
9443
+ var group = object$1({
9615
9444
  collapsed: boolean().optional(),
9616
9445
  group: text
9617
9446
  });
9618
- var nodeSource = object({
9447
+ var nodeSource = object$1({
9619
9448
  kind: literal("node"),
9620
9449
  nodeId: text,
9621
9450
  output: text,
9622
9451
  field: text.optional()
9623
9452
  });
9624
- var flowSource = object({
9453
+ var flowSource = object$1({
9625
9454
  kind: literal("flow"),
9626
9455
  input: text
9627
9456
  });
9628
9457
  var source = union([
9629
9458
  nodeSource,
9630
9459
  flowSource,
9631
- object({
9460
+ object$1({
9632
9461
  kind: literal("binding"),
9633
9462
  bindingId: text
9634
9463
  })
9635
9464
  ]);
9636
- var fixedInput = union([object({ kind: literal("unset") }), object({
9465
+ var fixedInput = union([object$1({ kind: literal("unset") }), object$1({
9637
9466
  kind: literal("value"),
9638
9467
  value: json
9639
9468
  })]);
9640
- var mapping = union([fixedInput, object({
9469
+ var mapping = union([fixedInput, object$1({
9641
9470
  kind: literal("sources"),
9642
9471
  sources: array(source)
9643
9472
  })]);
@@ -9678,40 +9507,58 @@ var capability = union([
9678
9507
  })).optional()
9679
9508
  })
9680
9509
  ]);
9681
- var inline = object({
9510
+ var inline = object$1({
9682
9511
  ...ports,
9683
9512
  name: text,
9684
9513
  moduleId: text,
9685
9514
  capabilities: array(capability).optional()
9686
9515
  });
9687
- var agentValue = union([object({
9516
+ var agentValue = union([object$1({
9688
9517
  kind: literal("value"),
9689
9518
  value: json
9690
- }), object({
9519
+ }), object$1({
9691
9520
  kind: literal("input"),
9692
9521
  input: text
9693
9522
  })]);
9694
- var agentInput$1 = union([agentValue, object({ kind: literal("model") })]);
9695
- var managed = object({
9523
+ var agentInput$1 = union([agentValue, object$1({ kind: literal("model") })]);
9524
+ var managed = object$1({
9696
9525
  ...ports,
9697
9526
  name: text,
9698
9527
  executor: union([
9699
- object({
9528
+ object$1({
9700
9529
  kind: literal("connector"),
9701
9530
  action: text,
9702
9531
  connectionId: text.optional()
9703
9532
  }),
9704
- object({
9533
+ object$1({
9534
+ kind: literal("openapi"),
9535
+ sourceUrl: text,
9536
+ method: text,
9537
+ path: text,
9538
+ serverUrl: text,
9539
+ document: json,
9540
+ auth: array(object$1({
9541
+ id: text,
9542
+ type: _enum([
9543
+ "bearer",
9544
+ "basic",
9545
+ "apiKey"
9546
+ ]),
9547
+ name: text.optional(),
9548
+ in: _enum(["header", "query"]).optional()
9549
+ }))
9550
+ }),
9551
+ object$1({
9705
9552
  kind: literal("llm"),
9706
9553
  mode: _enum(["chat", "json"])
9707
9554
  }),
9708
- object({
9555
+ object$1({
9709
9556
  kind: literal("agent"),
9710
9557
  code: boolean().optional(),
9711
9558
  model: text,
9712
9559
  prompt: text,
9713
9560
  maxRounds: number(),
9714
- tools: array(object({
9561
+ tools: array(object$1({
9715
9562
  id: text,
9716
9563
  name: text,
9717
9564
  description: text,
@@ -9720,7 +9567,7 @@ var managed = object({
9720
9567
  approval: boolean(),
9721
9568
  inputs: array(input.extend({ source: agentInput$1 }))
9722
9569
  })),
9723
- notification: object({
9570
+ notification: object$1({
9724
9571
  taskId: text,
9725
9572
  messageHandle: text,
9726
9573
  inputs: record(text, agentValue)
@@ -9728,20 +9575,20 @@ var managed = object({
9728
9575
  })
9729
9576
  ])
9730
9577
  });
9731
- var operand = union([object({
9578
+ var operand = union([object$1({
9732
9579
  kind: literal("value"),
9733
9580
  value: json.optional(),
9734
9581
  jsonSchema: json.optional()
9735
- }), object({
9582
+ }), object$1({
9736
9583
  kind: literal("source"),
9737
9584
  source
9738
9585
  })]);
9739
9586
  var condition = {
9740
9587
  matchMode: _enum(["first", "all"]),
9741
- cases: array(object({
9588
+ cases: array(object$1({
9742
9589
  description: text.optional(),
9743
9590
  output: text,
9744
- groups: array(object({ expressions: array(object({
9591
+ groups: array(object$1({ expressions: array(object$1({
9745
9592
  left: operand,
9746
9593
  operator: _enum([
9747
9594
  "!=",
@@ -9773,7 +9620,7 @@ var wait = {
9773
9620
  inputDefinitions: array(input),
9774
9621
  prompt: text
9775
9622
  };
9776
- var webhookOptions = object({
9623
+ var webhookOptions = object$1({
9777
9624
  allowedMethods: never().optional(),
9778
9625
  allowedOrigins: strings.optional(),
9779
9626
  noResponseBody: never().optional(),
@@ -9796,8 +9643,8 @@ var definition = {
9796
9643
  outputs: array(port).refine((definitions) => new Set(definitions.map((output) => output.handle)).size === definitions.length, "Duplicate Trigger output handle."),
9797
9644
  provider: text
9798
9645
  };
9799
- var endpoint = object({
9800
- body: object({
9646
+ var endpoint = object$1({
9647
+ body: object$1({
9801
9648
  allowArray: boolean(),
9802
9649
  allowEmpty: boolean(),
9803
9650
  formats: array(_enum([
@@ -9817,6 +9664,7 @@ var endpoint = object({
9817
9664
  ])),
9818
9665
  successStatus: number()
9819
9666
  });
9667
+ var sourceFlowIds = array(text.min(1)).refine((ids) => new Set(ids).size === ids.length, "Duplicate source Flow ID.");
9820
9668
  var trigger = {
9821
9669
  name: text,
9822
9670
  description: text.optional(),
@@ -9831,30 +9679,30 @@ var base = {
9831
9679
  timeoutMs: number().optional()
9832
9680
  };
9833
9681
  var node = union([
9834
- object({
9682
+ object$1({
9835
9683
  ...base,
9836
9684
  inputs: record(text, never()),
9837
9685
  kind: literal("condition"),
9838
9686
  ...condition
9839
9687
  }),
9840
- object({
9688
+ object$1({
9841
9689
  ...base,
9842
9690
  inputs: unknown().transform(() => ({})).default({}),
9843
9691
  kind: literal("value"),
9844
9692
  values: array(input)
9845
9693
  }),
9846
- object({
9694
+ object$1({
9847
9695
  ...base,
9848
9696
  kind: literal("subflow"),
9849
9697
  subflowId: text
9850
9698
  }),
9851
- object({
9699
+ object$1({
9852
9700
  ...base,
9853
9701
  kind: literal("task"),
9854
9702
  task: inline,
9855
9703
  additionalInputs: array(input).optional()
9856
9704
  }),
9857
- object({
9705
+ object$1({
9858
9706
  ...base,
9859
9707
  kind: literal("task"),
9860
9708
  taskId: text,
@@ -9870,48 +9718,53 @@ var node = union([
9870
9718
  kind: literal("wait"),
9871
9719
  ...wait
9872
9720
  }).omit({ timeoutMs: true }),
9873
- object({
9721
+ object$1({
9874
9722
  ...trigger,
9875
9723
  kind: literal("manual")
9876
9724
  }),
9877
- object({
9725
+ strictObject({
9726
+ ...trigger,
9727
+ kind: literal("error"),
9728
+ sourceFlowIds: sourceFlowIds.optional()
9729
+ }),
9730
+ object$1({
9878
9731
  ...trigger,
9879
9732
  kind: literal("webhook"),
9880
9733
  ...webhook
9881
9734
  }),
9882
- object({
9735
+ object$1({
9883
9736
  ...trigger,
9884
9737
  kind: literal("cron"),
9885
9738
  cronTimes: triggerScheduleSchema
9886
9739
  }),
9887
- object({
9740
+ object$1({
9888
9741
  ...trigger,
9889
9742
  kind: literal("poll"),
9890
9743
  connectionId: text.min(1).optional(),
9891
9744
  config: record(text, fixedInput),
9892
- definition: object({
9745
+ definition: object$1({
9893
9746
  ...definition,
9894
9747
  type: literal("poll")
9895
9748
  }),
9896
9749
  pollTimes: triggerScheduleSchema
9897
9750
  }),
9898
- object({
9751
+ object$1({
9899
9752
  ...trigger,
9900
9753
  kind: literal("integration"),
9901
9754
  connectionId: text.min(1).optional(),
9902
9755
  config: record(text, fixedInput),
9903
- definition: object({
9756
+ definition: object$1({
9904
9757
  ...definition,
9905
9758
  type: literal("integration"),
9906
9759
  endpoint
9907
9760
  })
9908
9761
  })
9909
9762
  ]);
9910
- var target = union([object({ kind: literal("flow") }), object({
9763
+ var target = union([object$1({ kind: literal("flow") }), object$1({
9911
9764
  kind: literal("subflow"),
9912
9765
  id: text
9913
9766
  })]);
9914
- var edge = object({
9767
+ var edge = object$1({
9915
9768
  source: text,
9916
9769
  target: text,
9917
9770
  sourceHandle: text.optional()
@@ -9920,32 +9773,36 @@ var at = {
9920
9773
  nodeId: text,
9921
9774
  target
9922
9775
  };
9923
- var subflow = object({
9776
+ var subflow = object$1({
9924
9777
  name: text,
9925
9778
  inputs: array(input),
9926
9779
  outputs: array(port.extend({ sources: array(union([nodeSource, flowSource])) }))
9927
9780
  });
9928
- var graph = object({
9781
+ var graph = object$1({
9929
9782
  nodes: record(text, node),
9930
9783
  edges: array(edge).default([])
9931
9784
  });
9932
- var binding = object({
9785
+ var binding = object$1({
9933
9786
  kind: literal("variable"),
9934
9787
  target: text
9935
9788
  });
9936
- var module = object({
9789
+ var module = object$1({
9937
9790
  name: text,
9938
9791
  imports: strings,
9939
9792
  source: text
9940
9793
  });
9941
- var document = object({
9794
+ var document = object$1({
9942
9795
  bindings: record(text, binding),
9943
9796
  graph,
9944
9797
  subflows: record(text, subflow.extend({ graph })),
9945
9798
  tasks: record(text, managed)
9946
9799
  });
9947
- object({
9948
- modelVersion: union([literal(2), literal(4)]),
9800
+ object$1({
9801
+ modelVersion: union([
9802
+ literal(2),
9803
+ literal(4),
9804
+ literal(5)
9805
+ ]),
9949
9806
  document,
9950
9807
  modules: record(text, module)
9951
9808
  }).extend({
@@ -9953,6 +9810,11 @@ object({
9953
9810
  version: literal(1)
9954
9811
  });
9955
9812
  var shapes = {
9813
+ "graph.trigger.sources.set": {
9814
+ nodeId: text,
9815
+ before: sourceFlowIds.optional(),
9816
+ value: sourceFlowIds.optional()
9817
+ },
9956
9818
  "binding.create": {
9957
9819
  bindingId: text,
9958
9820
  binding
@@ -9977,14 +9839,14 @@ var shapes = {
9977
9839
  },
9978
9840
  "graph.node.delete": at,
9979
9841
  "graph.node.field.set": union([
9980
- object({
9842
+ object$1({
9981
9843
  ...at,
9982
9844
  kind: literal("graph.node.field.set"),
9983
9845
  field: literal("connectionId"),
9984
9846
  before: text.min(1).optional(),
9985
9847
  value: text.min(1).optional()
9986
9848
  }),
9987
- object({
9849
+ object$1({
9988
9850
  ...at,
9989
9851
  kind: literal("graph.node.field.set"),
9990
9852
  field: _enum([
@@ -9995,14 +9857,14 @@ var shapes = {
9995
9857
  before: text.optional(),
9996
9858
  value: text.optional()
9997
9859
  }),
9998
- object({
9860
+ object$1({
9999
9861
  ...at,
10000
9862
  kind: literal("graph.node.field.set"),
10001
9863
  field: literal("maxExecutions"),
10002
9864
  before: number().int().positive().max(Number.MAX_SAFE_INTEGER).optional(),
10003
9865
  value: number().int().positive().max(Number.MAX_SAFE_INTEGER).optional()
10004
9866
  }),
10005
- object({
9867
+ object$1({
10006
9868
  ...at,
10007
9869
  kind: literal("graph.node.field.set"),
10008
9870
  field: literal("timeoutMs"),
@@ -10023,8 +9885,8 @@ var shapes = {
10023
9885
  },
10024
9886
  "graph.node.condition.set": {
10025
9887
  ...at,
10026
- before: object(condition),
10027
- value: object(condition)
9888
+ before: object$1(condition),
9889
+ value: object$1(condition)
10028
9890
  },
10029
9891
  "graph.node.values.set": {
10030
9892
  ...at,
@@ -10033,20 +9895,20 @@ var shapes = {
10033
9895
  },
10034
9896
  "graph.node.resolution.set": {
10035
9897
  ...at,
10036
- target: object({ kind: literal("flow") }),
10037
- before: object(wait),
10038
- value: object(wait)
9898
+ target: object$1({ kind: literal("flow") }),
9899
+ before: object$1(wait),
9900
+ value: object$1(wait)
10039
9901
  },
10040
9902
  "graph.node.webhook.set": {
10041
9903
  ...at,
10042
- target: object({ kind: literal("flow") }),
10043
- before: object(webhook),
10044
- value: object(webhook)
9904
+ target: object$1({ kind: literal("flow") }),
9905
+ before: object$1(webhook),
9906
+ value: object$1(webhook)
10045
9907
  },
10046
9908
  "graph.node.task.ports.set": {
10047
9909
  ...at,
10048
- before: object(ports),
10049
- value: object(ports)
9910
+ before: object$1(ports),
9911
+ value: object$1(ports)
10050
9912
  },
10051
9913
  "graph.node.task.name.set": {
10052
9914
  ...at,
@@ -10106,6 +9968,11 @@ var shapes = {
10106
9968
  before: text.optional(),
10107
9969
  value: text.optional()
10108
9970
  },
9971
+ "task.openapi.set": {
9972
+ taskId: text,
9973
+ before: managed,
9974
+ value: managed
9975
+ },
10109
9976
  "task.agent.set": {
10110
9977
  taskId: text,
10111
9978
  before: managed,
@@ -10122,7 +9989,7 @@ var shapes = {
10122
9989
  value: text
10123
9990
  }
10124
9991
  };
10125
- array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, shape instanceof ZodType ? shape : object({
9992
+ array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, shape instanceof ZodType ? shape : object$1({
10126
9993
  kind: literal(kind),
10127
9994
  ...shape
10128
9995
  })])).values()])).min(1);
@@ -10465,78 +10332,689 @@ function schemaValue(schema, path) {
10465
10332
  if (value == null || typeof value != "object") return;
10466
10333
  value = Array.isArray(value) ? value[Number(part)] : schemaObject(value)?.[String(part)];
10467
10334
  }
10468
- return value;
10335
+ return value;
10336
+ }
10337
+ function schemaMismatch(source, target, result) {
10338
+ if (source.nullable && !target.nullable) return { kind: "nullable" };
10339
+ if (result.error == "edgeError.binDiffType") return { kind: "binary" };
10340
+ if (result.error == "edgeError.artifactDiffType") return { kind: "artifact" };
10341
+ const sourceSchema = schemaObject(source.jsonSchema);
10342
+ const targetSchema = schemaObject(target.jsonSchema);
10343
+ const fallbackKeyword = result.errorPath == null && sourceSchema != null && targetSchema != null ? rootMismatchKeyword(sourceSchema, targetSchema) : void 0;
10344
+ const path = fallbackKeyword == null ? result.errorPath : [fallbackKeyword];
10345
+ const keyword = path?.at(-1);
10346
+ if (typeof keyword != "string" || !isSchemaKeyword(keyword)) return {
10347
+ kind: "schema",
10348
+ path
10349
+ };
10350
+ const ownerPath = path.slice(0, -1);
10351
+ return {
10352
+ kind: "keyword",
10353
+ keyword,
10354
+ path: ownerPath,
10355
+ source: schemaValue(source.jsonSchema, [...ownerPath, keyword]),
10356
+ target: schemaValue(target.jsonSchema, [...ownerPath, keyword])
10357
+ };
10358
+ }
10359
+ function rootMismatchKeyword(source, target) {
10360
+ if (!jsonEqual(source.type, target.type)) return "type";
10361
+ if (target.const !== void 0 && !jsonEqual(source.const, target.const)) return "const";
10362
+ if (target.enum !== void 0 && !jsonEqual(source.enum, target.enum)) return "enum";
10363
+ const sourceRequired = new Set(Array.isArray(source.required) ? source.required : []);
10364
+ if (Array.isArray(target.required) && target.required.some((name) => typeof name == "string" && !sourceRequired.has(name))) return "required";
10365
+ for (const keyword of schemaConstraintKeywords) if (target[keyword] !== void 0 && !jsonEqual(source[keyword], target[keyword])) return keyword;
10366
+ }
10367
+ var schemaConstraintKeywords = [
10368
+ "minLength",
10369
+ "maxLength",
10370
+ "pattern",
10371
+ "minimum",
10372
+ "exclusiveMinimum",
10373
+ "maximum",
10374
+ "exclusiveMaximum",
10375
+ "multipleOf",
10376
+ "minItems",
10377
+ "maxItems",
10378
+ "minProperties",
10379
+ "maxProperties"
10380
+ ];
10381
+ function comparePorts(source, target) {
10382
+ const result = compareSchemas(source.jsonSchema, target.jsonSchema, source.nullable, target.nullable);
10383
+ return result.kind == "incompatible" ? {
10384
+ kind: "incompatible",
10385
+ mismatch: schemaMismatch(source, target, result)
10386
+ } : result;
10387
+ }
10388
+ function portsAssignable(source, target) {
10389
+ return comparePorts(source, target).kind == "compatible";
10390
+ }
10391
+ function variableInputCompatible(jsonSchema) {
10392
+ const schema = schemaObject(jsonSchema);
10393
+ const types = schemaList(schema?.type);
10394
+ if (schema != null && types?.includes("string")) return compareSchemas({ type: "string" }, {
10395
+ ...schema,
10396
+ type: "string"
10397
+ }).kind == "compatible";
10398
+ return compareSchemas({ type: "string" }, jsonSchema).kind == "compatible";
10399
+ }
10400
+ function hasRetiredRef(value) {
10401
+ if (value == null || typeof value != "object") return false;
10402
+ const source = value;
10403
+ return source.contentMediaType == "oomol/ref" || Object.values(source).some(hasRetiredRef);
10404
+ }
10405
+ //#endregion
10406
+ //#region src/openapi/common/openapi.ts
10407
+ var methods = [
10408
+ "get",
10409
+ "put",
10410
+ "post",
10411
+ "delete",
10412
+ "options",
10413
+ "head",
10414
+ "patch",
10415
+ "trace"
10416
+ ];
10417
+ function object(value) {
10418
+ if (value == null || typeof value != "object" || Array.isArray(value)) throw new Error("Expected an OpenAPI object.");
10419
+ return value;
10420
+ }
10421
+ function httpUrl(value, base) {
10422
+ const url = new URL(value, base);
10423
+ if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.hash) throw new Error("An HTTP(S) URL without credentials or fragment is required.");
10424
+ return url.href;
10425
+ }
10426
+ function parseOpenApi(value) {
10427
+ const doc = object(value);
10428
+ if (typeof doc.openapi != "string" || !/^3\.[01]\.\d+$/.test(doc.openapi)) throw new Error("Only OpenAPI 3.0 and 3.1 JSON documents are supported.");
10429
+ object(doc.paths);
10430
+ return doc;
10431
+ }
10432
+ function pointer(doc, ref) {
10433
+ if (!ref.startsWith("#/")) throw new Error("External OpenAPI references are not supported.");
10434
+ let value = doc;
10435
+ for (const key of decodeURIComponent(ref.slice(2)).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~"))) {
10436
+ const source = object(value);
10437
+ if (!Object.hasOwn(source, key)) throw new Error("An OpenAPI reference is missing.");
10438
+ value = source[key];
10439
+ }
10440
+ return value;
10441
+ }
10442
+ function resolved(doc, value) {
10443
+ let result = object(value);
10444
+ const seen = /* @__PURE__ */ new Set();
10445
+ while (typeof result.$ref == "string") {
10446
+ if (seen.has(result.$ref)) throw new Error("Circular non-schema reference is unsupported.");
10447
+ seen.add(result.$ref);
10448
+ const { $ref, ...siblings } = result;
10449
+ result = {
10450
+ ...object(pointer(doc, $ref)),
10451
+ ...siblings
10452
+ };
10453
+ }
10454
+ return result;
10455
+ }
10456
+ function operation(doc, path, method) {
10457
+ const item = resolved(doc, object(doc.paths)[path]);
10458
+ if (!methods.includes(method) || item[method] == null) throw new Error("The selected operation is no longer available.");
10459
+ return {
10460
+ item,
10461
+ op: object(item[method])
10462
+ };
10463
+ }
10464
+ function servers(value, path, method) {
10465
+ const doc = parseOpenApi(value);
10466
+ const { item, op } = operation(doc, path, method);
10467
+ const entries = op.servers ?? item.servers ?? doc.servers;
10468
+ if (!Array.isArray(entries) || entries.length == 0) return [{ url: "/" }];
10469
+ return entries.map(object);
10470
+ }
10471
+ function snapshot(documentValue, path, method) {
10472
+ const doc = parseOpenApi(documentValue);
10473
+ const { item, op } = operation(doc, path, method);
10474
+ const security = op.security ?? doc.security ?? [];
10475
+ const result = {
10476
+ openapi: doc.openapi,
10477
+ paths: { [path]: {
10478
+ [method]: op,
10479
+ ...item.parameters == null ? {} : { parameters: item.parameters }
10480
+ } },
10481
+ servers: servers(doc, path, method),
10482
+ security
10483
+ };
10484
+ const visited = /* @__PURE__ */ new Set();
10485
+ function copy(ref) {
10486
+ if (visited.has(ref)) return;
10487
+ visited.add(ref);
10488
+ const value = pointer(doc, ref);
10489
+ const keys = decodeURIComponent(ref.slice(2)).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~"));
10490
+ if (keys.some((key) => [
10491
+ "__proto__",
10492
+ "constructor",
10493
+ "prototype"
10494
+ ].includes(key))) throw new Error("Unsupported reference key.");
10495
+ let target = result;
10496
+ for (const key of keys.slice(0, -1)) {
10497
+ if (!Object.hasOwn(target, key)) target[key] = {};
10498
+ target = object(target[key]);
10499
+ }
10500
+ target[keys.at(-1)] = structuredClone(value);
10501
+ visit(value);
10502
+ }
10503
+ function visit(value) {
10504
+ if (value == null || typeof value != "object") return;
10505
+ if (Array.isArray(value)) {
10506
+ value.forEach(visit);
10507
+ return;
10508
+ }
10509
+ if (typeof object(value).$ref == "string") copy(object(value).$ref);
10510
+ for (const [key, child] of Object.entries(value)) if (![
10511
+ "example",
10512
+ "examples",
10513
+ "default"
10514
+ ].includes(key)) visit(child);
10515
+ }
10516
+ visit(result);
10517
+ for (const entry of security) for (const name of Object.keys(object(entry))) copy(`#/components/securitySchemes/${name.replace(/~/g, "~0").replace(/\//g, "~1")}`);
10518
+ return structuredClone(result);
10519
+ }
10520
+ function schema$1(doc, schemaValue) {
10521
+ const defs = {};
10522
+ const ids = /* @__PURE__ */ new Map();
10523
+ function convert(value) {
10524
+ if (typeof value == "boolean") return value;
10525
+ const source = object(value);
10526
+ if (source.format == "binary" || source.$dynamicRef != null || source.$id != null) throw new Error("Binary and dynamically scoped schemas are unsupported.");
10527
+ const result = {};
10528
+ for (const [key, child] of Object.entries(source)) {
10529
+ if ([
10530
+ "nullable",
10531
+ "example",
10532
+ "xml",
10533
+ "discriminator",
10534
+ "__proto__"
10535
+ ].includes(key)) continue;
10536
+ if (key == "$ref") {
10537
+ if (typeof child != "string") throw new Error("Invalid schema reference.");
10538
+ let id = ids.get(child);
10539
+ if (id == null) {
10540
+ id = `s${ids.size}`;
10541
+ ids.set(child, id);
10542
+ defs[id] = convert(pointer(doc, child));
10543
+ }
10544
+ result.$ref = `#/$defs/${id}`;
10545
+ } else if ([
10546
+ "properties",
10547
+ "patternProperties",
10548
+ "$defs",
10549
+ "definitions",
10550
+ "dependentSchemas"
10551
+ ].includes(key)) result[key] = Object.fromEntries(Object.entries(object(child)).map(([name, childSchema]) => [name, convert(childSchema)]));
10552
+ else if ([
10553
+ "allOf",
10554
+ "anyOf",
10555
+ "oneOf",
10556
+ "prefixItems"
10557
+ ].includes(key)) {
10558
+ if (!Array.isArray(child)) throw new Error("Invalid schema composition.");
10559
+ result[key] = child.map(convert);
10560
+ } else if ([
10561
+ "items",
10562
+ "additionalProperties",
10563
+ "not",
10564
+ "if",
10565
+ "then",
10566
+ "else",
10567
+ "contains",
10568
+ "propertyNames",
10569
+ "unevaluatedProperties"
10570
+ ].includes(key)) result[key] = convert(child);
10571
+ else result[key] = child;
10572
+ }
10573
+ if (source.nullable === true) return { anyOf: [result, { type: "null" }] };
10574
+ for (const key of ["minimum", "maximum"]) {
10575
+ const exclusive = key == "minimum" ? "exclusiveMinimum" : "exclusiveMaximum";
10576
+ if (typeof result[exclusive] == "boolean") {
10577
+ if (result[exclusive] && typeof result[key] == "number") {
10578
+ result[exclusive] = result[key];
10579
+ delete result[key];
10580
+ } else delete result[exclusive];
10581
+ }
10582
+ }
10583
+ return result;
10584
+ }
10585
+ let converted = convert(schemaValue);
10586
+ if (typeof converted == "object" && converted != null && typeof object(converted).$ref == "string") {
10587
+ const id = String(object(converted).$ref).slice(8);
10588
+ const { $ref: _ref, ...siblings } = object(converted);
10589
+ converted = {
10590
+ ...object(defs[id]),
10591
+ ...siblings
10592
+ };
10593
+ }
10594
+ if (typeof converted == "boolean") return converted;
10595
+ return {
10596
+ $schema: "https://json-schema.org/draft/2020-12/schema",
10597
+ ...object(converted),
10598
+ ...Object.keys(defs).length ? { $defs: defs } : {}
10599
+ };
10600
+ }
10601
+ function parameters(config) {
10602
+ const doc = parseOpenApi(config.document);
10603
+ const { item, op } = operation(doc, config.path, config.method);
10604
+ const entries = /* @__PURE__ */ new Map();
10605
+ for (const value of [...item.parameters ?? [], ...op.parameters ?? []]) {
10606
+ const p = resolved(doc, value);
10607
+ if (![
10608
+ "path",
10609
+ "query",
10610
+ "header"
10611
+ ].includes(String(p.in)) || typeof p.name != "string" || p.content != null) throw new Error("Only schema-based path, query and header parameters are supported.");
10612
+ if (p.allowReserved === true) throw new Error("allowReserved parameters are unsupported.");
10613
+ if ((p.style ?? (p.in == "query" ? "form" : "simple")) != (p.in == "query" ? "form" : "simple")) throw new Error("Only form query and simple path/header serialization are supported.");
10614
+ entries.set(`${p.in}.${p.in == "header" ? p.name.toLowerCase() : p.name}`, p);
10615
+ }
10616
+ return [...entries.values()];
10617
+ }
10618
+ function jsonContent(doc, value) {
10619
+ const content = resolved(doc, value);
10620
+ const media = object(content.content);
10621
+ const mediaType = media["application/json"] != null ? "application/json" : Object.keys(media).find((key) => /^application\/.+\+json$/.test(key));
10622
+ const json = mediaType == null ? void 0 : media[mediaType];
10623
+ if (json == null) throw new Error("Only JSON request and response bodies are supported.");
10624
+ return {
10625
+ schema: schema$1(doc, object(json).schema ?? {}),
10626
+ required: content.required === true,
10627
+ mediaType
10628
+ };
10629
+ }
10630
+ function authHandles(auth) {
10631
+ return auth.flatMap((scheme) => scheme.type == "basic" ? [`auth.${scheme.id}.username`, `auth.${scheme.id}.password`] : [`auth.${scheme.id}.token`]);
10632
+ }
10633
+ function openApiTask(config, name = "OpenAPI") {
10634
+ if (!config.path) return {
10635
+ name,
10636
+ executor: config,
10637
+ inputs: [],
10638
+ outputs: []
10639
+ };
10640
+ const doc = parseOpenApi(config.document);
10641
+ const { op } = operation(doc, config.path, config.method);
10642
+ const params = parameters(config);
10643
+ const inputs = params.map((p) => {
10644
+ const jsonSchema = schema$1(doc, p.schema ?? {});
10645
+ const defaultValue = typeof jsonSchema == "boolean" ? void 0 : object(jsonSchema).default;
10646
+ return {
10647
+ handle: `${p.in}.${p.name}`,
10648
+ jsonSchema,
10649
+ nullable: p.required !== true && p.in != "path" || matchesSchema(null, jsonSchema),
10650
+ ...typeof p.description == "string" ? { description: p.description } : {},
10651
+ ...defaultValue === void 0 ? {} : { value: defaultValue }
10652
+ };
10653
+ });
10654
+ if (op.requestBody != null) {
10655
+ if (config.method == "get" || config.method == "head") throw new Error("GET and HEAD request bodies are unsupported.");
10656
+ const body = jsonContent(doc, op.requestBody);
10657
+ inputs.push({
10658
+ handle: "body",
10659
+ jsonSchema: body.schema,
10660
+ nullable: !body.required || matchesSchema(null, body.schema)
10661
+ });
10662
+ }
10663
+ const occupied = new Set(params.map((p) => `${p.in}.${p.in == "header" ? String(p.name).toLowerCase() : p.name}`));
10664
+ for (const auth of config.auth) {
10665
+ const location = auth.type == "apiKey" ? `${auth.in}.${auth.in == "header" ? auth.name?.toLowerCase() : auth.name}` : "header.authorization";
10666
+ if (occupied.has(location)) throw new Error("Authentication conflicts with a parameter or another security scheme.");
10667
+ if (auth.type == "apiKey" && (!auth.name || !["header", "query"].includes(auth.in ?? ""))) throw new Error("API Key requires a name and location.");
10668
+ occupied.add(location);
10669
+ }
10670
+ inputs.push(...authHandles(config.auth).map((handle) => ({
10671
+ handle,
10672
+ jsonSchema: { type: "string" },
10673
+ nullable: false
10674
+ })));
10675
+ const responses = object(op.responses);
10676
+ const schemas = [];
10677
+ for (const [status, response] of Object.entries(responses)) if (/^2\d\d$|^2XX$/.test(status) || status == "default") {
10678
+ const r = resolved(doc, response);
10679
+ if (r.content == null) schemas.push({ type: "null" });
10680
+ else {
10681
+ jsonContent(doc, r);
10682
+ for (const [mediaType, media] of Object.entries(object(r.content))) if (/^application\/(json|.+\+json)$/.test(mediaType)) schemas.push(schema$1(doc, object(media).schema ?? {}));
10683
+ }
10684
+ }
10685
+ if (!schemas.length) throw new Error("A successful JSON response definition is required.");
10686
+ return {
10687
+ name,
10688
+ executor: config,
10689
+ inputs,
10690
+ outputs: [
10691
+ {
10692
+ handle: "body",
10693
+ jsonSchema: schemas.length == 1 ? schemas[0] : {
10694
+ $schema: "https://json-schema.org/draft/2020-12/schema",
10695
+ anyOf: schemas.map((s, index) => inlineSchema(s, index))
10696
+ },
10697
+ nullable: config.method == "head" || schemas.some((item) => matchesSchema(null, item))
10698
+ },
10699
+ {
10700
+ handle: "statusCode",
10701
+ jsonSchema: { type: "integer" },
10702
+ nullable: false
10703
+ },
10704
+ {
10705
+ handle: "headers",
10706
+ jsonSchema: {
10707
+ type: "object",
10708
+ additionalProperties: { type: "string" }
10709
+ },
10710
+ nullable: false
10711
+ }
10712
+ ]
10713
+ };
10714
+ }
10715
+ function inlineSchema(value, index) {
10716
+ if (Array.isArray(value)) return value.map((item) => inlineSchema(item, index));
10717
+ if (value == null || typeof value != "object") return value;
10718
+ return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, key == "$ref" && typeof child == "string" && child.startsWith("#/") ? `#/anyOf/${index}/${child.slice(2)}` : inlineSchema(child, index)]));
10719
+ }
10720
+ /** The canvas validator and property panel share the same configuration contract. */
10721
+ function openApiFieldIssues(task) {
10722
+ if (task.executor.kind != "openapi") return [];
10723
+ const config = task.executor;
10724
+ let field = "sourceUrl";
10725
+ try {
10726
+ if (!config.sourceUrl.trim()) return [{
10727
+ field,
10728
+ message: "Enter an OpenAPI JSON document URL."
10729
+ }];
10730
+ httpUrl(config.sourceUrl);
10731
+ field = "operation";
10732
+ if (!config.path) return [{
10733
+ field,
10734
+ message: "Select an OpenAPI operation."
10735
+ }];
10736
+ field = "serverUrl";
10737
+ httpUrl(config.serverUrl);
10738
+ if (new URL(config.serverUrl).search) throw new Error("Server URLs must not contain a query string.");
10739
+ field = "operation";
10740
+ if (!dequal(config.document, snapshot(config.document, config.path, config.method))) return [{
10741
+ field,
10742
+ message: "Save only the selected operation and its dependencies."
10743
+ }];
10744
+ const expected = openApiTask(config, task.name);
10745
+ if (!dequal(expected.inputs, task.inputs) || !dequal(expected.outputs, task.outputs)) return [{
10746
+ field,
10747
+ message: "OpenAPI ports must match the saved operation."
10748
+ }];
10749
+ return [];
10750
+ } catch (error) {
10751
+ return [{
10752
+ field,
10753
+ message: error.message
10754
+ }];
10755
+ }
10756
+ }
10757
+ function openApiIssues(task) {
10758
+ return openApiFieldIssues(task).map((issue) => issue.message);
10759
+ }
10760
+ //#endregion
10761
+ //#region src/flow/common/promptTemplate.ts
10762
+ var promptReferencePattern = /\{\{\s*([^{}\s]+)\s*\}\}/g;
10763
+ function renderPrompt(template, input) {
10764
+ return template.replace(promptReferencePattern, (match, name) => {
10765
+ if (!Object.hasOwn(input, name)) return match;
10766
+ const value = input[name];
10767
+ return typeof value == "string" ? value : JSON.stringify(value);
10768
+ });
10769
+ }
10770
+ //#endregion
10771
+ //#region src/flow/common/connectionUsage.ts
10772
+ function connectionUsage(document) {
10773
+ const uses = [];
10774
+ const graphs = [{
10775
+ graph: document.graph,
10776
+ target: { kind: "flow" },
10777
+ name: ""
10778
+ }, ...Object.entries(document.subflows).map(([id, subflow]) => ({
10779
+ graph: subflow.graph,
10780
+ target: {
10781
+ kind: "subflow",
10782
+ id
10783
+ },
10784
+ name: subflow.name
10785
+ }))];
10786
+ for (const { graph, target, name: graphName } of graphs) for (const [nodeId, node] of Object.entries(graph.nodes)) {
10787
+ const task = node.kind == "task" && node.taskId != null ? document.tasks[node.taskId] : void 0;
10788
+ const name = [graphName, node.name ?? task?.name ?? nodeId].filter(Boolean).join(" / ");
10789
+ const add = (kind, actionId, connectionId) => {
10790
+ uses.push({
10791
+ kind,
10792
+ providerId: actionId.split(".")[0],
10793
+ actionId,
10794
+ connectionId,
10795
+ nodeId,
10796
+ name,
10797
+ target
10798
+ });
10799
+ };
10800
+ if (node.kind == "poll" || node.kind == "integration") uses.push({
10801
+ kind: "trigger",
10802
+ providerId: node.definition.provider,
10803
+ connectionId: node.connectionId,
10804
+ nodeId,
10805
+ name,
10806
+ target
10807
+ });
10808
+ if (task?.executor.kind == "connector") add("connector", task.executor.action, task.executor.connectionId);
10809
+ if (node.kind == "task" && node.task != null) {
10810
+ for (const capability of node.task.capabilities ?? []) if ("mode" in capability && capability.mode == "independent") for (const action of capability.actions) add("code", action.action, action.connectionId);
10811
+ }
10812
+ if (task?.executor.kind == "agent") {
10813
+ for (const tool of task.executor.tools) add("agent", tool.action, tool.connectionId);
10814
+ const notification = task.executor.notification == null ? void 0 : document.tasks[task.executor.notification.taskId]?.executor;
10815
+ if (notification?.kind == "connector") add("notification", notification.action, notification.connectionId);
10816
+ }
10817
+ }
10818
+ return uses;
10469
10819
  }
10470
- function schemaMismatch(source, target, result) {
10471
- if (source.nullable && !target.nullable) return { kind: "nullable" };
10472
- if (result.error == "edgeError.binDiffType") return { kind: "binary" };
10473
- if (result.error == "edgeError.artifactDiffType") return { kind: "artifact" };
10474
- const sourceSchema = schemaObject(source.jsonSchema);
10475
- const targetSchema = schemaObject(target.jsonSchema);
10476
- const fallbackKeyword = result.errorPath == null && sourceSchema != null && targetSchema != null ? rootMismatchKeyword(sourceSchema, targetSchema) : void 0;
10477
- const path = fallbackKeyword == null ? result.errorPath : [fallbackKeyword];
10478
- const keyword = path?.at(-1);
10479
- if (typeof keyword != "string" || !isSchemaKeyword(keyword)) return {
10480
- kind: "schema",
10481
- path
10482
- };
10483
- const ownerPath = path.slice(0, -1);
10820
+ function removeConnectionUsage(content, connectionId) {
10821
+ const document = content.document;
10484
10822
  return {
10485
- kind: "keyword",
10486
- keyword,
10487
- path: ownerPath,
10488
- source: schemaValue(source.jsonSchema, [...ownerPath, keyword]),
10489
- target: schemaValue(target.jsonSchema, [...ownerPath, keyword])
10823
+ ...content,
10824
+ document: {
10825
+ ...document,
10826
+ tasks: Object.fromEntries(Object.entries(document.tasks).map(([id, task]) => {
10827
+ const executor = task.executor;
10828
+ if (executor.kind == "connector" && executor.connectionId == connectionId) {
10829
+ const { connectionId: _, ...next } = executor;
10830
+ return [id, {
10831
+ ...task,
10832
+ executor: next
10833
+ }];
10834
+ }
10835
+ if (executor.kind == "agent") return [id, {
10836
+ ...task,
10837
+ executor: {
10838
+ ...executor,
10839
+ tools: executor.tools.map((tool) => {
10840
+ if (tool.connectionId != connectionId) return tool;
10841
+ const { connectionId: _, ...next } = tool;
10842
+ return next;
10843
+ })
10844
+ }
10845
+ }];
10846
+ return [id, task];
10847
+ })),
10848
+ graph: clearNodeConnections(document.graph, connectionId),
10849
+ subflows: Object.fromEntries(Object.entries(document.subflows).map(([id, subflow]) => [id, {
10850
+ ...subflow,
10851
+ graph: clearNodeConnections(subflow.graph, connectionId)
10852
+ }]))
10853
+ }
10490
10854
  };
10491
10855
  }
10492
- function rootMismatchKeyword(source, target) {
10493
- if (!jsonEqual(source.type, target.type)) return "type";
10494
- if (target.const !== void 0 && !jsonEqual(source.const, target.const)) return "const";
10495
- if (target.enum !== void 0 && !jsonEqual(source.enum, target.enum)) return "enum";
10496
- const sourceRequired = new Set(Array.isArray(source.required) ? source.required : []);
10497
- if (Array.isArray(target.required) && target.required.some((name) => typeof name == "string" && !sourceRequired.has(name))) return "required";
10498
- for (const keyword of schemaConstraintKeywords) if (target[keyword] !== void 0 && !jsonEqual(source[keyword], target[keyword])) return keyword;
10499
- }
10500
- var schemaConstraintKeywords = [
10501
- "minLength",
10502
- "maxLength",
10503
- "pattern",
10504
- "minimum",
10505
- "exclusiveMinimum",
10506
- "maximum",
10507
- "exclusiveMaximum",
10508
- "multipleOf",
10509
- "minItems",
10510
- "maxItems",
10511
- "minProperties",
10512
- "maxProperties"
10513
- ];
10514
- function comparePorts(source, target) {
10515
- const result = compareSchemas(source.jsonSchema, target.jsonSchema, source.nullable, target.nullable);
10516
- return result.kind == "incompatible" ? {
10517
- kind: "incompatible",
10518
- mismatch: schemaMismatch(source, target, result)
10519
- } : result;
10520
- }
10521
- function portsAssignable(source, target) {
10522
- return comparePorts(source, target).kind == "compatible";
10856
+ function clearNodeConnections(graph, connectionId) {
10857
+ return {
10858
+ ...graph,
10859
+ nodes: Object.fromEntries(Object.entries(graph.nodes).map(([id, node]) => {
10860
+ if ((node.kind == "poll" || node.kind == "integration") && node.connectionId == connectionId) {
10861
+ const { connectionId: _, ...remaining } = node;
10862
+ return [id, remaining];
10863
+ }
10864
+ if (node.kind != "task" || node.task == null) return [id, node];
10865
+ const capabilities = node.task.capabilities?.map((capability) => {
10866
+ if (!("mode" in capability) || capability.mode != "independent") return capability;
10867
+ return {
10868
+ ...capability,
10869
+ actions: capability.actions.map((action) => {
10870
+ if (action.connectionId != connectionId) return action;
10871
+ const { connectionId: _, ...remaining } = action;
10872
+ return remaining;
10873
+ })
10874
+ };
10875
+ });
10876
+ return [id, capabilities == null ? node : {
10877
+ ...node,
10878
+ task: {
10879
+ ...node.task,
10880
+ capabilities
10881
+ }
10882
+ }];
10883
+ }))
10884
+ };
10523
10885
  }
10524
- function variableInputCompatible(jsonSchema) {
10525
- const schema = schemaObject(jsonSchema);
10526
- const types = schemaList(schema?.type);
10527
- if (schema != null && types?.includes("string")) return compareSchemas({ type: "string" }, {
10528
- ...schema,
10529
- type: "string"
10530
- }).kind == "compatible";
10531
- return compareSchemas({ type: "string" }, jsonSchema).kind == "compatible";
10886
+ //#endregion
10887
+ //#region src/base/common/json.ts
10888
+ function hasJsonShape(root) {
10889
+ if (root === null || typeof root == "boolean" || typeof root == "string") return true;
10890
+ if (typeof root == "number") return Number.isFinite(root);
10891
+ if (typeof root != "object") return false;
10892
+ const ancestors = /* @__PURE__ */ new Set();
10893
+ const pending = [];
10894
+ let value = root;
10895
+ traversal: while (true) {
10896
+ let keys;
10897
+ let arrayLength;
10898
+ if (Array.isArray(value)) {
10899
+ arrayLength = value.length;
10900
+ keys = Reflect.ownKeys(value);
10901
+ if (keys.length != arrayLength + 1) return false;
10902
+ } else {
10903
+ const prototype = Reflect.getPrototypeOf(value);
10904
+ if (prototype != Object.prototype && prototype != null) return false;
10905
+ keys = Reflect.ownKeys(value);
10906
+ arrayLength = void 0;
10907
+ }
10908
+ ancestors.add(value);
10909
+ let index = 0;
10910
+ while (true) {
10911
+ if (index >= keys.length) {
10912
+ ancestors.delete(value);
10913
+ const parent = pending.pop();
10914
+ if (parent === void 0) return true;
10915
+ value = parent.value;
10916
+ keys = parent.keys;
10917
+ arrayLength = parent.arrayLength;
10918
+ index = parent.index;
10919
+ continue;
10920
+ }
10921
+ const key = keys[index++];
10922
+ if (arrayLength !== void 0) {
10923
+ if (key == "length") continue;
10924
+ if (typeof key != "string") return false;
10925
+ const arrayIndex = Number(key);
10926
+ if (!Number.isSafeInteger(arrayIndex) || arrayIndex < 0 || arrayIndex >= arrayLength || String(arrayIndex) != key) return false;
10927
+ } else if (typeof key != "string") return false;
10928
+ const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
10929
+ if (descriptor?.enumerable != true || !Object.hasOwn(descriptor, "value")) return false;
10930
+ const child = descriptor.value;
10931
+ if (child === null || typeof child == "boolean" || typeof child == "string") continue;
10932
+ if (typeof child == "number") {
10933
+ if (!Number.isFinite(child)) return false;
10934
+ continue;
10935
+ }
10936
+ if (typeof child != "object" || ancestors.has(child)) return false;
10937
+ pending.push({
10938
+ value,
10939
+ keys,
10940
+ arrayLength,
10941
+ index
10942
+ });
10943
+ value = child;
10944
+ continue traversal;
10945
+ }
10946
+ }
10532
10947
  }
10533
- function hasRetiredRef(value) {
10534
- if (value == null || typeof value != "object") return false;
10535
- const source = value;
10536
- return source.contentMediaType == "oomol/ref" || Object.values(source).some(hasRetiredRef);
10948
+ function isJsonObject(value) {
10949
+ try {
10950
+ return value != null && typeof value == "object" && !Array.isArray(value) && hasJsonShape(value);
10951
+ } catch {
10952
+ return false;
10953
+ }
10537
10954
  }
10538
10955
  //#endregion
10539
10956
  //#region src/trigger/common/contract.ts
10957
+ var errorOutputs = [
10958
+ {
10959
+ handle: "workflow",
10960
+ nullable: false,
10961
+ jsonSchema: {
10962
+ type: "object",
10963
+ additionalProperties: false,
10964
+ required: [
10965
+ "flowId",
10966
+ "name",
10967
+ "revisionId",
10968
+ "publicationId"
10969
+ ],
10970
+ properties: {
10971
+ flowId: { type: "string" },
10972
+ name: { type: "string" },
10973
+ revisionId: { type: "string" },
10974
+ publicationId: { type: ["string", "null"] }
10975
+ }
10976
+ }
10977
+ },
10978
+ {
10979
+ handle: "execution",
10980
+ nullable: false,
10981
+ jsonSchema: {
10982
+ type: "object",
10983
+ additionalProperties: false,
10984
+ required: [
10985
+ "runId",
10986
+ "status",
10987
+ "startedAt",
10988
+ "finishedAt"
10989
+ ],
10990
+ properties: {
10991
+ runId: { type: "string" },
10992
+ status: { enum: ["failed", "indeterminate"] },
10993
+ startedAt: { type: ["string", "null"] },
10994
+ finishedAt: { type: "string" }
10995
+ }
10996
+ }
10997
+ },
10998
+ {
10999
+ handle: "error",
11000
+ nullable: false,
11001
+ jsonSchema: {
11002
+ type: "object",
11003
+ additionalProperties: false,
11004
+ required: ["code", "message"],
11005
+ properties: {
11006
+ code: { type: "string" },
11007
+ message: { type: "string" },
11008
+ nodeId: { type: "string" },
11009
+ jobId: { type: "string" },
11010
+ path: {
11011
+ type: "array",
11012
+ items: { type: "string" }
11013
+ }
11014
+ }
11015
+ }
11016
+ }
11017
+ ];
10540
11018
  var webhookOutputs = [
10541
11019
  {
10542
11020
  handle: "headers",
@@ -10581,6 +11059,7 @@ var cronOutputs = [{
10581
11059
  }];
10582
11060
  function triggerOutputDefinitions(trigger) {
10583
11061
  switch (trigger.kind) {
11062
+ case "error": return errorOutputs;
10584
11063
  case "manual": return [];
10585
11064
  case "cron": return cronOutputs;
10586
11065
  case "poll":
@@ -11179,6 +11658,10 @@ function canonicalTriggerNode(trigger) {
11179
11658
  name: trigger.name
11180
11659
  });
11181
11660
  switch (trigger.kind) {
11661
+ case "error": return {
11662
+ ...common(trigger.kind),
11663
+ ...trigger.sourceFlowIds == null ? {} : { sourceFlowIds: [...trigger.sourceFlowIds] }
11664
+ };
11182
11665
  case "manual": return common(trigger.kind);
11183
11666
  case "webhook": return {
11184
11667
  ...common(trigger.kind),
@@ -11296,7 +11779,7 @@ function validateTrigger(triggerId, trigger, path, diagnostics) {
11296
11779
  }
11297
11780
  return;
11298
11781
  }
11299
- if (trigger.kind == "cron" || trigger.kind == "manual") return;
11782
+ if (trigger.kind == "error" || trigger.kind == "cron" || trigger.kind == "manual") return;
11300
11783
  if (trigger.connectionId == null) diagnostics.push(graphDiagnostic("trigger.connection-missing", "Select a connection account for this Trigger.", `${path}/connectionId`));
11301
11784
  const missingConfig = missingTriggerConfig(trigger.definition.configInputs, trigger.config);
11302
11785
  if (missingConfig.length > 0) diagnostics.push({
@@ -11320,6 +11803,7 @@ function nodeInputPorts(document, node) {
11320
11803
  case "cron":
11321
11804
  case "integration":
11322
11805
  case "poll":
11806
+ case "error":
11323
11807
  case "manual":
11324
11808
  case "webhook": return {};
11325
11809
  }
@@ -11370,6 +11854,7 @@ function nodeOutputPorts(document, node) {
11370
11854
  case "cron":
11371
11855
  case "integration":
11372
11856
  case "poll":
11857
+ case "error":
11373
11858
  case "manual":
11374
11859
  case "webhook": return triggerOutputPorts(node);
11375
11860
  }
@@ -11587,6 +12072,8 @@ function validateResolution(nodeId, node, allowed, path, diagnostics) {
11587
12072
  }
11588
12073
  function validateGraph(graph, document, flowInputs, allowTriggers, path, diagnostics) {
11589
12074
  const analysis = graphPaths(graph);
12075
+ const errorTriggers = Object.entries(graph.nodes).filter(([, node]) => node.kind == "error");
12076
+ if (errorTriggers.length > 1) for (const [nodeId] of errorTriggers) diagnostics.push(graphDiagnostic("graph.error-trigger-duplicate", "A graph can contain only one Flow Error node.", `${path}/nodes/${nodeId}`));
11590
12077
  const manualTriggers = Object.entries(graph.nodes).filter(([, node]) => node.kind == "manual");
11591
12078
  if (manualTriggers.length > 1) for (const [nodeId] of manualTriggers) diagnostics.push(graphDiagnostic("graph.manual-trigger-duplicate", "A graph can contain only one manual Trigger.", `${path}/nodes/${nodeId}`));
11592
12079
  const seen = /* @__PURE__ */ new Set();
@@ -23557,6 +24044,26 @@ async function validateFlow(revision, engine) {
23557
24044
  for (const taskId of [...closure.dependencies.tasks].toSorted()) {
23558
24045
  const task = revision.document.tasks[taskId];
23559
24046
  if (task == null) continue;
24047
+ for (const message of openApiIssues(task)) checked.diagnostics.push({
24048
+ code: "openapi.config-invalid",
24049
+ column: 0,
24050
+ line: 1,
24051
+ message,
24052
+ path: `/document/tasks/${taskId}/executor`
24053
+ });
24054
+ if (task.executor.kind == "openapi") {
24055
+ const handles = authHandles(task.executor.auth);
24056
+ for (const [graphPath, graph] of graphs) for (const [nodeId, node] of Object.entries(graph.nodes)) if (node.kind == "task" && node.taskId == taskId) for (const handle of handles) {
24057
+ const mapping = node.inputs[handle];
24058
+ if (mapping?.kind != "sources" || mapping.sources.length == 0 || mapping.sources.some((source) => source.kind == "flow")) checked.diagnostics.push({
24059
+ code: "openapi.auth-source",
24060
+ column: 0,
24061
+ line: 1,
24062
+ message: "Authentication requires a deployment variable or upstream output.",
24063
+ path: `${graphPath}/nodes/${nodeId}/inputs/${handle}`
24064
+ });
24065
+ }
24066
+ }
23560
24067
  for (const message of agentConfigIssues(task, revision.document.tasks)) checked.diagnostics.push({
23561
24068
  code: "agent.config-invalid",
23562
24069
  column: 0,