@oomol-lab/open-flow 0.1.0-beta.56 → 0.1.0-beta.57

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 (36) hide show
  1. package/dist/browser/{createResourceDialog-Btjes3wD.js → createResourceDialog-C23SBjYd.js} +2 -2
  2. package/dist/browser/flow-authoring-node.d.ts +6 -2
  3. package/dist/browser/flow-authoring.js +44 -12
  4. package/dist/browser/flow-change-schema.d.ts +266 -0
  5. package/dist/browser/flow-change.d.ts +5 -0
  6. package/dist/browser/flow-change.js +33 -2
  7. package/dist/browser/{flowChanges-BxutPLYO.js → flowChanges-fBiAeTzR.js} +954 -487
  8. package/dist/browser/{flowWorkspace-Dg4mqfa6.js → flowWorkspace-MqcEfg7T.js} +3 -3
  9. package/dist/browser/{icons-p2A9zs8t.js → icons-6oQ8Q9Wm.js} +4298 -4252
  10. package/dist/browser/preview.js +354 -36
  11. package/dist/browser/workbench.js +21 -10
  12. package/dist/browser/{workbenchSelect-LRp_Xjeq.js → workbenchSelect-DpLbIr29.js} +1 -1
  13. package/dist/common/authoring.d.ts +207 -0
  14. package/dist/common/authoringSchema.d.ts +1293 -0
  15. package/dist/common/control-api-conformance.js +975 -505
  16. package/dist/common/control-api-errors.d.ts +2 -1
  17. package/dist/common/control-api.d.ts +81 -0
  18. package/dist/common/control-api.js +973 -586
  19. package/dist/common/control-requests.d.ts +128 -0
  20. package/dist/common/control-requests.js +3122 -346
  21. package/dist/common/decision.js +12 -2
  22. package/dist/common/flow-encoding.js +12 -2
  23. package/dist/common/flow-semantics.d.ts +9 -0
  24. package/dist/common/flow-semantics.js +28 -3
  25. package/dist/common/integration-trigger.js +12 -2
  26. package/dist/common/lib-DrKav3HG.js +11403 -0
  27. package/dist/common/mcp.d.ts +120 -11
  28. package/dist/common/mcp.js +423 -51
  29. package/dist/common/openapi.js +12 -2
  30. package/dist/common/poll-trigger.js +12 -2
  31. package/dist/common/scheduler.js +12 -2
  32. package/dist/common/webhook-trigger.js +12 -2
  33. package/package.json +7 -1
  34. package/skills/open-flow/SKILL.md +32 -0
  35. package/skills/open-flow/references/flow-authoring.md +356 -0
  36. package/skills/open-flow/references/flow-n8n-conversion.md +196 -0
@@ -265,7 +265,7 @@ function safeExtend(schema, shape) {
265
265
  if (!isPlainObject$1(shape)) throw new Error("Invalid input to safeExtend: expected a plain object");
266
266
  return clone(schema, mergeDefs(schema._zod.def, { shape: extended(schema, shape) }));
267
267
  }
268
- function merge(a, b) {
268
+ function merge$1(a, b) {
269
269
  if (!b?._zod?.def) throw new Error("Invalid input to merge: expected an object schema. To merge a plain shape, use `.extend()`.");
270
270
  if (a._zod.def.checks?.length) throw new Error(".merge() cannot be used on object schemas containing refinements. Use .safeExtend() instead.");
271
271
  const newShape = {};
@@ -5506,7 +5506,7 @@ var ZodObject = /*@__PURE__*/ $constructor("ZodObject", (inst, def) => {
5506
5506
  return safeExtend(this, incoming);
5507
5507
  },
5508
5508
  merge(other) {
5509
- return merge(this, other);
5509
+ return merge$1(this, other);
5510
5510
  },
5511
5511
  pick(mask) {
5512
5512
  return pick$1(this, mask);
@@ -5584,7 +5584,7 @@ var ZodRecord = /*@__PURE__*/ $constructor("ZodRecord", (inst, def) => {
5584
5584
  inst.keyType = def.keyType;
5585
5585
  inst.valueType = def.valueType;
5586
5586
  });
5587
- function record$1(keyType, valueType, params) {
5587
+ function record$3(keyType, valueType, params) {
5588
5588
  if (!valueType || !valueType._zod) return new ZodRecord({
5589
5589
  type: "record",
5590
5590
  keyType: string(),
@@ -5832,7 +5832,7 @@ function refine(fn, _params = {}) {
5832
5832
  function superRefine(fn, params) {
5833
5833
  return /* @__PURE__ */ _superRefine(fn, params);
5834
5834
  }
5835
- function json$3(params) {
5835
+ function json$5(params) {
5836
5836
  const jsonSchema = lazy(() => {
5837
5837
  return union([
5838
5838
  string(params),
@@ -5840,7 +5840,7 @@ function json$3(params) {
5840
5840
  boolean(),
5841
5841
  _null(),
5842
5842
  array(jsonSchema),
5843
- record$1(string(), jsonSchema)
5843
+ record$3(string(), jsonSchema)
5844
5844
  ]);
5845
5845
  });
5846
5846
  return jsonSchema;
@@ -5853,19 +5853,6 @@ function preprocess(fn, schema) {
5853
5853
  });
5854
5854
  }
5855
5855
  //#endregion
5856
- //#region src/execution/common/wait.ts
5857
- /** Shared by decision entry points, the editor, and durable decision storage. */
5858
- var waitCommentSchema = string().trim().refine((value) => [...value].length <= 2e3, "Wait comment must contain at most 2,000 Unicode code points.").nullable().optional();
5859
- //#endregion
5860
- //#region src/flow/common/inputValue.ts
5861
- /** Converts explicit user values at authoring boundaries, never persisted legacy data. */
5862
- function inputValues(values) {
5863
- return Object.fromEntries(Object.entries(values).map(([name, value]) => [name, {
5864
- kind: "value",
5865
- value
5866
- }]));
5867
- }
5868
- //#endregion
5869
5856
  //#region ../../node_modules/.bun/dequal@2.0.3/node_modules/dequal/lite/index.mjs
5870
5857
  var has = Object.prototype.hasOwnProperty;
5871
5858
  function dequal(foo, bar) {
@@ -5914,9 +5901,9 @@ function deepCompareStrict(a, b) {
5914
5901
  //#endregion
5915
5902
  //#region ../../node_modules/.bun/@cfworker+json-schema@4.1.1/node_modules/@cfworker/json-schema/dist/esm/pointer.js
5916
5903
  function encodePointer(p) {
5917
- return encodeURI(escapePointer(p));
5904
+ return encodeURI(escapePointer$1(p));
5918
5905
  }
5919
- function escapePointer(p) {
5906
+ function escapePointer$1(p) {
5920
5907
  return p.replace(/~/g, "~0").replace(/\//g, "~1");
5921
5908
  }
5922
5909
  //#endregion
@@ -6770,6 +6757,660 @@ var Validator = class {
6770
6757
  }
6771
6758
  };
6772
6759
  //#endregion
6760
+ //#region src/openapi/common/authBindings.ts
6761
+ /** Never allow credentials to enter a Revision as literal node inputs. */
6762
+ function assertOpenApiAuthBindings(document) {
6763
+ for (const node of Object.values(document.graph.nodes)) {
6764
+ if (node.kind != "task" || !("executor" in node.task) || node.task.executor.kind != "openapi") continue;
6765
+ for (const [handle, mapping] of Object.entries(node.inputs)) if (handle.startsWith("auth.") && mapping.kind == "value") throw new TypeError("OpenAPI authentication accepts deployment variables and upstream outputs only.");
6766
+ }
6767
+ }
6768
+ //#endregion
6769
+ //#region src/flow/common/inputValue.ts
6770
+ /** Converts explicit user values at authoring boundaries, never persisted legacy data. */
6771
+ function inputValues(values) {
6772
+ return Object.fromEntries(Object.entries(values).map(([name, value]) => [name, {
6773
+ kind: "value",
6774
+ value
6775
+ }]));
6776
+ }
6777
+ //#endregion
6778
+ //#region src/flow/common/condition.ts
6779
+ var unaryOperator = (operator) => operator.startsWith("is");
6780
+ var operandHandle = (caseIndex, groupIndex, expressionIndex, side) => `${caseIndex}/${groupIndex}/${expressionIndex}/${side}`;
6781
+ /** Derived addresses let operand bindings use the ordinary input analysis and editor. Never persisted as node inputs. */
6782
+ function conditionOperands(node) {
6783
+ return node.cases.flatMap((item, c) => item.groups.flatMap((group, g) => group.expressions.flatMap((expression, e) => [{
6784
+ handle: operandHandle(c, g, e, "left"),
6785
+ operand: expression.left,
6786
+ expression,
6787
+ side: "left"
6788
+ }, ...!unaryOperator(expression.operator) ? [{
6789
+ handle: operandHandle(c, g, e, "right"),
6790
+ operand: expression.right ?? { kind: "value" },
6791
+ expression,
6792
+ side: "right"
6793
+ }] : []])));
6794
+ }
6795
+ function nodeInputMappings(node) {
6796
+ if (node.kind != "condition") return "inputs" in node ? node.inputs : {};
6797
+ return Object.fromEntries(conditionOperands(node).flatMap(({ handle, operand }) => operand.kind == "source" ? [[handle, {
6798
+ kind: "sources",
6799
+ sources: [operand.source]
6800
+ }]] : operand.value === void 0 ? [] : [[handle, {
6801
+ kind: "value",
6802
+ value: operand.value
6803
+ }]]));
6804
+ }
6805
+ function conditionInputPorts(node) {
6806
+ return Object.fromEntries(conditionOperands(node).map(({ handle, operand }) => [handle, {
6807
+ jsonSchema: operand.kind === "value" ? operand.jsonSchema ?? {} : {},
6808
+ nullable: operand.kind === "value" ? operand.value === null : true
6809
+ }]));
6810
+ }
6811
+ function setConditionInput(node, handle, mapping) {
6812
+ const entry = conditionOperands(node).find((item) => item.handle == handle);
6813
+ if (entry == null) throw new Error("Condition operand does not exist.");
6814
+ if (mapping?.kind == "sources" && mapping.sources.length != 1) throw new Error("A Condition operand requires one Source.");
6815
+ const value = mapping?.kind == "sources" ? {
6816
+ kind: "source",
6817
+ source: mapping.sources[0]
6818
+ } : {
6819
+ kind: "value",
6820
+ ...entry.operand.kind === "value" && entry.operand.jsonSchema != null ? { jsonSchema: entry.operand.jsonSchema } : {},
6821
+ ...mapping?.kind == "value" ? { value: mapping.value } : {}
6822
+ };
6823
+ const [c, g, e] = handle.split("/").map(Number);
6824
+ return {
6825
+ ...node,
6826
+ cases: node.cases.map((item, ci) => ci != c ? item : {
6827
+ ...item,
6828
+ groups: item.groups.map((group, gi) => gi != g ? group : {
6829
+ ...group,
6830
+ expressions: group.expressions.map((expression, ei) => ei != e ? expression : {
6831
+ ...expression,
6832
+ [entry.side]: value
6833
+ })
6834
+ })
6835
+ })
6836
+ };
6837
+ }
6838
+ function resourceNameIssue(value) {
6839
+ const name = value.trim();
6840
+ if (name.length == 0) return "empty";
6841
+ if (name.length > 80) return "tooLong";
6842
+ for (const character of name) {
6843
+ const code = character.charCodeAt(0);
6844
+ if (code <= 31 || code >= 127 && code <= 159) return "controlCharacter";
6845
+ }
6846
+ if (!/^[\p{L}\p{N}](?:[\p{L}\p{N} _-]*[\p{L}\p{N}])?$/u.test(name)) return "specialCharacter";
6847
+ }
6848
+ function portsByHandle(ports) {
6849
+ return Object.fromEntries(ports.flatMap((port) => "handle" in port ? [[port.handle, port]] : []));
6850
+ }
6851
+ function decodeConnectorCapabilities(value) {
6852
+ if (!Array.isArray(value)) throw new TypeError("Connector capabilities must be an array.");
6853
+ if (value.length == 0) return [];
6854
+ if (value.some((item) => item != null && typeof item == "object" && !Array.isArray(item) && Object.hasOwn(item, "mode"))) {
6855
+ if (value.length != 1) throw new TypeError("Connector capability is declared more than once.");
6856
+ const source = value[0];
6857
+ if (source.mode == "shared") {
6858
+ if (source.kind != "connector" || Object.keys(source).some((key) => !["kind", "mode"].includes(key))) throw new TypeError("Invalid shared Connector permission capability.");
6859
+ return [{
6860
+ kind: "connector",
6861
+ mode: "shared"
6862
+ }];
6863
+ }
6864
+ if (Object.keys(source).some((key) => ![
6865
+ "kind",
6866
+ "mode",
6867
+ "actions"
6868
+ ].includes(key)) || source.kind != "connector" || source.mode != "independent" || !Array.isArray(source.actions)) throw new TypeError("Invalid Connector permission capability.");
6869
+ const actions = source.actions.map((entry) => {
6870
+ if (entry == null || typeof entry != "object" || Array.isArray(entry)) throw new TypeError("Invalid Connector Action.");
6871
+ const action = entry;
6872
+ if (Object.keys(action).some((key) => !["action", "connectionId"].includes(key)) || typeof action.action != "string" || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_.-]+$/.test(action.action) || Object.hasOwn(action, "connectionId") && (typeof action.connectionId != "string" || action.connectionId.length == 0)) throw new TypeError("Invalid Connector Action permission.");
6873
+ return action.connectionId == null ? { action: action.action } : {
6874
+ action: action.action,
6875
+ connectionId: action.connectionId
6876
+ };
6877
+ });
6878
+ if (new Set(actions.map((action) => action.action)).size != actions.length) throw new TypeError("Duplicate Connector Action permission.");
6879
+ return [{
6880
+ kind: "connector",
6881
+ mode: "independent",
6882
+ actions
6883
+ }];
6884
+ }
6885
+ if (value.some((item) => item != null && typeof item == "object" && !Array.isArray(item) && !Object.hasOwn(item, "action"))) {
6886
+ if (value.length != 1) throw new TypeError("Connector capability is declared more than once.");
6887
+ const item = value[0];
6888
+ if (item == null || typeof item != "object" || Array.isArray(item)) throw new TypeError("Invalid Connector capability.");
6889
+ const source = item;
6890
+ if (Object.keys(source).some((key) => ![
6891
+ "kind",
6892
+ "actionHints",
6893
+ "connectionHints"
6894
+ ].includes(key)) || source.kind != "connector" || Object.hasOwn(source, "actionHints") && !Array.isArray(source.actionHints) || Object.hasOwn(source, "connectionHints") && !Array.isArray(source.connectionHints)) throw new TypeError("Invalid Connector capability.");
6895
+ const actionHints = (source.actionHints ?? []).map((action) => {
6896
+ if (typeof action != "string" || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_.-]+$/.test(action)) throw new TypeError("Invalid Connector Action hint.");
6897
+ return action;
6898
+ });
6899
+ if (new Set(actionHints).size != actionHints.length) throw new TypeError("Duplicate Connector Action hint.");
6900
+ const keys = /* @__PURE__ */ new Set();
6901
+ const connectionHints = (source.connectionHints ?? []).map((entry) => {
6902
+ if (entry == null || typeof entry != "object" || Array.isArray(entry)) throw new TypeError("Invalid Connector Connection hint.");
6903
+ const hint = entry;
6904
+ if (Object.keys(hint).some((key) => ![
6905
+ "action",
6906
+ "connectionId",
6907
+ "alias"
6908
+ ].includes(key)) || typeof hint.action != "string" || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_.-]+$/.test(hint.action) || typeof hint.connectionId != "string" || hint.connectionId.length == 0 || Object.hasOwn(hint, "alias") && (typeof hint.alias != "string" || hint.alias.length == 0)) throw new TypeError("Invalid Connector Connection hint.");
6909
+ const key = `${hint.action}\0${hint.alias ?? ""}`;
6910
+ if (keys.has(key)) throw new TypeError("Duplicate Connector Connection hint.");
6911
+ keys.add(key);
6912
+ return hint.alias == null ? {
6913
+ action: hint.action,
6914
+ connectionId: hint.connectionId
6915
+ } : {
6916
+ action: hint.action,
6917
+ connectionId: hint.connectionId,
6918
+ alias: hint.alias
6919
+ };
6920
+ });
6921
+ return [{
6922
+ kind: "connector",
6923
+ ...actionHints.length == 0 ? {} : { actionHints },
6924
+ ...connectionHints.length == 0 ? {} : { connectionHints }
6925
+ }];
6926
+ }
6927
+ const actions = /* @__PURE__ */ new Set();
6928
+ return value.map((item) => {
6929
+ if (item == null || typeof item != "object" || Array.isArray(item)) throw new TypeError("Invalid Connector capability.");
6930
+ const source = item;
6931
+ if (Object.keys(source).some((key) => ![
6932
+ "kind",
6933
+ "action",
6934
+ "connections",
6935
+ "connectionId"
6936
+ ].includes(key)) || source.kind != "connector" || typeof source.action != "string" || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_.-]+$/.test(source.action) || !Array.isArray(source.connections)) throw new TypeError("Invalid Connector capability.");
6937
+ if (actions.has(source.action)) throw new TypeError("Connector Action is declared more than once.");
6938
+ actions.add(source.action);
6939
+ const ids = /* @__PURE__ */ new Set();
6940
+ const aliases = /* @__PURE__ */ new Set();
6941
+ const connections = source.connections.map((entry) => {
6942
+ if (entry == null || typeof entry != "object" || Array.isArray(entry)) throw new TypeError("Invalid Connector Connection.");
6943
+ const connection = entry;
6944
+ if (Object.keys(connection).some((key) => !["connectionId", "alias"].includes(key)) || typeof connection.connectionId != "string" || connection.connectionId.length == 0 || ids.has(connection.connectionId)) throw new TypeError("Invalid or duplicate Connector Connection ID.");
6945
+ ids.add(connection.connectionId);
6946
+ if (Object.hasOwn(connection, "alias")) {
6947
+ if (typeof connection.alias != "string" || connection.alias.length == 0 || aliases.has(connection.alias)) throw new TypeError("Invalid or duplicate Connector alias.");
6948
+ aliases.add(connection.alias);
6949
+ }
6950
+ return {
6951
+ connectionId: connection.connectionId,
6952
+ ...connection.alias == null ? {} : { alias: connection.alias }
6953
+ };
6954
+ });
6955
+ if (Object.hasOwn(source, "connectionId") && (typeof source.connectionId != "string" || !ids.has(source.connectionId))) throw new TypeError("The default Connector Connection must be declared.");
6956
+ return {
6957
+ kind: "connector",
6958
+ action: source.action,
6959
+ connections,
6960
+ ...source.connectionId == null ? {} : { connectionId: source.connectionId }
6961
+ };
6962
+ });
6963
+ }
6964
+ function normalizeNodeName(value) {
6965
+ return value.trim().normalize("NFC");
6966
+ }
6967
+ function nodeNameIssue(graph, nodeId, value) {
6968
+ const name = normalizeNodeName(value);
6969
+ if (name.length == 0) return "empty";
6970
+ return Object.entries(graph.nodes).some(([candidateId, node]) => candidateId != nodeId && node.name != null && normalizeNodeName(node.name) == name) ? "duplicate" : void 0;
6971
+ }
6972
+ var FlowChangeError = class extends Error {
6973
+ constructor(message) {
6974
+ super(message);
6975
+ this.name = "FlowChangeError";
6976
+ }
6977
+ };
6978
+ function invalid(message) {
6979
+ throw new FlowChangeError(message);
6980
+ }
6981
+ function applyFlowChanges(content, operations) {
6982
+ const document = { ...content.document };
6983
+ const modules = { ...content.modules };
6984
+ for (const operation of operations) switch (operation.kind) {
6985
+ case "graph.trigger.sources.set": {
6986
+ const graph = document.graph;
6987
+ const node = graph.nodes[operation.nodeId];
6988
+ if (node?.kind != "error") invalid("The Flow Error node does not exist.");
6989
+ if (!dequal(node.sourceFlowIds, operation.before)) invalid("The Flow Error node’s sources changed before this operation was applied.");
6990
+ const { sourceFlowIds: _, ...base } = node;
6991
+ const updated = operation.value == null ? base : {
6992
+ ...base,
6993
+ sourceFlowIds: operation.value
6994
+ };
6995
+ document.graph = {
6996
+ ...graph,
6997
+ nodes: {
6998
+ ...graph.nodes,
6999
+ [operation.nodeId]: updated
7000
+ }
7001
+ };
7002
+ break;
7003
+ }
7004
+ case "binding.create":
7005
+ if (document.bindings[operation.bindingId] != null) invalid("A Binding with this ID already exists.");
7006
+ document.bindings = {
7007
+ ...document.bindings,
7008
+ [operation.bindingId]: operation.binding
7009
+ };
7010
+ break;
7011
+ case "binding.delete": {
7012
+ if (document.bindings[operation.bindingId] == null) invalid("The Binding does not exist.");
7013
+ const bindings = { ...document.bindings };
7014
+ delete bindings[operation.bindingId];
7015
+ document.bindings = bindings;
7016
+ break;
7017
+ }
7018
+ case "binding.target.set": {
7019
+ const binding = document.bindings[operation.bindingId];
7020
+ if (binding == null) invalid("The Binding does not exist.");
7021
+ if (binding.target != operation.before) invalid("The Binding target changed before this operation was applied.");
7022
+ document.bindings = {
7023
+ ...document.bindings,
7024
+ [operation.bindingId]: {
7025
+ ...binding,
7026
+ target: operation.value
7027
+ }
7028
+ };
7029
+ break;
7030
+ }
7031
+ case "graph.edge.connect": {
7032
+ const graph = document.graph;
7033
+ if (graph.nodes[operation.edge.source] == null) invalid("The source Node does not exist.");
7034
+ const node = graph.nodes[operation.edge.target];
7035
+ if (node == null || !("inputs" in node)) invalid("The target Node does not accept execution dependencies.");
7036
+ if (graph.edges.some((edge) => dequal(edge, operation.edge))) invalid("The Nodes are already connected.");
7037
+ Object.assign(document, { graph: {
7038
+ ...graph,
7039
+ edges: [...graph.edges, operation.edge]
7040
+ } });
7041
+ break;
7042
+ }
7043
+ case "graph.edge.disconnect": {
7044
+ const graph = document.graph;
7045
+ const edges = graph.edges.filter((edge) => !dequal(edge, operation.edge));
7046
+ if (edges.length == graph.edges.length) invalid("The Nodes are not connected.");
7047
+ Object.assign(document, { graph: {
7048
+ ...graph,
7049
+ edges
7050
+ } });
7051
+ break;
7052
+ }
7053
+ case "graph.node.additional-inputs.set": {
7054
+ const graph = document.graph;
7055
+ const node = graph.nodes[operation.nodeId];
7056
+ if (node?.kind != "task") invalid("The Task Node does not exist.");
7057
+ if (!dequal(node.additionalInputs, operation.before)) invalid("The Task Node inputs changed before this operation was applied.");
7058
+ const { additionalInputs: _, ...rest } = node;
7059
+ const updated = operation.value == null ? rest : {
7060
+ ...rest,
7061
+ additionalInputs: operation.value
7062
+ };
7063
+ Object.assign(document, { graph: {
7064
+ ...graph,
7065
+ nodes: {
7066
+ ...graph.nodes,
7067
+ [operation.nodeId]: updated
7068
+ }
7069
+ } });
7070
+ break;
7071
+ }
7072
+ case "graph.node.condition.set": {
7073
+ const graph = document.graph;
7074
+ const node = graph.nodes[operation.nodeId];
7075
+ if (node?.kind != "condition") invalid("The Condition Node does not exist.");
7076
+ if (!dequal(node.cases, operation.before.cases) || node.matchMode != operation.before.matchMode) invalid("The Condition Node changed before this operation was applied.");
7077
+ const updated = {
7078
+ ...node,
7079
+ ...operation.value
7080
+ };
7081
+ Object.assign(document, { graph: {
7082
+ ...graph,
7083
+ nodes: {
7084
+ ...graph.nodes,
7085
+ [operation.nodeId]: updated
7086
+ }
7087
+ } });
7088
+ break;
7089
+ }
7090
+ case "graph.node.replace": {
7091
+ const graph = document.graph;
7092
+ if (!dequal(graph.nodes[operation.nodeId], operation.before)) invalid("The Node changed before this operation was applied.");
7093
+ if (operation.node.kind != operation.before.kind) invalid("Replacing a Node cannot change its kind.");
7094
+ if (operation.node.kind == "task" && "moduleId" in operation.node.task && operation.node.task.capabilities !== void 0) decodeConnectorCapabilities(operation.node.task.capabilities);
7095
+ const name = normalizeNodeName(operation.node.name ?? "");
7096
+ const issue = nodeNameIssue(graph, operation.nodeId, name);
7097
+ if (issue != null) invalid(`Node name is ${issue}.`);
7098
+ const node = name == operation.node.name ? operation.node : {
7099
+ ...operation.node,
7100
+ name
7101
+ };
7102
+ Object.assign(document, { graph: {
7103
+ ...graph,
7104
+ nodes: {
7105
+ ...graph.nodes,
7106
+ [operation.nodeId]: node
7107
+ }
7108
+ } });
7109
+ break;
7110
+ }
7111
+ case "graph.node.create": {
7112
+ const graph = document.graph;
7113
+ if (graph.nodes[operation.nodeId] != null) invalid("A Node with this ID already exists in the target graph.");
7114
+ if (operation.node.kind == "error" && Object.values(graph.nodes).some((node) => node.kind == "error")) invalid("A graph can contain only one Flow Error node.");
7115
+ if (operation.node.kind == "manual" && Object.values(graph.nodes).some((node) => node.kind == "manual")) invalid("A graph can contain only one manual Trigger.");
7116
+ if (operation.node.kind == "task" && "moduleId" in operation.node.task && operation.node.task.capabilities !== void 0) decodeConnectorCapabilities(operation.node.task.capabilities);
7117
+ if (operation.node.name == null) invalid("A Node name cannot be empty.");
7118
+ const name = normalizeNodeName(operation.node.name);
7119
+ const issue = nodeNameIssue(graph, operation.nodeId, name);
7120
+ if (issue == "empty") invalid("A Node name cannot be empty.");
7121
+ if (issue == "duplicate") invalid("A Node with this name already exists in the target graph.");
7122
+ const node = name == operation.node.name ? operation.node : {
7123
+ ...operation.node,
7124
+ name
7125
+ };
7126
+ Object.assign(document, { graph: {
7127
+ ...graph,
7128
+ nodes: {
7129
+ ...graph.nodes,
7130
+ [operation.nodeId]: node
7131
+ }
7132
+ } });
7133
+ break;
7134
+ }
7135
+ case "graph.node.delete": {
7136
+ const graph = document.graph;
7137
+ if (graph.nodes[operation.nodeId] == null) invalid("The Node does not exist in the target graph.");
7138
+ const removed = /* @__PURE__ */ new Set([operation.nodeId]);
7139
+ const nodes = Object.fromEntries(Object.entries(graph.nodes).filter(([nodeId]) => !removed.has(nodeId)));
7140
+ Object.assign(document, { graph: {
7141
+ ...graph,
7142
+ edges: graph.edges.filter((edge) => !removed.has(edge.source) && !removed.has(edge.target)),
7143
+ nodes
7144
+ } });
7145
+ break;
7146
+ }
7147
+ case "graph.node.field.set": {
7148
+ const graph = document.graph;
7149
+ const node = graph.nodes[operation.nodeId];
7150
+ if (node == null) invalid("The Node does not exist in the target graph.");
7151
+ if (operation.field == "connectionId" && node.kind != "poll" && node.kind != "integration") invalid("Only provider Triggers select a node Connection.");
7152
+ if (!dequal(Reflect.get(node, operation.field), operation.before)) invalid("The Node field changed before this operation was applied.");
7153
+ const updated = { ...node };
7154
+ if (operation.field == "name") {
7155
+ if (typeof operation.value != "string") invalid("A Node name cannot be empty.");
7156
+ const name = normalizeNodeName(operation.value);
7157
+ const issue = nodeNameIssue(graph, operation.nodeId, name);
7158
+ if (issue == "empty") invalid("A Node name cannot be empty.");
7159
+ if (issue == "duplicate") invalid("A Node with this name already exists in the target graph.");
7160
+ Object.assign(updated, { name });
7161
+ } else if (operation.value == null) Reflect.deleteProperty(updated, operation.field);
7162
+ else Object.assign(updated, { [operation.field]: operation.value });
7163
+ Object.assign(document, { graph: {
7164
+ ...graph,
7165
+ nodes: {
7166
+ ...graph.nodes,
7167
+ [operation.nodeId]: updated
7168
+ }
7169
+ } });
7170
+ break;
7171
+ }
7172
+ case "graph.node.input.set": {
7173
+ const graph = document.graph;
7174
+ const node = graph.nodes[operation.nodeId];
7175
+ if (node == null || !("inputs" in node)) invalid("The Node does not accept inputs.");
7176
+ if (!dequal(nodeInputMappings(node)[operation.handle], operation.before)) invalid("The Node input changed before this operation was applied.");
7177
+ const inputs = { ...node.inputs };
7178
+ if (operation.value == null) delete inputs[operation.handle];
7179
+ else inputs[operation.handle] = operation.value;
7180
+ Object.assign(document, { graph: {
7181
+ ...graph,
7182
+ nodes: {
7183
+ ...graph.nodes,
7184
+ [operation.nodeId]: node.kind == "condition" ? setConditionInput(node, operation.handle, operation.value) : {
7185
+ ...node,
7186
+ inputs
7187
+ }
7188
+ }
7189
+ } });
7190
+ break;
7191
+ }
7192
+ case "graph.node.task.capabilities.set": {
7193
+ const graph = document.graph;
7194
+ const node = graph.nodes[operation.nodeId];
7195
+ if (node?.kind != "task" || !("moduleId" in node.task)) invalid("The inline Task Node does not exist.");
7196
+ if (!dequal(node.task.capabilities, operation.before)) invalid("The inline Task capabilities changed before this operation was applied.");
7197
+ const task = { ...node.task };
7198
+ if (operation.value === void 0) delete task.capabilities;
7199
+ else task.capabilities = decodeConnectorCapabilities(operation.value);
7200
+ Object.assign(document, { graph: {
7201
+ ...graph,
7202
+ nodes: {
7203
+ ...graph.nodes,
7204
+ [operation.nodeId]: {
7205
+ ...node,
7206
+ task
7207
+ }
7208
+ }
7209
+ } });
7210
+ break;
7211
+ }
7212
+ case "graph.node.task.name.set": {
7213
+ const graph = document.graph;
7214
+ const node = graph.nodes[operation.nodeId];
7215
+ if (node?.kind != "task" || !("moduleId" in node.task)) invalid("The inline Task Node does not exist.");
7216
+ if (node.task.name != operation.before) invalid("The inline Task name changed before this operation was applied.");
7217
+ const updated = {
7218
+ ...node,
7219
+ task: {
7220
+ ...node.task,
7221
+ name: operation.value
7222
+ }
7223
+ };
7224
+ Object.assign(document, { graph: {
7225
+ ...graph,
7226
+ nodes: {
7227
+ ...graph.nodes,
7228
+ [operation.nodeId]: updated
7229
+ }
7230
+ } });
7231
+ break;
7232
+ }
7233
+ case "graph.node.task.ports.set": {
7234
+ const graph = document.graph;
7235
+ const node = graph.nodes[operation.nodeId];
7236
+ if (node?.kind != "task" || !("moduleId" in node.task)) invalid("The inline Task Node does not exist.");
7237
+ if (!dequal({
7238
+ inputs: node.task.inputs,
7239
+ outputs: node.task.outputs
7240
+ }, operation.before)) invalid("The inline Task ports changed before this operation was applied.");
7241
+ const updated = {
7242
+ ...node,
7243
+ task: {
7244
+ ...node.task,
7245
+ inputs: operation.value.inputs,
7246
+ outputs: operation.value.outputs
7247
+ }
7248
+ };
7249
+ Object.assign(document, { graph: {
7250
+ ...graph,
7251
+ nodes: {
7252
+ ...graph.nodes,
7253
+ [operation.nodeId]: updated
7254
+ }
7255
+ } });
7256
+ break;
7257
+ }
7258
+ case "graph.node.values.set": {
7259
+ const graph = document.graph;
7260
+ const node = graph.nodes[operation.nodeId];
7261
+ if (node?.kind != "value") invalid("The Value Node does not exist.");
7262
+ if (!dequal(node.values, operation.before)) invalid("The Value Node changed before this operation was applied.");
7263
+ Object.assign(document, { graph: {
7264
+ ...graph,
7265
+ nodes: {
7266
+ ...graph.nodes,
7267
+ [operation.nodeId]: {
7268
+ ...node,
7269
+ values: operation.value
7270
+ }
7271
+ }
7272
+ } });
7273
+ break;
7274
+ }
7275
+ case "graph.node.resolution.set": {
7276
+ const graph = document.graph;
7277
+ const node = graph.nodes[operation.nodeId];
7278
+ if (node?.kind != "wait" && node?.kind != "approval" || !dequal({
7279
+ inputDefinitions: node.inputDefinitions,
7280
+ prompt: node.prompt
7281
+ }, operation.before)) invalid("The resolution node changed before this operation was applied.");
7282
+ const updated = {
7283
+ ...node,
7284
+ ...operation.value
7285
+ };
7286
+ document.graph = {
7287
+ ...graph,
7288
+ nodes: {
7289
+ ...graph.nodes,
7290
+ [operation.nodeId]: updated
7291
+ }
7292
+ };
7293
+ break;
7294
+ }
7295
+ case "graph.node.webhook.set": {
7296
+ const graph = document.graph;
7297
+ const node = graph.nodes[operation.nodeId];
7298
+ if (node?.kind != "webhook") invalid("The Webhook Node does not exist.");
7299
+ if (node.method != operation.before.method || !dequal(node.bodyFields, operation.before.bodyFields) || !dequal(node.options, operation.before.options)) invalid("The Webhook Node changed before this operation was applied.");
7300
+ const { options: _, ...rest } = node;
7301
+ const updated = operation.value.options == null ? {
7302
+ ...rest,
7303
+ bodyFields: operation.value.bodyFields,
7304
+ method: operation.value.method
7305
+ } : {
7306
+ ...node,
7307
+ ...operation.value
7308
+ };
7309
+ Object.assign(document, { graph: {
7310
+ ...graph,
7311
+ nodes: {
7312
+ ...graph.nodes,
7313
+ [operation.nodeId]: updated
7314
+ }
7315
+ } });
7316
+ break;
7317
+ }
7318
+ case "graph.trigger.config.set": {
7319
+ const graph = document.graph;
7320
+ const node = graph.nodes[operation.nodeId];
7321
+ if (node == null || node.kind != "integration" && node.kind != "poll") invalid("The configurable Trigger Node does not exist.");
7322
+ if (!dequal(node.config[operation.name], operation.before)) invalid("The Trigger configuration changed before this operation was applied.");
7323
+ const config = { ...node.config };
7324
+ if (operation.value === void 0) delete config[operation.name];
7325
+ else config[operation.name] = operation.value;
7326
+ document.graph = {
7327
+ ...graph,
7328
+ nodes: {
7329
+ ...graph.nodes,
7330
+ [operation.nodeId]: {
7331
+ ...node,
7332
+ config
7333
+ }
7334
+ }
7335
+ };
7336
+ break;
7337
+ }
7338
+ case "graph.trigger.schedule.set": {
7339
+ const graph = document.graph;
7340
+ const node = graph.nodes[operation.nodeId];
7341
+ if (node == null || node.kind != "cron" && node.kind != "poll") invalid("The scheduled Trigger Node does not exist.");
7342
+ if (!dequal(node.kind == "cron" ? node.cronTimes : node.pollTimes, operation.before)) invalid("The Trigger schedule changed before this operation was applied.");
7343
+ const updated = node.kind == "cron" ? {
7344
+ ...node,
7345
+ cronTimes: operation.value
7346
+ } : {
7347
+ ...node,
7348
+ pollTimes: operation.value
7349
+ };
7350
+ document.graph = {
7351
+ ...graph,
7352
+ nodes: {
7353
+ ...graph.nodes,
7354
+ [operation.nodeId]: updated
7355
+ }
7356
+ };
7357
+ break;
7358
+ }
7359
+ case "module.create":
7360
+ if (modules[operation.moduleId] != null) invalid("A CodeModule with this ID already exists.");
7361
+ modules[operation.moduleId] = operation.module;
7362
+ break;
7363
+ case "module.delete":
7364
+ if (modules[operation.moduleId] == null) invalid("The CodeModule does not exist.");
7365
+ delete modules[operation.moduleId];
7366
+ break;
7367
+ case "module.rename": {
7368
+ const module = modules[operation.moduleId];
7369
+ if (module == null) invalid("The CodeModule does not exist.");
7370
+ if (module.name != operation.before) invalid("The CodeModule name changed before this operation was applied.");
7371
+ modules[operation.moduleId] = {
7372
+ ...module,
7373
+ name: operation.name
7374
+ };
7375
+ break;
7376
+ }
7377
+ case "module.source.replace": {
7378
+ const module = modules[operation.moduleId];
7379
+ if (module == null) invalid("The CodeModule does not exist.");
7380
+ if (module.source != operation.beforeSource || !dequal(module.imports, operation.beforeImports)) invalid("The CodeModule source changed before this operation was applied.");
7381
+ modules[operation.moduleId] = {
7382
+ ...module,
7383
+ imports: operation.imports,
7384
+ source: operation.source
7385
+ };
7386
+ break;
7387
+ }
7388
+ case "graph.node.task.set": {
7389
+ const graph = document.graph;
7390
+ const node = graph.nodes[operation.nodeId];
7391
+ if (node?.kind != "task") invalid("The Task Node does not exist.");
7392
+ if (!dequal(node.task, operation.before)) invalid("The Task configuration changed before this operation was applied.");
7393
+ document.graph = {
7394
+ ...graph,
7395
+ nodes: {
7396
+ ...graph.nodes,
7397
+ [operation.nodeId]: {
7398
+ ...node,
7399
+ task: operation.value
7400
+ }
7401
+ }
7402
+ };
7403
+ break;
7404
+ }
7405
+ }
7406
+ assertOpenApiAuthBindings(document);
7407
+ return {
7408
+ document,
7409
+ modelVersion: 6,
7410
+ modules
7411
+ };
7412
+ }
7413
+ //#endregion
6773
7414
  //#region src/json-schema-subset/utils.ts
6774
7415
  var nextId = 0;
6775
7416
  function createId() {
@@ -7189,7 +7830,7 @@ var ExpressionKind = Object.freeze({
7189
7830
  });
7190
7831
  //#endregion
7191
7832
  //#region src/json-schema-subset/expression/expression.ts
7192
- var expression = (delegate) => (e1, e2) => {
7833
+ var expression$1 = (delegate) => (e1, e2) => {
7193
7834
  const rootNode = {
7194
7835
  parent: null,
7195
7836
  swapped: false,
@@ -9177,7 +9818,7 @@ function checkWithResult(extendsContext, schema1, schema2) {
9177
9818
  const describe = describer();
9178
9819
  const equals = schemaEqualsChecker(extendsContext);
9179
9820
  context.isEquals = wrapEqualsCheckerWithCache(isDeepEquals);
9180
- context.calculate = expression({
9821
+ context.calculate = expression$1({
9181
9822
  describe,
9182
9823
  equals,
9183
9824
  calculate,
@@ -9705,16 +10346,19 @@ var webhookMethods = [
9705
10346
  "PATCH",
9706
10347
  "DELETE"
9707
10348
  ];
10349
+ function webhookSupportsBody(method) {
10350
+ return method !== "GET";
10351
+ }
9708
10352
  var text$1 = string();
9709
- var json$2 = json$3();
10353
+ var json$4 = json$5();
9710
10354
  var strings = array(text$1);
9711
10355
  var port = object$1({
9712
10356
  description: text$1.optional(),
9713
- jsonSchema: json$2,
10357
+ jsonSchema: json$4,
9714
10358
  nullable: boolean(),
9715
10359
  handle: text$1
9716
10360
  });
9717
- var input = port.extend({ value: json$2.optional() });
10361
+ var input = port.extend({ value: json$4.optional() });
9718
10362
  var group = object$1({
9719
10363
  collapsed: boolean().optional(),
9720
10364
  group: text$1
@@ -9730,13 +10374,13 @@ var source = union([object$1({
9730
10374
  })]);
9731
10375
  var fixedInput = union([object$1({ kind: literal("unset") }), object$1({
9732
10376
  kind: literal("value"),
9733
- value: json$2
10377
+ value: json$4
9734
10378
  })]);
9735
10379
  var mapping = union([fixedInput, object$1({
9736
10380
  kind: literal("sources"),
9737
10381
  sources: array(source)
9738
10382
  })]);
9739
- var inputs$1 = record$1(text$1, mapping);
10383
+ var inputs$1 = record$3(text$1, mapping);
9740
10384
  var ports = {
9741
10385
  inputs: array(union([input, group])),
9742
10386
  outputs: array(union([port, group]))
@@ -9781,7 +10425,7 @@ var inline = object$1({
9781
10425
  });
9782
10426
  var agentValue = union([object$1({
9783
10427
  kind: literal("value"),
9784
- value: json$2
10428
+ value: json$4
9785
10429
  }), object$1({
9786
10430
  kind: literal("input"),
9787
10431
  input: text$1
@@ -9813,7 +10457,7 @@ var decisionQuestion = discriminatedUnion("type", [
9813
10457
  criteria: strings
9814
10458
  })
9815
10459
  ]);
9816
- var managed = object$1({
10460
+ var managedFields = object$1({
9817
10461
  ...ports,
9818
10462
  name: text$1,
9819
10463
  executor: union([
@@ -9828,7 +10472,7 @@ var managed = object$1({
9828
10472
  method: text$1,
9829
10473
  path: text$1,
9830
10474
  serverUrl: text$1,
9831
- document: json$2,
10475
+ document: json$4,
9832
10476
  auth: array(object$1({
9833
10477
  id: text$1,
9834
10478
  type: _enum([
@@ -9868,15 +10512,16 @@ var managed = object$1({
9868
10512
  connectionId: text$1.optional(),
9869
10513
  inputDefinitions: array(input),
9870
10514
  messageHandle: text$1,
9871
- inputs: record$1(text$1, agentValue)
10515
+ inputs: record$3(text$1, agentValue)
9872
10516
  }).optional()
9873
10517
  })
9874
10518
  ])
9875
- }).transform(limitDecisionTask);
9876
- var operand = union([object$1({
10519
+ });
10520
+ var managed = managedFields.transform(limitDecisionTask);
10521
+ var operand$1 = union([object$1({
9877
10522
  kind: literal("value"),
9878
- value: json$2.optional(),
9879
- jsonSchema: json$2.optional()
10523
+ value: json$4.optional(),
10524
+ jsonSchema: json$4.optional()
9880
10525
  }), object$1({
9881
10526
  kind: literal("source"),
9882
10527
  source
@@ -9887,7 +10532,7 @@ var condition = {
9887
10532
  description: text$1.optional(),
9888
10533
  output: text$1,
9889
10534
  groups: array(object$1({ expressions: array(object$1({
9890
- left: operand,
10535
+ left: operand$1,
9891
10536
  operator: _enum([
9892
10537
  "!=",
9893
10538
  "<",
@@ -9910,7 +10555,7 @@ var condition = {
9910
10555
  "notHasValue",
9911
10556
  "startsWith"
9912
10557
  ]),
9913
- right: operand.optional()
10558
+ right: operand$1.optional()
9914
10559
  })) }))
9915
10560
  }))
9916
10561
  };
@@ -9923,7 +10568,7 @@ var webhookOptions = object$1({
9923
10568
  allowedOrigins: strings.optional(),
9924
10569
  noResponseBody: never().optional(),
9925
10570
  responseData: text$1.optional(),
9926
- responseHeaders: record$1(text$1, text$1).optional(),
10571
+ responseHeaders: record$3(text$1, text$1).optional(),
9927
10572
  responseStatusCode: number().int().min(200).max(599).optional()
9928
10573
  });
9929
10574
  var webhook = {
@@ -9979,7 +10624,7 @@ var base = {
9979
10624
  var node = union([
9980
10625
  object$1({
9981
10626
  ...base,
9982
- inputs: record$1(text$1, never()),
10627
+ inputs: record$3(text$1, never()),
9983
10628
  kind: literal("condition"),
9984
10629
  ...condition
9985
10630
  }),
@@ -10028,7 +10673,7 @@ var node = union([
10028
10673
  ...trigger$1,
10029
10674
  kind: literal("poll"),
10030
10675
  connectionId: text$1.min(1).optional(),
10031
- config: record$1(text$1, fixedInput),
10676
+ config: record$3(text$1, fixedInput),
10032
10677
  definition: object$1({
10033
10678
  ...definition,
10034
10679
  type: literal("poll")
@@ -10039,7 +10684,7 @@ var node = union([
10039
10684
  ...trigger$1,
10040
10685
  kind: literal("integration"),
10041
10686
  connectionId: text$1.min(1).optional(),
10042
- config: record$1(text$1, fixedInput),
10687
+ config: record$3(text$1, fixedInput),
10043
10688
  definition: object$1({
10044
10689
  ...definition,
10045
10690
  type: literal("integration"),
@@ -10047,6 +10692,25 @@ var node = union([
10047
10692
  })
10048
10693
  })
10049
10694
  ]);
10695
+ /** Configuration schemas shared by the node authoring boundary. */
10696
+ var authoringDefinitionSchemas = {
10697
+ input,
10698
+ port,
10699
+ ports,
10700
+ condition: strictObject(condition),
10701
+ wait: strictObject(wait),
10702
+ webhook: strictObject(webhook),
10703
+ schedule: triggerScheduleSchema,
10704
+ capabilities: array(capability),
10705
+ connector: managedFields.shape.executor.options[0].omit({ kind: true }).strict(),
10706
+ openapi: managedFields.shape.executor.options[1].omit({ kind: true }).strict(),
10707
+ decision: managedFields.shape.executor.options[2].omit({ kind: true }).strict(),
10708
+ llm: managedFields.shape.executor.options[3].omit({ kind: true }).strict(),
10709
+ agent: managedFields.shape.executor.options[4].omit({
10710
+ kind: true,
10711
+ notification: true
10712
+ }).strict()
10713
+ };
10050
10714
  var edge = object$1({
10051
10715
  source: text$1,
10052
10716
  target: text$1,
@@ -10057,7 +10721,7 @@ var at = {
10057
10721
  target: never().optional()
10058
10722
  };
10059
10723
  var graph = object$1({
10060
- nodes: record$1(text$1, node),
10724
+ nodes: record$3(text$1, node),
10061
10725
  edges: array(edge).default([])
10062
10726
  });
10063
10727
  var binding = object$1({
@@ -10070,7 +10734,7 @@ var module = object$1({
10070
10734
  source: text$1
10071
10735
  });
10072
10736
  var document = preprocess(rejectRetiredDefinitions, object$1({
10073
- bindings: record$1(text$1, binding),
10737
+ bindings: record$3(text$1, binding),
10074
10738
  graph
10075
10739
  }));
10076
10740
  object$1({
@@ -10081,21 +10745,21 @@ object$1({
10081
10745
  literal(6)
10082
10746
  ]),
10083
10747
  document,
10084
- modules: record$1(text$1, module)
10748
+ modules: record$3(text$1, module)
10085
10749
  }).extend({
10086
10750
  kind: literal("open-flow-flow-revision"),
10087
10751
  version: literal(1)
10088
10752
  });
10089
10753
  function rejectRetiredDefinitions(value) {
10090
- const candidate = record(value);
10754
+ const candidate = record$2(value);
10091
10755
  if (candidate.tasks !== void 0 && (candidate.tasks === null || typeof candidate.tasks !== "object" || Array.isArray(candidate.tasks) || Object.keys(candidate.tasks).length > 0)) throw new TypeError("Independent Task definitions are no longer supported.");
10092
- if (Object.values(record(record(candidate.graph).nodes)).some((candidateNode) => Object.hasOwn(record(candidateNode), "taskId"))) throw new TypeError("Task references are no longer supported.");
10756
+ if (Object.values(record$2(record$2(candidate.graph).nodes)).some((candidateNode) => Object.hasOwn(record$2(candidateNode), "taskId"))) throw new TypeError("Task references are no longer supported.");
10093
10757
  const subflows = candidate.subflows;
10094
10758
  if (subflows !== void 0 && (subflows === null || typeof subflows !== "object" || Array.isArray(subflows) || Object.keys(subflows).length > 0)) throw new TypeError("Subflows are no longer supported.");
10095
- if (Object.values(record(record(candidate.graph).nodes)).some((candidateNode) => record(candidateNode).kind === "subflow")) throw new TypeError("Subflow nodes are no longer supported.");
10759
+ if (Object.values(record$2(record$2(candidate.graph).nodes)).some((candidateNode) => record$2(candidateNode).kind === "subflow")) throw new TypeError("Subflow nodes are no longer supported.");
10096
10760
  return value;
10097
10761
  }
10098
- function record(value) {
10762
+ function record$2(value) {
10099
10763
  return value != null && typeof value == "object" && !Array.isArray(value) ? value : {};
10100
10764
  }
10101
10765
  var shapes = {
@@ -10126,6 +10790,11 @@ var shapes = {
10126
10790
  ...at,
10127
10791
  node
10128
10792
  },
10793
+ "graph.node.replace": {
10794
+ ...at,
10795
+ before: node,
10796
+ node
10797
+ },
10129
10798
  "graph.node.delete": at,
10130
10799
  "graph.node.field.set": union([
10131
10800
  object$1({
@@ -10260,310 +10929,90 @@ function decodeChangeOperation(candidate, index) {
10260
10929
  if (schema == null) throw new TypeError(`operations[${index}]: Unknown operation ${JSON.stringify(kind)}.`);
10261
10930
  return parseOperation(candidate, index, schema.parse);
10262
10931
  }
10932
+ function decodeChangeOperations(value) {
10933
+ checkJsonDepth(value);
10934
+ return array(unknown()).min(1).parse(value).map(decodeChangeOperation);
10935
+ }
10263
10936
  function changeOperationsSchema(kind) {
10264
10937
  const schema = kind == null ? operations : variants.get(kind);
10265
10938
  if (schema == null) throw new TypeError(`Unknown operation ${JSON.stringify(kind)}.`);
10266
10939
  return toJSONSchema(schema, { io: "input" });
10267
10940
  }
10268
- function resourceNameIssue(value) {
10269
- const name = value.trim();
10270
- if (name.length == 0) return "empty";
10271
- if (name.length > 80) return "tooLong";
10272
- for (const character of name) {
10273
- const code = character.charCodeAt(0);
10274
- if (code <= 31 || code >= 127 && code <= 159) return "controlCharacter";
10275
- }
10276
- if (!/^[\p{L}\p{N}](?:[\p{L}\p{N} _-]*[\p{L}\p{N}])?$/u.test(name)) return "specialCharacter";
10277
- }
10278
10941
  //#endregion
10279
- //#region src/flow/common/nodeChanges.ts
10280
- var codeTaskTemplate = `export default async function (inputs, context) {
10281
- return { result: inputs.value }
10942
+ //#region src/control/common/authoringLlm.ts
10943
+ var authoringLlmConfiguration = strictObject({
10944
+ mode: _enum(["chat", "json"]),
10945
+ resultSchema: json$5(),
10946
+ model: json$5().optional().describe("Default model settings: {model, temperature?, top_p?, max_tokens?}. A bound model input takes precedence."),
10947
+ template: json$5().optional().describe("Default message templates: [{role: \"system\" | \"user\" | \"assistant\", content: \"Text with {{namedInput}}\"}]."),
10948
+ messages: json$5().optional().describe("Default conversation history, prepended without template interpolation; an array of {role, content} or null.")
10949
+ });
10950
+ var defaults = {
10951
+ model: "model",
10952
+ template: "template",
10953
+ messages: "messages"
10954
+ };
10955
+ /** Read defaults only. Node bindings remain independently visible and editable. */
10956
+ function llmConfigurationView(task) {
10957
+ if (task.executor.kind != "llm") throw new TypeError("Expected an LLM task.");
10958
+ const config = {
10959
+ mode: task.executor.mode,
10960
+ resultSchema: task.outputs.find((port) => "handle" in port)?.jsonSchema ?? {}
10961
+ };
10962
+ for (const [name, handle] of Object.entries(defaults)) {
10963
+ const port = task.inputs.find((candidate) => "handle" in candidate && candidate.handle == handle);
10964
+ if (port != null && Object.hasOwn(port, "value")) config[name] = port.value;
10965
+ }
10966
+ return config;
10282
10967
  }
10283
- `;
10284
- function createCodeTask(identity, name, module = void 0, ports = {
10285
- inputs: [{
10286
- handle: "value",
10287
- jsonSchema: { type: "string" },
10288
- nullable: true,
10289
- value: "foo"
10290
- }],
10291
- outputs: [{
10292
- handle: "result",
10293
- jsonSchema: {},
10294
- nullable: true
10295
- }]
10296
- }) {
10297
- return [{
10298
- kind: "module.create",
10299
- module: {
10300
- ...module ?? {
10301
- imports: [],
10302
- source: codeTaskTemplate
10303
- },
10304
- name
10305
- },
10306
- moduleId: identity.moduleId
10307
- }, {
10308
- kind: "graph.node.create",
10309
- node: {
10310
- inputs: defaultInputs(ports.inputs),
10311
- kind: "task",
10312
- name,
10313
- task: {
10314
- capabilities: ports.capabilities ?? [{
10315
- kind: "connector",
10316
- mode: "independent",
10317
- actions: []
10318
- }],
10319
- inputs: ports.inputs,
10320
- moduleId: identity.moduleId,
10321
- name,
10322
- outputs: ports.outputs
10323
- }
10968
+ /** Update default values without altering port contracts, groups, or node bindings. */
10969
+ function prepareLlmConfiguration(config, previous, name) {
10970
+ if (previous.executor.kind != "llm") throw new TypeError("Expected an LLM task.");
10971
+ const old = llmConfigurationView(previous);
10972
+ const changed = Object.keys(defaults).filter((key) => Object.hasOwn(old, key) != Object.hasOwn(config, key) || !dequal(old[key], config[key]));
10973
+ const inputs = previous.inputs.map((port) => {
10974
+ if (!("handle" in port)) return port;
10975
+ const key = changed.find((candidate) => defaults[candidate] == port.handle);
10976
+ if (key == null) return port;
10977
+ const { value: _value, ...withoutDefault } = port;
10978
+ return Object.hasOwn(config, key) ? {
10979
+ ...withoutDefault,
10980
+ value: config[key]
10981
+ } : withoutDefault;
10982
+ });
10983
+ return {
10984
+ ...previous,
10985
+ name,
10986
+ executor: {
10987
+ ...previous.executor,
10988
+ mode: config.mode
10324
10989
  },
10325
- nodeId: identity.nodeId
10326
- }];
10990
+ inputs,
10991
+ outputs: dequal(old.resultSchema, config.resultSchema) ? previous.outputs : previous.outputs.map((port) => "handle" in port ? {
10992
+ ...port,
10993
+ jsonSchema: config.resultSchema
10994
+ } : port)
10995
+ };
10327
10996
  }
10328
- function createManagedTask(identity, task) {
10329
- return [{
10330
- kind: "graph.node.create",
10331
- node: {
10332
- inputs: defaultInputs(task.inputs),
10333
- kind: "task",
10334
- name: task.name,
10335
- task
10336
- },
10337
- nodeId: identity.nodeId
10338
- }];
10339
- }
10340
- function createLlmTask(identity, name, mode, outputDescription, options = {}) {
10341
- const values = options.inputs ?? {};
10342
- return createManagedTask(identity, {
10343
- executor: {
10344
- kind: "llm",
10345
- mode
10346
- },
10347
- inputs: [
10348
- {
10349
- handle: "messages",
10350
- jsonSchema: {
10351
- items: { type: "object" },
10352
- type: "array"
10353
- },
10354
- nullable: true,
10355
- value: llmInputValue(values, "messages", null)
10356
- },
10357
- {
10358
- handle: "input",
10359
- jsonSchema: { type: "string" },
10360
- nullable: false,
10361
- value: llmInputValue(values, "input", "Alex")
10362
- },
10363
- {
10364
- handle: "template",
10365
- jsonSchema: {
10366
- items: { type: "object" },
10367
- minItems: 1,
10368
- type: "array"
10369
- },
10370
- nullable: false,
10371
- value: llmInputValue(values, "template", [{
10372
- content: "Hello, I'm {{input}}",
10373
- role: "user"
10374
- }])
10375
- },
10376
- {
10377
- handle: "model",
10378
- jsonSchema: { type: "object" },
10379
- nullable: false,
10380
- value: llmInputValue(values, "model", { model: "deepseek-v4-flash" })
10381
- }
10382
- ],
10383
- name,
10384
- outputs: [{
10385
- ...options.output,
10386
- description: options.output?.description ?? outputDescription,
10387
- handle: "output",
10388
- jsonSchema: options.output?.jsonSchema ?? (mode == "chat" ? { type: "string" } : {}),
10389
- nullable: options.output?.nullable ?? false
10390
- }]
10391
- });
10392
- }
10393
- function createCondition(nodeId, name) {
10394
- return [{
10395
- kind: "graph.node.create",
10396
- node: {
10397
- cases: [{
10398
- groups: [{ expressions: [{
10399
- left: { kind: "value" },
10400
- operator: "==",
10401
- right: { kind: "value" }
10402
- }] }],
10403
- output: "case"
10404
- }],
10405
- matchMode: "first",
10406
- inputs: {},
10407
- kind: "condition",
10408
- name
10409
- },
10410
- nodeId
10411
- }];
10412
- }
10413
- function createValue(nodeId, name) {
10414
- return [{
10415
- kind: "graph.node.create",
10416
- node: {
10417
- inputs: {},
10418
- kind: "value",
10419
- name,
10420
- values: [{
10421
- handle: "value",
10422
- jsonSchema: {},
10423
- nullable: true,
10424
- value: null
10425
- }]
10426
- },
10427
- nodeId
10428
- }];
10429
- }
10430
- function createWait(nodeId, name) {
10431
- return [{
10432
- kind: "graph.node.create",
10433
- node: {
10434
- inputDefinitions: [],
10435
- inputs: {},
10436
- kind: "wait",
10437
- name,
10438
- prompt: name
10439
- },
10440
- nodeId
10441
- }];
10442
- }
10443
- function createApproval(nodeId, name) {
10444
- return [{
10445
- kind: "graph.node.create",
10446
- node: {
10447
- inputDefinitions: [],
10448
- inputs: {},
10449
- kind: "approval",
10450
- name,
10451
- prompt: name
10452
- },
10453
- nodeId
10454
- }];
10455
- }
10456
- function createBuiltinTrigger(nodeId, node) {
10457
- return [{
10458
- kind: "graph.node.create",
10459
- node,
10460
- nodeId
10461
- }];
10462
- }
10463
- function createProviderTrigger(nodeId, definition, options) {
10464
- const name = options.name ?? definition.displayName;
10465
- return [{
10466
- kind: "graph.node.create",
10467
- node: definition.type == "poll" ? {
10468
- ...options.connectionId == null ? {} : { connectionId: options.connectionId },
10469
- config: inputValues(options.config),
10470
- definition,
10471
- kind: "poll",
10472
- name,
10473
- pollTimes: options.schedule ?? [{
10474
- type: "every",
10475
- unit: "minute",
10476
- value: 5
10477
- }]
10478
- } : {
10479
- ...options.connectionId == null ? {} : { connectionId: options.connectionId },
10480
- config: inputValues(options.config),
10481
- definition,
10482
- kind: "integration",
10483
- name
10484
- },
10485
- nodeId
10486
- }];
10487
- }
10488
- function defaultInputs(ports) {
10489
- return Object.fromEntries(ports.flatMap((port) => "handle" in port && Object.hasOwn(port, "value") ? [[port.handle, {
10490
- kind: "value",
10491
- value: port.value
10492
- }]] : []));
10493
- }
10494
- function llmInputValue(values, handle, fallback) {
10495
- return values != null && Object.hasOwn(values, handle) ? values[handle] : fallback;
10496
- }
10497
- function createDecisionTask(identity, name = "AI Decision", questions) {
10498
- return createManagedTask(identity, decisionTask(questions, name));
10499
- }
10500
- //#endregion
10501
- //#region src/control/common/draftOperations.ts
10502
- var text = string().min(1);
10503
- var json$1 = json$3();
10504
- var triggerCreate = strictObject({
10505
- kind: literal("graph.trigger.create"),
10506
- nodeId: text,
10507
- key: text,
10508
- connectionId: text.optional(),
10509
- name: text.optional(),
10510
- config: record$1(text, json$1),
10511
- schedule: triggerScheduleSchema.readonly().optional()
10512
- });
10513
- function decodeDraftOperations(value) {
10514
- checkJsonDepth(value);
10515
- return array(unknown()).min(1).parse(value).map((candidate, index) => {
10516
- const { kind } = parseOperation(candidate, index, object$1({ kind: text }).parse);
10517
- return kind == "graph.trigger.create" ? parseOperation(candidate, index, triggerCreate.parse) : decodeChangeOperation(candidate, index);
10518
- });
10519
- }
10520
- function draftOperationsSchema(kind) {
10521
- if (kind != null && kind != "graph.trigger.create") return changeOperationsSchema(kind);
10522
- const trigger = toJSONSchema(triggerCreate);
10523
- if (kind == "graph.trigger.create") return trigger;
10524
- const schema = changeOperationsSchema();
10997
+ /** Keep the production LLM factory's contracts while removing sample business data. */
10998
+ function initialAuthoringLlmTask(task) {
10999
+ if (task.executor.kind != "llm") throw new TypeError("Expected an LLM task.");
10525
11000
  return {
10526
- ...schema,
10527
- items: { anyOf: [schema.items, trigger] }
11001
+ ...task,
11002
+ inputs: task.inputs.flatMap((port) => {
11003
+ if (!("handle" in port)) return [port];
11004
+ if (port.handle == "input") return [];
11005
+ if (port.handle == "template") return [{
11006
+ ...port,
11007
+ value: [{
11008
+ role: "user",
11009
+ content: ""
11010
+ }]
11011
+ }];
11012
+ return [port];
11013
+ })
10528
11014
  };
10529
11015
  }
10530
- function resolveDraftOperations(operations, definition) {
10531
- return operations.flatMap((operation) => {
10532
- if (operation.kind != "graph.trigger.create") return [operation];
10533
- const snapshot = definition(operation.key);
10534
- if (snapshot.type != "poll" && operation.schedule != null) throw new Error("Only Poll triggers accept a schedule.");
10535
- return createProviderTrigger(operation.nodeId, snapshot, operation);
10536
- });
10537
- }
10538
- //#endregion
10539
- //#region src/control/common/eventSourceSchemas.ts
10540
- var id$1 = string().min(1).max(256);
10541
- var eventType = string().regex(/^[a-z][a-z0-9_.]{0,127}$/);
10542
- var name = string().trim().min(1).max(128);
10543
- var secret = string().min(1).max(256);
10544
- var createEventSourceSchema = strictObject({
10545
- version: literal(1),
10546
- name,
10547
- connectionId: id$1,
10548
- teamId: id$1.nullable(),
10549
- verificationToken: secret,
10550
- encryptKey: secret,
10551
- eventTypes: array(eventType).min(1).max(200).refine((values) => new Set(values).size == values.length),
10552
- manageSubscriptions: boolean()
10553
- });
10554
- var updateEventSourceSchema = strictObject({
10555
- version: literal(1),
10556
- expectedRevision: int().positive(),
10557
- name,
10558
- enabled: boolean(),
10559
- eventTypes: array(eventType).min(1).max(200).refine((values) => new Set(values).size == values.length),
10560
- verificationToken: secret.optional(),
10561
- encryptKey: secret.optional()
10562
- });
10563
- var eventSourceRevisionSchema = strictObject({
10564
- version: literal(1),
10565
- expectedRevision: int().positive()
10566
- });
10567
11016
  //#endregion
10568
11017
  //#region src/openapi/common/openapi.ts
10569
11018
  var methods = [
@@ -10948,6 +11397,2323 @@ function selectOperation(value, sourceUrl, path, method) {
10948
11397
  return config;
10949
11398
  }
10950
11399
  //#endregion
11400
+ //#region src/control/common/authoringOpenApi.ts
11401
+ var authenticationSchema = union([
11402
+ strictObject({ schemes: array(string().min(1)).describe("One complete security alternative advertised by this operation; [] selects no authentication.") }),
11403
+ strictObject({ type: _enum(["bearer", "basic"]) }),
11404
+ strictObject({
11405
+ type: literal("apiKey"),
11406
+ name: string().min(1),
11407
+ in: _enum(["header", "query"])
11408
+ })
11409
+ ]);
11410
+ var authoringOpenApiSchema = strictObject({
11411
+ sourceUrl: string().min(1),
11412
+ path: string().min(1),
11413
+ method: string().min(1),
11414
+ serverUrl: string().optional(),
11415
+ authentication: authenticationSchema.optional().describe("Omit to use the operation default. Bind credentials through the advertised node inputs.")
11416
+ });
11417
+ function openApiAuthenticationChoices(config) {
11418
+ try {
11419
+ return securityOptions(config.document, config.path, config.method).map(({ label, auth, error }) => Object.assign({ label }, auth == null ? { error } : { authentication: { schemes: auth.map((item) => item.id) } }));
11420
+ } catch (error) {
11421
+ return [{
11422
+ label: "Saved operation",
11423
+ error: error.message
11424
+ }];
11425
+ }
11426
+ }
11427
+ function authenticationView(config) {
11428
+ const schemes = config.auth.map((item) => item.id);
11429
+ if (!openApiAuthenticationChoices(config).some((option) => "authentication" in option && dequal(option.authentication?.schemes, schemes)) && config.auth.length == 1) {
11430
+ const { id: _id, ...manual } = config.auth[0];
11431
+ return manual;
11432
+ }
11433
+ return { schemes };
11434
+ }
11435
+ function openApiConfigView(config) {
11436
+ return {
11437
+ sourceUrl: config.sourceUrl,
11438
+ path: config.path,
11439
+ method: config.method,
11440
+ serverUrl: config.serverUrl,
11441
+ authentication: authenticationView(config)
11442
+ };
11443
+ }
11444
+ var AuthoringOpenApiAuthenticationError = class extends Error {
11445
+ constructor(config) {
11446
+ super("Choose one complete authentication alternative advertised by this operation, or configure manual authentication.");
11447
+ this.code = "openapi.authentication-invalid";
11448
+ this.name = "AuthoringOpenApiAuthenticationError";
11449
+ this.details = {
11450
+ field: "config.authentication",
11451
+ choices: openApiAuthenticationChoices(config)
11452
+ };
11453
+ }
11454
+ };
11455
+ function prepareAuthentication(config, choice) {
11456
+ if (!("schemes" in choice)) return [{
11457
+ id: "manual",
11458
+ ...choice
11459
+ }];
11460
+ const names = new Set(choice.schemes);
11461
+ const matched = securityOptions(config.document, config.path, config.method).find((option) => option.auth != null && names.size == choice.schemes.length && option.auth.length == names.size && option.auth.every((auth) => names.has(auth.id)));
11462
+ if (matched?.auth == null) throw new AuthoringOpenApiAuthenticationError(config);
11463
+ return matched.auth;
11464
+ }
11465
+ /** Operation snapshots and credential handles remain stable until their business selection changes. */
11466
+ async function prepareOpenApiTask(config, previous, fetch, name, explicit = {}) {
11467
+ const current = previous?.executor.kind == "openapi" ? previous.executor : void 0;
11468
+ const changed = current == null || config.sourceUrl != current.sourceUrl || config.path != current.path || config.method != current.method;
11469
+ const authentication = changed && current != null && !explicit.authentication ? void 0 : config.authentication;
11470
+ let selected;
11471
+ if (!changed) selected = current;
11472
+ else {
11473
+ const document = await fetch(config.sourceUrl);
11474
+ if (authentication != null && !("schemes" in authentication)) {
11475
+ const saved = snapshot(document, config.path, config.method);
11476
+ selected = {
11477
+ kind: "openapi",
11478
+ sourceUrl: httpUrl(config.sourceUrl),
11479
+ path: config.path,
11480
+ method: config.method,
11481
+ serverUrl: serverAddress(servers(saved, config.path, config.method)[0], config.sourceUrl),
11482
+ document: saved,
11483
+ auth: []
11484
+ };
11485
+ } else selected = selectOperation(document, config.sourceUrl, config.path, config.method);
11486
+ }
11487
+ const defaultAuth = () => {
11488
+ const defaultSelection = securityOptions(current.document, current.path, current.method).find((option) => option.auth != null)?.auth;
11489
+ if (defaultSelection == null) throw new AuthoringOpenApiAuthenticationError(current);
11490
+ return defaultSelection;
11491
+ };
11492
+ const auth = authentication == null ? !changed && explicit.authentication ? defaultAuth() : selected.auth : !changed && dequal(authentication, authenticationView(current)) ? current.auth : prepareAuthentication(selected, authentication);
11493
+ const serverUrl = !changed && explicit.serverUrl && config.serverUrl == null ? serverAddress(servers(current.document, current.path, current.method)[0], current.sourceUrl) : changed && current != null && !explicit.serverUrl ? selected.serverUrl : config.serverUrl ?? selected.serverUrl;
11494
+ const executor = {
11495
+ ...selected,
11496
+ auth,
11497
+ serverUrl
11498
+ };
11499
+ if (previous != null && !changed && dequal(auth, current.auth)) return {
11500
+ ...previous,
11501
+ name,
11502
+ executor
11503
+ };
11504
+ return openApiTask(executor, name);
11505
+ }
11506
+ //#endregion
11507
+ //#region src/control/common/authoringSchema.ts
11508
+ var id$2 = string().min(1);
11509
+ var json$3 = json$5();
11510
+ var patch = record$3(id$2, json$3);
11511
+ var authoringTypes = [
11512
+ "manual",
11513
+ "webhook",
11514
+ "cron",
11515
+ "error",
11516
+ "poll",
11517
+ "integration",
11518
+ "code",
11519
+ "connector",
11520
+ "agent",
11521
+ "llm",
11522
+ "decision",
11523
+ "openapi",
11524
+ "condition",
11525
+ "value",
11526
+ "wait",
11527
+ "approval"
11528
+ ];
11529
+ var type = _enum(authoringTypes);
11530
+ var referenceSchema = id$2.describe("An existing node reference returned by read/search, or $alias for a preceding node.add in this edit batch. For node.add.as \"step\", reference \"$step\", never bare \"step\". Aliases are local to one batch.");
11531
+ var output = strictObject({
11532
+ kind: literal("output"),
11533
+ node: referenceSchema,
11534
+ port: id$2.optional().describe("Omit for a node with one output. For multiple outputs, choose a name from node details."),
11535
+ field: string().optional()
11536
+ });
11537
+ var variable = strictObject({
11538
+ kind: literal("variable"),
11539
+ name: id$2
11540
+ });
11541
+ var authoringSourceSchema = union([
11542
+ output,
11543
+ variable,
11544
+ strictObject({
11545
+ kind: literal("value"),
11546
+ value: json$3
11547
+ }),
11548
+ strictObject({ kind: literal("unset") }),
11549
+ strictObject({ kind: literal("default") }),
11550
+ strictObject({
11551
+ kind: literal("sources"),
11552
+ sources: array(union([output, variable])).min(1)
11553
+ })
11554
+ ]);
11555
+ var operand = union([
11556
+ strictObject({
11557
+ kind: literal("value"),
11558
+ value: json$3.optional(),
11559
+ schema: json$3.optional()
11560
+ }),
11561
+ output,
11562
+ variable
11563
+ ]);
11564
+ var agentTool = authoringDefinitionSchemas.agent.shape.tools.element.omit({
11565
+ id: true,
11566
+ inputs: true
11567
+ }).extend({ inputs: record$3(id$2, authoringDefinitionSchemas.agent.shape.tools.element.shape.inputs.element.shape.source).optional().describe("Action input sources by name. The tool resolves types from the Action. New inputs default to model-provided; existing sources are preserved when omitted.") }).strict();
11568
+ var notification = strictObject({
11569
+ ...authoringDefinitionSchemas.connector.shape,
11570
+ messageHandle: id$2,
11571
+ inputs: record$3(id$2, union([strictObject({
11572
+ kind: literal("value"),
11573
+ value: json$3
11574
+ }), strictObject({
11575
+ kind: literal("input"),
11576
+ input: id$2
11577
+ })]))
11578
+ });
11579
+ var field = strictObject({
11580
+ schema: json$3.optional(),
11581
+ nullable: boolean().optional(),
11582
+ description: string().optional()
11583
+ });
11584
+ var inputFields = record$3(id$2, field.extend({ default: json$3.optional() })).describe("Optional business input constraints by name. A binding to a new Code, Agent, LLM, Wait or Approval input automatically declares an input accepting any JSON. Existing constraints are preserved. Omitted schema accepts any JSON; omitted nullable is true. Use default for inherited values; input.set supplies data.");
11585
+ var outputFields = record$3(id$2, field).describe("Code return fields by name. Omitted schema accepts any JSON; omitted nullable is true.");
11586
+ var expression = strictObject({
11587
+ left: operand,
11588
+ operator: authoringDefinitionSchemas.condition.shape.cases.element.shape.groups.element.shape.expressions.element.shape.operator,
11589
+ right: operand.optional()
11590
+ });
11591
+ var all = strictObject({ all: array(expression) });
11592
+ var when = union([
11593
+ expression,
11594
+ all,
11595
+ strictObject({ any: array(union([expression, all])) })
11596
+ ]);
11597
+ var authoringConfigurations = {
11598
+ manual: strictObject({}),
11599
+ error: strictObject({ sourceFlowIds: array(id$2).optional() }),
11600
+ webhook: authoringDefinitionSchemas.webhook.omit({ bodyFields: true }).extend({ body: inputFields }).strict(),
11601
+ cron: strictObject({ schedule: authoringDefinitionSchemas.schedule }),
11602
+ poll: strictObject({
11603
+ key: id$2,
11604
+ connectionId: id$2.optional(),
11605
+ schedule: authoringDefinitionSchemas.schedule
11606
+ }),
11607
+ integration: strictObject({
11608
+ key: id$2,
11609
+ connectionId: id$2.optional()
11610
+ }),
11611
+ code: strictObject({
11612
+ inputs: inputFields,
11613
+ outputs: outputFields,
11614
+ capabilities: authoringDefinitionSchemas.capabilities.optional()
11615
+ }),
11616
+ connector: authoringDefinitionSchemas.connector.strict(),
11617
+ openapi: authoringOpenApiSchema,
11618
+ agent: authoringDefinitionSchemas.agent.omit({
11619
+ prompt: true,
11620
+ tools: true
11621
+ }).extend({
11622
+ inputs: inputFields,
11623
+ resultSchema: json$3.describe("JSON schema of the final result. Defaults to text. The tool manages the output definition; references can omit port."),
11624
+ tools: array(agentTool),
11625
+ notification: notification.optional()
11626
+ }).strict(),
11627
+ llm: authoringLlmConfiguration.extend({ inputs: inputFields }),
11628
+ decision: authoringDefinitionSchemas.decision,
11629
+ condition: strictObject({
11630
+ match: _enum(["first", "all"]),
11631
+ branches: array(strictObject({
11632
+ name: id$2,
11633
+ description: string().optional(),
11634
+ when
11635
+ }))
11636
+ }),
11637
+ value: strictObject({
11638
+ values: patch,
11639
+ outputs: outputFields
11640
+ }),
11641
+ wait: strictObject({ inputs: inputFields }),
11642
+ approval: strictObject({ inputs: inputFields })
11643
+ };
11644
+ var updates = strictObject({
11645
+ name: id$2.optional(),
11646
+ description: string().optional(),
11647
+ icon: string().optional(),
11648
+ maxExecutions: int().positive().optional(),
11649
+ timeoutMs: number().nonnegative().optional(),
11650
+ config: patch.optional().describe("Recursively merge configuration; omitted fields remain unchanged and arrays replace as a whole. This includes schema objects: {} does not clear an existing schema. Use clear paths to remove fields, e.g. [\"config\",\"inputs\",\"amount\",\"schema\",\"type\"].")
11651
+ });
11652
+ var authoringEditSchema = discriminatedUnion("op", [
11653
+ strictObject({
11654
+ op: literal("node.add"),
11655
+ as: id$2.regex(/^[A-Za-z][\w-]*$/).describe("Unique batch-local alias without the $ prefix. Later edits must reference this new node as $alias; the bare alias is not its node ID."),
11656
+ type,
11657
+ name: id$2,
11658
+ config: patch.optional(),
11659
+ inputs: record$3(id$2, authoringSourceSchema).optional().describe("Input data sources, applied after creation, as input.set operations. Execution edges are separate."),
11660
+ code: string().optional(),
11661
+ prompt: string().optional()
11662
+ }),
11663
+ strictObject({
11664
+ op: literal("node.update"),
11665
+ node: referenceSchema,
11666
+ set: updates.optional(),
11667
+ clear: array(array(id$2).min(1)).optional()
11668
+ }),
11669
+ strictObject({
11670
+ op: literal("node.remove"),
11671
+ node: referenceSchema
11672
+ }),
11673
+ strictObject({
11674
+ op: literal("input.set"),
11675
+ node: referenceSchema,
11676
+ input: id$2,
11677
+ source: authoringSourceSchema
11678
+ }),
11679
+ strictObject({
11680
+ op: _enum(["edge.connect", "edge.disconnect"]),
11681
+ source: referenceSchema,
11682
+ target: referenceSchema,
11683
+ branch: id$2.optional()
11684
+ }),
11685
+ strictObject({
11686
+ op: literal("text.edit"),
11687
+ node: referenceSchema,
11688
+ field: _enum(["code", "prompt"]),
11689
+ oldText: id$2,
11690
+ newText: string()
11691
+ }),
11692
+ strictObject({
11693
+ op: literal("text.set"),
11694
+ node: referenceSchema,
11695
+ field: _enum(["code", "prompt"]),
11696
+ text: string()
11697
+ })
11698
+ ]);
11699
+ var authoringRequestSchema = strictObject({
11700
+ baseRevision: id$2,
11701
+ requestId: id$2.max(256),
11702
+ edits: array(authoringEditSchema).min(1).max(1e3)
11703
+ });
11704
+ var authoringReadSchema = strictObject({
11705
+ revision: id$2.optional().describe("Fixed revision from a previous read; omit to read the current draft."),
11706
+ nodes: array(id$2).min(1).max(100).optional().describe("Node references to read in one batch. Mutually exclusive with text. Long texts return metadata."),
11707
+ text: strictObject({
11708
+ node: id$2,
11709
+ field: _enum(["code", "prompt"]),
11710
+ start: int().positive().default(1),
11711
+ lines: int().min(1).max(200).default(80)
11712
+ }).optional().describe("Read code or prompt by line (1-based). Mutually exclusive with nodes. Follow nextStart at the same revision until truncated is false.")
11713
+ }).refine((v) => v.nodes == null || v.text == null, "Choose nodes or text.").meta({
11714
+ not: { required: ["nodes", "text"] },
11715
+ description: "Omit nodes and text for an outline; provide nodes for details, or text for an excerpt."
11716
+ });
11717
+ var authoringCheckSchema = strictObject({ revisionId: id$2 });
11718
+ var authoringSearchSchema = strictObject({
11719
+ revision: id$2.optional(),
11720
+ query: id$2.max(1e3),
11721
+ type: type.optional(),
11722
+ offset: int().nonnegative().default(0),
11723
+ limit: int().min(1).max(100).default(20)
11724
+ });
11725
+ var authoringSchemaQuery = strictObject({
11726
+ type: type.optional(),
11727
+ action: id$2.optional()
11728
+ }).refine((v) => v.type == null || v.action == null, "Choose type or action.");
11729
+ var requestContracts = {
11730
+ read: {
11731
+ schema: authoringReadSchema,
11732
+ guidance: "Choose one mode: outline (omit nodes and text), node details (nodes), or text excerpt (text). nodes and text are mutually exclusive. Text defaults to 80 lines, at most 200 lines and 24000 characters. For the complete text, repeat at nextStart with the same revision until truncated is false.",
11733
+ examples: [
11734
+ {},
11735
+ {
11736
+ revision: "REVISION",
11737
+ nodes: ["NODE"]
11738
+ },
11739
+ {
11740
+ revision: "REVISION",
11741
+ text: {
11742
+ node: "NODE",
11743
+ field: "prompt",
11744
+ start: 1,
11745
+ lines: 80
11746
+ }
11747
+ }
11748
+ ]
11749
+ },
11750
+ search: {
11751
+ schema: authoringSearchSchema,
11752
+ guidance: "Search names, configurations and text. Keep the returned revision when following nextOffset or reading a match.",
11753
+ examples: [{
11754
+ query: "Customer summary",
11755
+ type: "agent"
11756
+ }]
11757
+ },
11758
+ edit: {
11759
+ schema: authoringRequestSchema,
11760
+ guidance: "Use the observed revision as baseRevision and a stable requestId. Edits are ordered and atomic. node.add.as declares a batch-local alias without $. Every later reference to that new node must use $alias, including node, edge source/target and output source node fields; a bare alias is not the node ID. Use returned node references in later batches. Updates recursively merge objects (including schemas); {} preserves existing fields. Arrays replace as a whole. Remove fields with clear paths. Text replacement requires exactly one match. Read the target text first. A saved draft can have validation diagnostics.",
11761
+ examples: [{
11762
+ baseRevision: "REVISION",
11763
+ requestId: "CREATE_REQUEST",
11764
+ edits: [
11765
+ {
11766
+ op: "node.add",
11767
+ as: "start",
11768
+ type: "manual",
11769
+ name: "Start"
11770
+ },
11771
+ {
11772
+ op: "node.add",
11773
+ as: "step",
11774
+ type: "code",
11775
+ name: "Process",
11776
+ code: "export default ({value}) => ({result:value})"
11777
+ },
11778
+ {
11779
+ op: "edge.connect",
11780
+ source: "$start",
11781
+ target: "$step"
11782
+ },
11783
+ {
11784
+ op: "node.update",
11785
+ node: "$step",
11786
+ set: { description: "Created and connected in one atomic edit." }
11787
+ }
11788
+ ]
11789
+ }, {
11790
+ baseRevision: "REVISION",
11791
+ requestId: "REQUEST",
11792
+ edits: [{
11793
+ op: "text.edit",
11794
+ node: "NODE",
11795
+ field: "prompt",
11796
+ oldText: "Original rule.",
11797
+ newText: "Updated rule."
11798
+ }]
11799
+ }]
11800
+ },
11801
+ check: {
11802
+ schema: authoringCheckSchema,
11803
+ guidance: "Check a fixed revision. In the CLI, pass this identity with --revision REVISION.",
11804
+ examples: [{ revisionId: "REVISION" }]
11805
+ }
11806
+ };
11807
+ /** Transport-independent discovery of the same requests the service validates. */
11808
+ function authoringRequestContract(name) {
11809
+ if (!Object.hasOwn(requestContracts, name)) return void 0;
11810
+ const contract = requestContracts[name];
11811
+ return {
11812
+ request: toJSONSchema(contract.schema, { io: "input" }),
11813
+ guidance: contract.guidance,
11814
+ examples: contract.examples
11815
+ };
11816
+ }
11817
+ function authoringSchema(kind) {
11818
+ return kind == null ? {
11819
+ types: authoringTypes,
11820
+ request: toJSONSchema(authoringRequestSchema),
11821
+ guidance: "Read a node type schema before creating or configuring it. Use $alias to reference a preceding node.add in the same batch. Read returns stable node references. Long code and prompt fields use text reads and edits. Changes use the observed baseRevision and a stable requestId."
11822
+ } : {
11823
+ type: kind,
11824
+ inputSources: ["poll", "integration"].includes(kind) ? [
11825
+ "value",
11826
+ "unset",
11827
+ "default"
11828
+ ] : [
11829
+ "manual",
11830
+ "error",
11831
+ "cron",
11832
+ "webhook",
11833
+ "value",
11834
+ "condition"
11835
+ ].includes(kind) ? [] : [
11836
+ "value",
11837
+ "unset",
11838
+ "default",
11839
+ "output",
11840
+ "variable",
11841
+ "sources"
11842
+ ],
11843
+ extensibleInputs: [
11844
+ "code",
11845
+ "agent",
11846
+ "llm",
11847
+ "wait",
11848
+ "approval"
11849
+ ].includes(kind),
11850
+ guidance: kind == "condition" ? "Edit branch operands through config.branches. A branch can test one expression, all expressions, or any alternatives. Unmatched execution uses branch otherwise." : ["poll", "integration"].includes(kind) ? "Configure static parameters with node.add.inputs or input.set. Definitions come from the selected Trigger key; execution output and variable sources are unavailable." : kind == "llm" ? "Configure model settings, message templates and history as defaults. Input bindings with the same names override these defaults; named business inputs can be bound directly. Template strings interpolate {{name}}." : kind == "openapi" ? "Select an operation; the tool resolves its ports and authentication. Read authenticationChoices from node details. authentication is replaced as a complete choice. Bind advertised credentials through inputs." : "Supply business configuration and input data. Fixed definitions are assembled by the tool. Existing constraints and defaults are preserved on partial updates.",
11851
+ example: {
11852
+ op: "node.add",
11853
+ as: "step",
11854
+ type: kind,
11855
+ name: "Step",
11856
+ ...{
11857
+ connector: { config: {
11858
+ action: "<Action ID>",
11859
+ connectionId: "<Connection ID>"
11860
+ } },
11861
+ poll: { config: {
11862
+ key: "<Trigger key>",
11863
+ schedule: [{
11864
+ type: "every",
11865
+ unit: "minute",
11866
+ value: 5
11867
+ }]
11868
+ } },
11869
+ integration: { config: { key: "<Trigger key>" } },
11870
+ openapi: { config: {
11871
+ sourceUrl: "https://example.com/openapi.json",
11872
+ path: "/items",
11873
+ method: "get"
11874
+ } },
11875
+ code: {
11876
+ code: "export default ({value}) => ({result:value})",
11877
+ inputs: { value: {
11878
+ kind: "value",
11879
+ value: "Hello"
11880
+ } }
11881
+ },
11882
+ condition: { config: {
11883
+ match: "first",
11884
+ branches: [{
11885
+ name: "yes",
11886
+ when: {
11887
+ left: {
11888
+ kind: "value",
11889
+ value: 120
11890
+ },
11891
+ operator: ">",
11892
+ right: {
11893
+ kind: "value",
11894
+ value: 100
11895
+ }
11896
+ }
11897
+ }]
11898
+ } },
11899
+ value: { config: { values: {
11900
+ threshold: 100,
11901
+ region: "EU"
11902
+ } } },
11903
+ webhook: { config: {
11904
+ method: "POST",
11905
+ body: { orderId: {
11906
+ schema: { type: "string" },
11907
+ nullable: false
11908
+ } }
11909
+ } },
11910
+ wait: {
11911
+ prompt: "Continue processing this order?",
11912
+ inputs: { order: {
11913
+ kind: "value",
11914
+ value: { orderId: "A-1" }
11915
+ } }
11916
+ },
11917
+ approval: {
11918
+ prompt: "Approve this order?",
11919
+ inputs: { order: {
11920
+ kind: "value",
11921
+ value: { orderId: "A-1" }
11922
+ } }
11923
+ },
11924
+ llm: {
11925
+ config: {
11926
+ model: { model: "deepseek-v4-flash" },
11927
+ template: [{
11928
+ role: "user",
11929
+ content: "Summarize {{order}}."
11930
+ }]
11931
+ },
11932
+ inputs: { order: {
11933
+ kind: "value",
11934
+ value: {
11935
+ orderId: "A-1",
11936
+ total: 42
11937
+ }
11938
+ } }
11939
+ },
11940
+ agent: {
11941
+ config: { model: "deepseek-v4-flash" },
11942
+ inputs: { orders: {
11943
+ kind: "value",
11944
+ value: [{
11945
+ orderId: "A-1",
11946
+ total: 42
11947
+ }]
11948
+ } },
11949
+ prompt: "Summarize {{orders}}."
11950
+ }
11951
+ }[kind]
11952
+ },
11953
+ configuration: toJSONSchema(authoringConfigurations[kind].partial()),
11954
+ texts: kind == "code" ? ["code"] : [
11955
+ "agent",
11956
+ "wait",
11957
+ "approval"
11958
+ ].includes(kind) ? ["prompt"] : []
11959
+ };
11960
+ }
11961
+ var authoringDiagnosticSchema = object$1({
11962
+ code: id$2,
11963
+ message: string(),
11964
+ nodes: array(id$2),
11965
+ field: string().optional(),
11966
+ line: number().optional(),
11967
+ column: number().optional()
11968
+ });
11969
+ var authoringCheckResponse = object$1({
11970
+ flowId: id$2,
11971
+ revisionId: id$2,
11972
+ valid: boolean(),
11973
+ diagnostics: array(authoringDiagnosticSchema),
11974
+ version: literal(1)
11975
+ });
11976
+ var authoringEditResponse = object$1({
11977
+ flowId: id$2,
11978
+ saved: literal(true),
11979
+ revision: id$2,
11980
+ nodes: record$3(id$2, id$2),
11981
+ changes: array(object$1({
11982
+ index: int(),
11983
+ op: id$2,
11984
+ node: id$2.optional()
11985
+ })),
11986
+ validation: object$1({
11987
+ status: _enum([
11988
+ "valid",
11989
+ "invalid",
11990
+ "unavailable"
11991
+ ]),
11992
+ diagnostics: array(authoringDiagnosticSchema).optional()
11993
+ }),
11994
+ version: literal(1)
11995
+ });
11996
+ var authoringReadResponse = object$1({
11997
+ flowId: id$2,
11998
+ revision: id$2,
11999
+ data: object$1({
12000
+ nodes: array(record$3(string(), json$3)).optional(),
12001
+ edges: array(json$3).optional(),
12002
+ text: record$3(string(), json$3).optional()
12003
+ }),
12004
+ version: literal(1)
12005
+ });
12006
+ var authoringSearchResponse = object$1({
12007
+ flowId: id$2,
12008
+ revision: id$2,
12009
+ data: object$1({
12010
+ matches: array(object$1({
12011
+ node: id$2,
12012
+ field: id$2,
12013
+ line: int().optional(),
12014
+ excerpt: string()
12015
+ })),
12016
+ total: int(),
12017
+ nextOffset: int().optional()
12018
+ }),
12019
+ version: literal(1)
12020
+ });
12021
+ //#endregion
12022
+ //#region src/trigger/common/contract.ts
12023
+ var errorOutputs = [
12024
+ {
12025
+ handle: "workflow",
12026
+ nullable: false,
12027
+ jsonSchema: {
12028
+ type: "object",
12029
+ additionalProperties: false,
12030
+ required: [
12031
+ "flowId",
12032
+ "name",
12033
+ "revisionId",
12034
+ "publicationId"
12035
+ ],
12036
+ properties: {
12037
+ flowId: { type: "string" },
12038
+ name: { type: "string" },
12039
+ revisionId: { type: "string" },
12040
+ publicationId: { type: ["string", "null"] }
12041
+ }
12042
+ }
12043
+ },
12044
+ {
12045
+ handle: "execution",
12046
+ nullable: false,
12047
+ jsonSchema: {
12048
+ type: "object",
12049
+ additionalProperties: false,
12050
+ required: [
12051
+ "runId",
12052
+ "status",
12053
+ "startedAt",
12054
+ "finishedAt"
12055
+ ],
12056
+ properties: {
12057
+ runId: { type: "string" },
12058
+ status: { enum: ["failed", "indeterminate"] },
12059
+ startedAt: { type: ["string", "null"] },
12060
+ finishedAt: { type: "string" }
12061
+ }
12062
+ }
12063
+ },
12064
+ {
12065
+ handle: "error",
12066
+ nullable: false,
12067
+ jsonSchema: {
12068
+ type: "object",
12069
+ additionalProperties: false,
12070
+ required: ["code", "message"],
12071
+ properties: {
12072
+ code: { type: "string" },
12073
+ message: { type: "string" },
12074
+ nodeId: { type: "string" },
12075
+ jobId: { type: "string" },
12076
+ path: {
12077
+ type: "array",
12078
+ items: { type: "string" }
12079
+ }
12080
+ }
12081
+ }
12082
+ }
12083
+ ];
12084
+ var webhookOutputs = [
12085
+ {
12086
+ handle: "headers",
12087
+ jsonSchema: {
12088
+ type: "object",
12089
+ additionalProperties: { type: "string" }
12090
+ },
12091
+ nullable: false
12092
+ },
12093
+ {
12094
+ handle: "query",
12095
+ jsonSchema: {
12096
+ type: "object",
12097
+ additionalProperties: {
12098
+ type: ["string", "array"],
12099
+ items: { type: "string" }
12100
+ }
12101
+ },
12102
+ nullable: false
12103
+ },
12104
+ {
12105
+ handle: "body",
12106
+ jsonSchema: {
12107
+ type: "object",
12108
+ additionalProperties: true
12109
+ },
12110
+ nullable: false
12111
+ },
12112
+ {
12113
+ handle: "webhookUrl",
12114
+ jsonSchema: { type: "string" },
12115
+ nullable: false
12116
+ }
12117
+ ];
12118
+ var cronOutputs = [{
12119
+ handle: "scheduledAt",
12120
+ jsonSchema: {
12121
+ type: "string",
12122
+ format: "date-time"
12123
+ },
12124
+ nullable: false
12125
+ }];
12126
+ function triggerOutputDefinitions(trigger) {
12127
+ switch (trigger.kind) {
12128
+ case "error": return errorOutputs;
12129
+ case "manual": return [];
12130
+ case "cron": return cronOutputs;
12131
+ case "poll":
12132
+ case "integration": return trigger.definition.outputs;
12133
+ case "webhook": return webhookOutputs.filter((port) => port.handle !== "body" || webhookSupportsBody(trigger.method)).map((port) => port.handle === "body" ? Object.assign({}, port, { jsonSchema: {
12134
+ type: "object",
12135
+ additionalProperties: false,
12136
+ properties: Object.fromEntries(trigger.bodyFields.map((field) => [field.handle, field.jsonSchema])),
12137
+ required: trigger.bodyFields.filter((field) => !field.nullable && !Object.hasOwn(field, "value")).map((field) => field.handle)
12138
+ } }) : port);
12139
+ }
12140
+ }
12141
+ function triggerOutputPorts(trigger) {
12142
+ return Object.fromEntries(triggerOutputDefinitions(trigger).map(({ handle, ...port }) => [handle, port]));
12143
+ }
12144
+ //#endregion
12145
+ //#region src/flow/common/graph.ts
12146
+ function nodeInputPorts(node) {
12147
+ switch (node.kind) {
12148
+ case "condition": return conditionInputPorts(node);
12149
+ case "value": return {};
12150
+ case "task": return portsByHandle([...node.task.inputs, ...node.additionalInputs ?? []]);
12151
+ case "approval":
12152
+ case "wait": return portsByHandle(node.inputDefinitions);
12153
+ case "cron":
12154
+ case "integration":
12155
+ case "poll":
12156
+ case "error":
12157
+ case "manual":
12158
+ case "webhook": return {};
12159
+ }
12160
+ }
12161
+ function resolutionActions(node) {
12162
+ return node.kind == "wait" ? ["continue"] : ["approve", "reject"];
12163
+ }
12164
+ var objectPort = (properties) => ({
12165
+ nullable: false,
12166
+ jsonSchema: {
12167
+ type: "object",
12168
+ properties,
12169
+ required: Object.keys(properties),
12170
+ additionalProperties: false
12171
+ }
12172
+ });
12173
+ function resolutionOutputPorts(node) {
12174
+ const actions = resolutionActions(node);
12175
+ const inputs = {
12176
+ type: "object",
12177
+ properties: Object.fromEntries(node.inputDefinitions.map((port) => [port.handle, {}])),
12178
+ required: node.inputDefinitions.map((port) => port.handle),
12179
+ additionalProperties: false
12180
+ };
12181
+ return {
12182
+ pending: objectPort({
12183
+ inputs,
12184
+ prompt: { type: "string" },
12185
+ ...Object.fromEntries(actions.map((action) => [`${action}Url`, { type: "string" }])),
12186
+ expiresAt: { type: "string" }
12187
+ }),
12188
+ ...Object.fromEntries(actions.map((action) => [action, objectPort({
12189
+ inputs,
12190
+ action: { const: action },
12191
+ resolvedAt: { type: "string" },
12192
+ comment: { type: ["string", "null"] }
12193
+ })]))
12194
+ };
12195
+ }
12196
+ function nodeOutputPorts(node) {
12197
+ switch (node.kind) {
12198
+ case "condition": return {};
12199
+ case "value": return portsByHandle(node.values);
12200
+ case "task": return portsByHandle(node.task.outputs);
12201
+ case "approval":
12202
+ case "wait": return resolutionOutputPorts(node);
12203
+ case "cron":
12204
+ case "integration":
12205
+ case "poll":
12206
+ case "error":
12207
+ case "manual":
12208
+ case "webhook": return triggerOutputPorts(node);
12209
+ }
12210
+ }
12211
+ //#endregion
12212
+ //#region src/flow/common/moduleChanges.ts
12213
+ async function imports(source) {
12214
+ try {
12215
+ const { parse } = await import("./lib-DrKav3HG.js");
12216
+ const program = parse(source, {
12217
+ errorRecovery: true,
12218
+ sourceType: "module"
12219
+ }).program;
12220
+ const dependencies = /* @__PURE__ */ new Set();
12221
+ for (const statement of program.body) {
12222
+ if (statement.type != "ImportDeclaration") continue;
12223
+ const match = /^\.\/(.+)\.mjs$/.exec(statement.source.value);
12224
+ if (match?.[1] != null) dependencies.add(match[1]);
12225
+ }
12226
+ return [...dependencies].toSorted();
12227
+ } catch {
12228
+ return [];
12229
+ }
12230
+ }
12231
+ //#endregion
12232
+ //#region src/flow/common/nodeChanges.ts
12233
+ var codeTaskTemplate = `export default async function (inputs, context) {
12234
+ return { result: inputs.value }
12235
+ }
12236
+ `;
12237
+ var defaultCodeTaskPorts = {
12238
+ inputs: [{
12239
+ handle: "value",
12240
+ jsonSchema: { type: "string" },
12241
+ nullable: true,
12242
+ value: "foo"
12243
+ }],
12244
+ outputs: [{
12245
+ handle: "result",
12246
+ jsonSchema: {},
12247
+ nullable: true
12248
+ }]
12249
+ };
12250
+ function createCodeTask(identity, name, module = void 0, ports = defaultCodeTaskPorts) {
12251
+ return [{
12252
+ kind: "module.create",
12253
+ module: {
12254
+ ...module ?? {
12255
+ imports: [],
12256
+ source: codeTaskTemplate
12257
+ },
12258
+ name
12259
+ },
12260
+ moduleId: identity.moduleId
12261
+ }, {
12262
+ kind: "graph.node.create",
12263
+ node: {
12264
+ inputs: defaultInputs(ports.inputs),
12265
+ kind: "task",
12266
+ name,
12267
+ task: {
12268
+ capabilities: ports.capabilities ?? [{
12269
+ kind: "connector",
12270
+ mode: "independent",
12271
+ actions: []
12272
+ }],
12273
+ inputs: ports.inputs,
12274
+ moduleId: identity.moduleId,
12275
+ name,
12276
+ outputs: ports.outputs
12277
+ }
12278
+ },
12279
+ nodeId: identity.nodeId
12280
+ }];
12281
+ }
12282
+ function createManagedTask(identity, task) {
12283
+ return [{
12284
+ kind: "graph.node.create",
12285
+ node: {
12286
+ inputs: defaultInputs(task.inputs),
12287
+ kind: "task",
12288
+ name: task.name,
12289
+ task
12290
+ },
12291
+ nodeId: identity.nodeId
12292
+ }];
12293
+ }
12294
+ function createAgentTask(identity, name, defaults = {}) {
12295
+ return createManagedTask(identity, {
12296
+ name,
12297
+ inputs: defaults.inputs ?? [{
12298
+ handle: "input",
12299
+ jsonSchema: { type: "string" },
12300
+ nullable: false,
12301
+ value: ""
12302
+ }],
12303
+ outputs: [{
12304
+ handle: "output",
12305
+ jsonSchema: { type: "string" },
12306
+ nullable: false,
12307
+ description: defaults.outputDescription ?? "The final result produced by the Agent."
12308
+ }],
12309
+ executor: {
12310
+ kind: "agent",
12311
+ model: "deepseek-v4-flash",
12312
+ prompt: defaults.prompt ?? "Summarize the following content, highlighting key points and next steps.\n\n{{input}}",
12313
+ maxRounds: 10,
12314
+ tools: []
12315
+ }
12316
+ });
12317
+ }
12318
+ function createLlmTask(identity, name, mode, outputDescription, options = {}) {
12319
+ const values = options.inputs ?? {};
12320
+ return createManagedTask(identity, {
12321
+ executor: {
12322
+ kind: "llm",
12323
+ mode
12324
+ },
12325
+ inputs: [
12326
+ {
12327
+ handle: "messages",
12328
+ jsonSchema: {
12329
+ items: { type: "object" },
12330
+ type: "array"
12331
+ },
12332
+ nullable: true,
12333
+ value: llmInputValue(values, "messages", null)
12334
+ },
12335
+ {
12336
+ handle: "input",
12337
+ jsonSchema: { type: "string" },
12338
+ nullable: false,
12339
+ value: llmInputValue(values, "input", "Alex")
12340
+ },
12341
+ {
12342
+ handle: "template",
12343
+ jsonSchema: {
12344
+ items: { type: "object" },
12345
+ minItems: 1,
12346
+ type: "array"
12347
+ },
12348
+ nullable: false,
12349
+ value: llmInputValue(values, "template", [{
12350
+ content: "Hello, I'm {{input}}",
12351
+ role: "user"
12352
+ }])
12353
+ },
12354
+ {
12355
+ handle: "model",
12356
+ jsonSchema: { type: "object" },
12357
+ nullable: false,
12358
+ value: llmInputValue(values, "model", { model: "deepseek-v4-flash" })
12359
+ }
12360
+ ],
12361
+ name,
12362
+ outputs: [{
12363
+ ...options.output,
12364
+ description: options.output?.description ?? outputDescription,
12365
+ handle: "output",
12366
+ jsonSchema: options.output?.jsonSchema ?? (mode == "chat" ? { type: "string" } : {}),
12367
+ nullable: options.output?.nullable ?? false
12368
+ }]
12369
+ });
12370
+ }
12371
+ function createCondition(nodeId, name) {
12372
+ return [{
12373
+ kind: "graph.node.create",
12374
+ node: {
12375
+ cases: [{
12376
+ groups: [{ expressions: [{
12377
+ left: { kind: "value" },
12378
+ operator: "==",
12379
+ right: { kind: "value" }
12380
+ }] }],
12381
+ output: "case"
12382
+ }],
12383
+ matchMode: "first",
12384
+ inputs: {},
12385
+ kind: "condition",
12386
+ name
12387
+ },
12388
+ nodeId
12389
+ }];
12390
+ }
12391
+ function createValue(nodeId, name, values = [{
12392
+ handle: "value",
12393
+ jsonSchema: {},
12394
+ nullable: true,
12395
+ value: null
12396
+ }]) {
12397
+ return [{
12398
+ kind: "graph.node.create",
12399
+ node: {
12400
+ inputs: {},
12401
+ kind: "value",
12402
+ name,
12403
+ values
12404
+ },
12405
+ nodeId
12406
+ }];
12407
+ }
12408
+ function createWait(nodeId, name) {
12409
+ return [{
12410
+ kind: "graph.node.create",
12411
+ node: {
12412
+ inputDefinitions: [],
12413
+ inputs: {},
12414
+ kind: "wait",
12415
+ name,
12416
+ prompt: name
12417
+ },
12418
+ nodeId
12419
+ }];
12420
+ }
12421
+ function createApproval(nodeId, name) {
12422
+ return [{
12423
+ kind: "graph.node.create",
12424
+ node: {
12425
+ inputDefinitions: [],
12426
+ inputs: {},
12427
+ kind: "approval",
12428
+ name,
12429
+ prompt: name
12430
+ },
12431
+ nodeId
12432
+ }];
12433
+ }
12434
+ function createBuiltinTrigger(nodeId, node) {
12435
+ return [{
12436
+ kind: "graph.node.create",
12437
+ node,
12438
+ nodeId
12439
+ }];
12440
+ }
12441
+ function createProviderTrigger(nodeId, definition, options) {
12442
+ const name = options.name ?? definition.displayName;
12443
+ return [{
12444
+ kind: "graph.node.create",
12445
+ node: definition.type == "poll" ? {
12446
+ ...options.connectionId == null ? {} : { connectionId: options.connectionId },
12447
+ config: inputValues(options.config),
12448
+ definition,
12449
+ kind: "poll",
12450
+ name,
12451
+ pollTimes: options.schedule ?? [{
12452
+ type: "every",
12453
+ unit: "minute",
12454
+ value: 5
12455
+ }]
12456
+ } : {
12457
+ ...options.connectionId == null ? {} : { connectionId: options.connectionId },
12458
+ config: inputValues(options.config),
12459
+ definition,
12460
+ kind: "integration",
12461
+ name
12462
+ },
12463
+ nodeId
12464
+ }];
12465
+ }
12466
+ function cleanVariableBindings(content, operations) {
12467
+ const before = bindingReferences(content.document);
12468
+ const changed = applyFlowChanges(content, operations);
12469
+ const after = bindingReferences(changed.document);
12470
+ return [...operations, ...[...before.keys()].flatMap((bindingId) => after.has(bindingId) || changed.document.bindings[bindingId]?.kind != "variable" ? [] : [{
12471
+ bindingId,
12472
+ kind: "binding.delete"
12473
+ }])];
12474
+ }
12475
+ function bindingReferences(document) {
12476
+ const references = /* @__PURE__ */ new Map();
12477
+ const add = (bindingId) => {
12478
+ references.set(bindingId, (references.get(bindingId) ?? 0) + 1);
12479
+ };
12480
+ for (const node of Object.values(document.graph.nodes)) {
12481
+ if (!("inputs" in node)) continue;
12482
+ const inputs = Object.values(nodeInputMappings(node));
12483
+ for (const mapping of inputs) {
12484
+ if (mapping.kind != "sources") continue;
12485
+ for (const source of mapping.sources) if (source.kind == "binding") add(source.bindingId);
12486
+ }
12487
+ }
12488
+ return references;
12489
+ }
12490
+ function defaultInputs(ports) {
12491
+ return Object.fromEntries(ports.flatMap((port) => "handle" in port && Object.hasOwn(port, "value") ? [[port.handle, {
12492
+ kind: "value",
12493
+ value: port.value
12494
+ }]] : []));
12495
+ }
12496
+ function llmInputValue(values, handle, fallback) {
12497
+ return values != null && Object.hasOwn(values, handle) ? values[handle] : fallback;
12498
+ }
12499
+ function createDecisionTask(identity, name = "AI Decision", questions) {
12500
+ return createManagedTask(identity, decisionTask(questions, name));
12501
+ }
12502
+ //#endregion
12503
+ //#region src/control/common/authoringCondition.ts
12504
+ /** Preserve empty groups in invalid drafts; do not turn them into unconditional branches. */
12505
+ function conditionConfigurationView(node, source) {
12506
+ const operand = (value) => value.kind == "source" ? source(value.source) : {
12507
+ kind: "value",
12508
+ ...value.value === void 0 ? {} : { value: value.value },
12509
+ ...value.jsonSchema === void 0 ? {} : { schema: value.jsonSchema }
12510
+ };
12511
+ const expression = (value) => ({
12512
+ left: operand(value.left),
12513
+ operator: value.operator,
12514
+ ...value.right === void 0 ? {} : { right: operand(value.right) }
12515
+ });
12516
+ return {
12517
+ match: node.matchMode,
12518
+ branches: node.cases.map((branch) => {
12519
+ const groups = branch.groups.map((group) => group.expressions.length == 1 ? expression(group.expressions[0]) : { all: group.expressions.map(expression) });
12520
+ return {
12521
+ name: branch.output,
12522
+ ...branch.description === void 0 ? {} : { description: branch.description },
12523
+ when: groups.length == 1 ? groups[0] : { any: groups }
12524
+ };
12525
+ })
12526
+ };
12527
+ }
12528
+ function prepareConditionConfiguration(config, source) {
12529
+ const operand = (value) => value.kind == "value" ? {
12530
+ kind: "value",
12531
+ ...value.value === void 0 ? {} : { value: value.value },
12532
+ ...value.schema === void 0 ? {} : { jsonSchema: value.schema }
12533
+ } : {
12534
+ kind: "source",
12535
+ source: source(value)
12536
+ };
12537
+ const expression = (value) => ({
12538
+ left: operand(value.left),
12539
+ operator: value.operator,
12540
+ ...value.right === void 0 ? {} : { right: operand(value.right) }
12541
+ });
12542
+ return {
12543
+ matchMode: config.match,
12544
+ cases: config.branches.map((branch) => {
12545
+ const groups = "any" in branch.when ? branch.when.any : [branch.when];
12546
+ return {
12547
+ output: branch.name,
12548
+ ...branch.description === void 0 ? {} : { description: branch.description },
12549
+ groups: groups.map((group) => ({ expressions: ("all" in group ? group.all : [group]).map(expression) }))
12550
+ };
12551
+ })
12552
+ };
12553
+ }
12554
+ /** Map a path relative to a persisted Condition configuration into its normalized public config. */
12555
+ function conditionConfigurationFieldPath(node, path) {
12556
+ if (path[0] == "matchMode") return ["match", ...path.slice(1)];
12557
+ if (path[0] != "cases") return path;
12558
+ if (path.length == 1) return ["branches"];
12559
+ const branchIndex = Number(path[1]), branch = node.cases[branchIndex], base = ["branches", path[1]];
12560
+ if (path[2] == "output") return [
12561
+ ...base,
12562
+ "name",
12563
+ ...path.slice(3)
12564
+ ];
12565
+ if (path[2] != "groups") return [...base, ...path.slice(2)];
12566
+ base.push("when");
12567
+ if (branch == null || path.length == 3) return base;
12568
+ const groupIndex = Number(path[3]), group = branch.groups[groupIndex];
12569
+ if (branch.groups.length != 1) base.push("any", path[3]);
12570
+ if (path[4] != "expressions") return [...base, ...path.slice(4)];
12571
+ if (group == null || path.length == 5) return group?.expressions.length == 1 ? base : [...base, "all"];
12572
+ if (group.expressions.length != 1) base.push("all", path[5]);
12573
+ const remaining = path.slice(6).filter((part, index) => !(index == 1 && part == "source"));
12574
+ if (remaining[0] == "left" || remaining[0] == "right") switch (remaining[1]) {
12575
+ case "jsonSchema":
12576
+ remaining[1] = "schema";
12577
+ break;
12578
+ case "nodeId":
12579
+ remaining[1] = "node";
12580
+ break;
12581
+ case "output":
12582
+ remaining[1] = "port";
12583
+ break;
12584
+ case "bindingId": remaining[1] = "name";
12585
+ }
12586
+ return [...base, ...remaining];
12587
+ }
12588
+ //#endregion
12589
+ //#region src/control/common/authoringDiagnosticFields.ts
12590
+ var metadata = /* @__PURE__ */ new Set([
12591
+ "name",
12592
+ "description",
12593
+ "icon",
12594
+ "timeoutMs",
12595
+ "maxExecutions"
12596
+ ]);
12597
+ function portField(ports, path, parent) {
12598
+ const port = ports[Number(path[0])];
12599
+ if (port == null || !("handle" in port)) return parent;
12600
+ const field = `${parent}.${port.handle}`;
12601
+ switch (path[1]) {
12602
+ case "jsonSchema": return [
12603
+ field,
12604
+ "schema",
12605
+ ...path.slice(2)
12606
+ ].join(".");
12607
+ case "value": return [
12608
+ field,
12609
+ "default",
12610
+ ...path.slice(2)
12611
+ ].join(".");
12612
+ case "nullable":
12613
+ case "description": return [field, ...path.slice(1)].join(".");
12614
+ default: return field;
12615
+ }
12616
+ }
12617
+ /** Accept a decoded JSON Pointer, including or omitting its initial empty component. */
12618
+ function authoringDiagnosticField(_content, node, parts) {
12619
+ const path = parts[0] == "" ? parts.slice(1) : parts;
12620
+ if (path[0] == "modules") return "code";
12621
+ let location = path[0] == "document" && path[1] == "graph" && path[2] == "nodes" ? path.slice(4) : path;
12622
+ const inlineDefinition = node.kind == "task" && location[0] == "task";
12623
+ if (inlineDefinition) location = location.slice(1);
12624
+ if (location.length == 0) return "config";
12625
+ const head = location[0];
12626
+ if (!inlineDefinition && metadata.has(head)) return location.join(".");
12627
+ if (head == "prompt") return "prompt";
12628
+ if (head == "inputs" && !inlineDefinition) {
12629
+ if (node.kind == "condition" && location[1] != null) {
12630
+ const [branch, group, expression, side] = location[1].split("/");
12631
+ if (branch != null && group != null && expression != null && (side == "left" || side == "right")) return ["config", ...conditionConfigurationFieldPath(node, [
12632
+ "cases",
12633
+ branch,
12634
+ "groups",
12635
+ group,
12636
+ "expressions",
12637
+ expression,
12638
+ side
12639
+ ])].join(".");
12640
+ return "config.branches";
12641
+ }
12642
+ return location[1] == null ? "inputs" : `inputs.${location[1]}`;
12643
+ }
12644
+ if (node.kind == "task") {
12645
+ const task = node.task;
12646
+ if (task == null) return "config";
12647
+ const executor = "executor" in task ? task.executor : void 0;
12648
+ if (head == "additionalInputs") return portField(node.additionalInputs ?? [], location.slice(1), "config.inputs");
12649
+ if (head == "inputs" || head == "outputs") {
12650
+ const ports = task[head];
12651
+ const port = ports[Number(location[1])];
12652
+ if (head == "outputs" && (executor?.kind == "agent" || executor?.kind == "llm")) return location[2] == "jsonSchema" ? [
12653
+ "config",
12654
+ "resultSchema",
12655
+ ...location.slice(3)
12656
+ ].join(".") : "config.resultSchema";
12657
+ if (head == "inputs" && executor?.kind == "llm" && port != null && "handle" in port && [
12658
+ "model",
12659
+ "template",
12660
+ "messages"
12661
+ ].includes(port.handle)) return [
12662
+ "config",
12663
+ port.handle,
12664
+ ...location[2] == "value" ? location.slice(3) : []
12665
+ ].join(".");
12666
+ const custom = executor == null || executor.kind == "agent" || executor.kind == "llm";
12667
+ return portField(ports, location.slice(1), custom ? `config.${head}` : head == "inputs" ? "inputPorts" : "outputPorts");
12668
+ }
12669
+ if (head == "executor") {
12670
+ const field = location[1];
12671
+ if (field == null || field == "kind") return "config";
12672
+ if (field == "prompt") return "prompt";
12673
+ if (executor?.kind == "openapi") {
12674
+ if (field == "document") return "config";
12675
+ if (field == "auth") return "config.authentication";
12676
+ }
12677
+ if (executor?.kind == "agent") {
12678
+ if (field == "tools") {
12679
+ const tool = executor.tools[Number(location[2])];
12680
+ if (tool == null) return "config.tools";
12681
+ const base = `config.tools.${location[2]}`;
12682
+ if (location[3] == "id") return base;
12683
+ if (location[3] == "inputs") {
12684
+ const input = tool.inputs[Number(location[4])];
12685
+ if (input == null) return `${base}.inputs`;
12686
+ return location[5] == "source" ? [
12687
+ base,
12688
+ "inputs",
12689
+ input.handle,
12690
+ ...location.slice(6)
12691
+ ].join(".") : `${base}.inputs.${input.handle}`;
12692
+ }
12693
+ }
12694
+ if (field == "notification" && location[2] == "inputDefinitions") return "config.notification.inputs";
12695
+ }
12696
+ return ["config", ...location.slice(1)].join(".");
12697
+ }
12698
+ if (head == "capabilities") return ["config", ...location].join(".");
12699
+ if (head == "name") return "name";
12700
+ return "config";
12701
+ }
12702
+ switch (node.kind) {
12703
+ case "condition": return head == "cases" || head == "matchMode" ? ["config", ...conditionConfigurationFieldPath(node, location)].join(".") : "config";
12704
+ case "wait":
12705
+ case "approval": return head == "inputDefinitions" ? portField(node.inputDefinitions, location.slice(1), "config.inputs") : "config";
12706
+ case "webhook":
12707
+ if (head == "bodyFields") return portField(node.bodyFields, location.slice(1), "config.body");
12708
+ return head == "method" || head == "options" ? ["config", ...location].join(".") : "config";
12709
+ case "value": {
12710
+ if (head != "values") return "config";
12711
+ const port = node.values[Number(location[1])];
12712
+ if (port == null) return "config.values";
12713
+ if (location[2] == "value") return [
12714
+ "config",
12715
+ "values",
12716
+ port.handle,
12717
+ ...location.slice(3)
12718
+ ].join(".");
12719
+ return portField(node.values, location.slice(1), "config.outputs");
12720
+ }
12721
+ case "cron": return head == "cronTimes" ? [
12722
+ "config",
12723
+ "schedule",
12724
+ ...location.slice(1)
12725
+ ].join(".") : "config";
12726
+ case "poll":
12727
+ case "integration":
12728
+ if (head == "config") return location[1] == null ? "inputs" : `inputs.${location[1]}`;
12729
+ if (head == "definition") return location[1] == "configInputs" ? portField(node.definition.configInputs, location.slice(2), "inputPorts") : "config.key";
12730
+ if (head == "pollTimes") return [
12731
+ "config",
12732
+ "schedule",
12733
+ ...location.slice(1)
12734
+ ].join(".");
12735
+ return head == "connectionId" ? "config.connectionId" : "config";
12736
+ case "error": return head == "sourceFlowIds" ? ["config", ...location].join(".") : "config";
12737
+ default: return "config";
12738
+ }
12739
+ }
12740
+ //#endregion
12741
+ //#region src/control/common/authoringFields.ts
12742
+ var record$1 = (value) => value != null && typeof value == "object" && !Array.isArray(value) ? value : {};
12743
+ /** Business field contracts, independent of storage handles and presentation groups. */
12744
+ function fieldsView(ports) {
12745
+ return Object.fromEntries(ports.flatMap((port) => "handle" in port ? [[port.handle, {
12746
+ schema: port.jsonSchema,
12747
+ nullable: port.nullable,
12748
+ ...port.description == null ? {} : { description: port.description },
12749
+ ...Object.hasOwn(port, "value") ? { default: port.value } : {}
12750
+ }]] : []));
12751
+ }
12752
+ function fieldsToPorts(fields, previous) {
12753
+ const remaining = new Map(Object.entries(record$1(fields)));
12754
+ function port(handle, value) {
12755
+ const field = record$1(value);
12756
+ return {
12757
+ handle,
12758
+ jsonSchema: Object.hasOwn(field, "schema") ? field.schema : {},
12759
+ nullable: field.nullable ?? true,
12760
+ ...field.description == null ? {} : { description: String(field.description) },
12761
+ ...Object.hasOwn(field, "default") ? { value: field.default } : {}
12762
+ };
12763
+ }
12764
+ return [...previous.flatMap((old) => {
12765
+ if (!("handle" in old)) return [old];
12766
+ if (!remaining.has(old.handle)) return [];
12767
+ const value = remaining.get(old.handle);
12768
+ remaining.delete(old.handle);
12769
+ return [dequal(fieldsView([old])[old.handle], value) ? old : port(old.handle, value)];
12770
+ }), ...Array.from(remaining, ([handle, value]) => port(handle, value))];
12771
+ }
12772
+ //#endregion
12773
+ //#region src/control/common/authoringTools.ts
12774
+ var AuthoringToolInputError = class extends Error {
12775
+ constructor(details) {
12776
+ super(`Unknown input ${JSON.stringify(details.input)} for tool ${JSON.stringify(details.tool)}. Choose from: ${details.choices.join(", ") || "(none)"}.`);
12777
+ this.code = "tool.input-not-found";
12778
+ this.name = "AuthoringToolInputError";
12779
+ this.details = details;
12780
+ }
12781
+ };
12782
+ function outwardAgentTools(tools) {
12783
+ return tools.map(({ id: _id, inputs, ...tool }) => ({
12784
+ ...tool,
12785
+ inputs: Object.fromEntries(inputs.map((input) => [input.handle, input.source]))
12786
+ }));
12787
+ }
12788
+ /** Keep persisted Action contracts until the caller selects a different Action. */
12789
+ async function prepareAgentTools(tools, previous, action, id) {
12790
+ const prepared = [];
12791
+ for (const tool of tools) {
12792
+ const old = previous.find((item) => item.name == tool.name);
12793
+ const retained = old?.action == tool.action ? old : void 0;
12794
+ const definition = retained == null ? await action(tool.action) : void 0;
12795
+ const ports = retained?.inputs ?? Object.entries(definition.inputs).map(([handle, port]) => Object.assign({}, port, {
12796
+ handle,
12797
+ source: { kind: "model" }
12798
+ }));
12799
+ const choices = ports.map((port) => port.handle);
12800
+ for (const input of Object.keys(tool.inputs ?? {})) if (!choices.includes(input)) throw new AuthoringToolInputError({
12801
+ tool: tool.name,
12802
+ action: tool.action,
12803
+ input,
12804
+ choices
12805
+ });
12806
+ const { inputs: sources, ...settings } = tool;
12807
+ prepared.push({
12808
+ ...settings,
12809
+ id: old?.id ?? id(),
12810
+ action: definition?.actionId ?? tool.action,
12811
+ inputs: ports.map((port) => sources != null && Object.hasOwn(sources, port.handle) ? Object.assign({}, port, { source: sources[port.handle] }) : port)
12812
+ });
12813
+ }
12814
+ return prepared;
12815
+ }
12816
+ //#endregion
12817
+ //#region src/control/common/authoring.ts
12818
+ var record = (value) => value != null && typeof value == "object" && !Array.isArray(value) ? value : {};
12819
+ var json$2 = (value) => JSON.parse(JSON.stringify(value));
12820
+ var AuthoringError = class extends Error {
12821
+ constructor(code, message, details = {}) {
12822
+ super(message);
12823
+ this.code = code;
12824
+ this.details = details;
12825
+ this.name = "AuthoringError";
12826
+ }
12827
+ };
12828
+ function fail(code, message, details = {}) {
12829
+ throw new AuthoringError(code, message, details);
12830
+ }
12831
+ function nodeAt(content, ref) {
12832
+ return (Object.hasOwn(content.document.graph.nodes, ref) ? content.document.graph.nodes[ref] : void 0) ?? fail("node.not-found", `Node ${JSON.stringify(ref)} does not exist.`, { node: ref });
12833
+ }
12834
+ function taskAt(node) {
12835
+ return node.kind == "task" ? node.task : void 0;
12836
+ }
12837
+ var llmReservedInputs = [
12838
+ "model",
12839
+ "template",
12840
+ "messages"
12841
+ ];
12842
+ function inputDefinitions(node) {
12843
+ if (node.kind == "condition") return {};
12844
+ if (node.kind == "poll" || node.kind == "integration") return Object.fromEntries(node.definition.configInputs.flatMap((port) => "handle" in port ? [[port.handle, port]] : []));
12845
+ return nodeInputPorts(node);
12846
+ }
12847
+ function inputMappings(node) {
12848
+ return node.kind == "condition" ? {} : node.kind == "poll" || node.kind == "integration" ? node.config : nodeInputMappings(node);
12849
+ }
12850
+ function typeOf(node) {
12851
+ const task = taskAt(node);
12852
+ return node.kind != "task" ? node.kind : task != null && "executor" in task ? task.executor.kind : "code";
12853
+ }
12854
+ function outwardSource(content, value) {
12855
+ if (Array.isArray(value)) return value.map((v) => outwardSource(content, v));
12856
+ if (value == null || typeof value != "object") return value;
12857
+ const v = record(value);
12858
+ if (v.kind == "node" && typeof v.nodeId == "string" && typeof v.output == "string") return {
12859
+ kind: "output",
12860
+ node: v.nodeId,
12861
+ port: v.output,
12862
+ ...v.field == null ? {} : { field: v.field }
12863
+ };
12864
+ if (v.kind == "binding" && typeof v.bindingId == "string") return {
12865
+ kind: "variable",
12866
+ name: content.document.bindings[v.bindingId]?.target ?? "[missing variable]"
12867
+ };
12868
+ if (v.kind == "value") return value;
12869
+ return Object.fromEntries(Object.entries(v).map(([k, item]) => [k, outwardSource(content, item)]));
12870
+ }
12871
+ function authoringEdges(edges) {
12872
+ return edges.map((edge) => edge.sourceHandle == null ? {
12873
+ source: edge.source,
12874
+ target: edge.target
12875
+ } : {
12876
+ source: edge.source,
12877
+ target: edge.target,
12878
+ branch: edge.sourceHandle
12879
+ });
12880
+ }
12881
+ function authoringNode(content, ref) {
12882
+ const node = nodeAt(content, ref), type = typeOf(node), task = taskAt(node);
12883
+ let config = {};
12884
+ const texts = {};
12885
+ if (task != null && "executor" in task) {
12886
+ const { kind: _, ...executor } = task.executor;
12887
+ config = { ...executor };
12888
+ if (task.executor.kind == "agent") {
12889
+ const { prompt, tools, notification, ...rest } = task.executor;
12890
+ const { kind: _agentKind, ...settings } = rest;
12891
+ config = {
12892
+ ...settings,
12893
+ inputs: fieldsView([...task.inputs, ...node.kind == "task" ? node.additionalInputs ?? [] : []]),
12894
+ resultSchema: task.outputs.find((port) => "handle" in port)?.jsonSchema ?? { type: "string" },
12895
+ tools: outwardAgentTools(tools)
12896
+ };
12897
+ texts.prompt = prompt;
12898
+ if (notification != null) {
12899
+ const { inputDefinitions: _definitions, ...noticeSettings } = notification;
12900
+ config.notification = noticeSettings;
12901
+ }
12902
+ } else if (task.executor.kind == "llm") config = {
12903
+ ...llmConfigurationView(task),
12904
+ inputs: fieldsView([...task.inputs, ...node.kind == "task" ? node.additionalInputs ?? [] : []].filter((port) => !("handle" in port) || !llmReservedInputs.includes(port.handle)))
12905
+ };
12906
+ else if (task.executor.kind == "openapi") config = { ...openApiConfigView(task.executor) };
12907
+ } else if (node.kind == "task" && "moduleId" in node.task) {
12908
+ config = {
12909
+ inputs: fieldsView([...node.task.inputs, ...node.additionalInputs ?? []]),
12910
+ outputs: fieldsView(node.task.outputs),
12911
+ ...node.task.capabilities == null ? {} : { capabilities: node.task.capabilities }
12912
+ };
12913
+ texts.code = content.modules[node.task.moduleId]?.source ?? "";
12914
+ } else switch (node.kind) {
12915
+ case "condition":
12916
+ config = { ...conditionConfigurationView(node, (value) => outwardSource(content, value)) };
12917
+ break;
12918
+ case "value":
12919
+ config = {
12920
+ values: Object.fromEntries(node.values.filter((port) => Object.hasOwn(port, "value")).map((port) => [port.handle, port.value])),
12921
+ outputs: fieldsView(node.values.map(({ value: _value, ...port }) => port))
12922
+ };
12923
+ break;
12924
+ case "wait":
12925
+ case "approval":
12926
+ config = { inputs: fieldsView(node.inputDefinitions) };
12927
+ texts.prompt = node.prompt;
12928
+ break;
12929
+ case "webhook":
12930
+ config = {
12931
+ body: fieldsView(node.bodyFields),
12932
+ method: node.method,
12933
+ ...node.options == null ? {} : { options: node.options }
12934
+ };
12935
+ break;
12936
+ case "cron":
12937
+ config = { schedule: node.cronTimes };
12938
+ break;
12939
+ case "error":
12940
+ config = node.sourceFlowIds == null ? {} : { sourceFlowIds: node.sourceFlowIds };
12941
+ break;
12942
+ case "poll":
12943
+ case "integration": config = {
12944
+ key: node.definition.key,
12945
+ ...node.connectionId == null ? {} : { connectionId: node.connectionId },
12946
+ ...node.kind == "poll" ? { schedule: node.pollTimes } : {}
12947
+ };
12948
+ }
12949
+ const edges = authoringEdges(content.document.graph.edges);
12950
+ return {
12951
+ ref,
12952
+ type,
12953
+ name: node.name ?? ref,
12954
+ readOnly: false,
12955
+ ...node.description == null ? {} : { description: node.description },
12956
+ ...node.icon == null ? {} : { icon: node.icon },
12957
+ ..."timeoutMs" in node && node.timeoutMs != null ? { timeoutMs: node.timeoutMs } : {},
12958
+ ..."maxExecutions" in node && node.maxExecutions != null ? { maxExecutions: node.maxExecutions } : {},
12959
+ config: json$2(config),
12960
+ texts: Object.fromEntries(Object.entries(texts).map(([field, text]) => [field, {
12961
+ lines: text.split("\n").length,
12962
+ characters: text.length
12963
+ }])),
12964
+ inputs: outwardSource(content, inputMappings(node)),
12965
+ inputPorts: fieldsView(Object.entries(inputDefinitions(node)).map(([handle, port]) => Object.assign({}, port, { handle }))),
12966
+ outputPorts: fieldsView(Object.entries(nodeOutputPorts(node)).map(([handle, port]) => Object.assign({}, port, { handle }))),
12967
+ ...task != null && "executor" in task && task.executor.kind == "openapi" ? { authenticationChoices: openApiAuthenticationChoices(task.executor) } : {},
12968
+ incoming: edges.filter((e) => e.target == ref),
12969
+ outgoing: edges.filter((e) => e.source == ref)
12970
+ };
12971
+ }
12972
+ function textAt(content, node, field) {
12973
+ if (field == "code" && node.kind == "task" && "moduleId" in node.task) return content.modules[node.task.moduleId]?.source ?? fail("text.missing", "Node source is missing.");
12974
+ const task = taskAt(node);
12975
+ if (field == "prompt" && task != null && "executor" in task && task.executor.kind == "agent") return task.executor.prompt;
12976
+ if (field == "prompt" && (node.kind == "wait" || node.kind == "approval")) return node.prompt;
12977
+ return fail("text.unsupported", `This node has no ${field} field.`);
12978
+ }
12979
+ function readAuthoring(content, query = {}) {
12980
+ const q = authoringReadSchema.parse(query);
12981
+ if (q.text != null) {
12982
+ const lines = textAt(content, nodeAt(content, q.text.node), q.text.field).split("\n");
12983
+ const selected = lines.slice(q.text.start - 1, q.text.start - 1 + q.text.lines);
12984
+ let count = 0, characters = 0;
12985
+ for (const line of selected) {
12986
+ if (characters + line.length + 1 > 24e3) break;
12987
+ characters += line.length + 1;
12988
+ count++;
12989
+ }
12990
+ if (count == 0 && selected.length > 0) fail("text.line-too-large", "Selected line exceeds 24000 characters; use search to locate a smaller edit.", {
12991
+ node: q.text.node,
12992
+ field: q.text.field
12993
+ });
12994
+ const end = q.text.start - 1 + count;
12995
+ return { text: {
12996
+ ...q.text,
12997
+ content: selected.slice(0, count).join("\n"),
12998
+ totalLines: lines.length,
12999
+ ...end < lines.length ? { nextStart: end + 1 } : {},
13000
+ truncated: end < lines.length
13001
+ } };
13002
+ }
13003
+ if (q.nodes != null) return { nodes: q.nodes.map((ref) => authoringNode(content, ref)) };
13004
+ return {
13005
+ nodes: Object.keys(content.document.graph.nodes).map((ref) => {
13006
+ const node = authoringNode(content, ref);
13007
+ return {
13008
+ ref,
13009
+ type: node.type,
13010
+ name: node.name,
13011
+ readOnly: node.readOnly,
13012
+ inputHandles: Object.keys(node.inputPorts),
13013
+ outputHandles: Object.keys(node.outputPorts),
13014
+ inputs: compactValue(node.inputs),
13015
+ texts: node.texts
13016
+ };
13017
+ }),
13018
+ edges: authoringEdges(content.document.graph.edges)
13019
+ };
13020
+ }
13021
+ function compactValue(value, depth = 0) {
13022
+ if (depth >= 4 && value != null && typeof value == "object") return { truncated: true };
13023
+ if (typeof value == "string") return value.length > 160 ? {
13024
+ preview: value.slice(0, 160),
13025
+ truncated: true
13026
+ } : value;
13027
+ if (Array.isArray(value)) return value.length > 8 ? {
13028
+ preview: value.slice(0, 8).map((v) => compactValue(v, depth + 1)),
13029
+ truncated: true
13030
+ } : value.map((v) => compactValue(v, depth + 1));
13031
+ if (value != null && typeof value == "object") return Object.fromEntries([...Object.entries(value).slice(0, 8).map(([key, v]) => [key, compactValue(v, depth + 1)]), ...Object.keys(value).length > 8 ? [["truncated", true]] : []]);
13032
+ return value;
13033
+ }
13034
+ function searchAuthoring(content, query) {
13035
+ const q = authoringSearchSchema.parse(query), needle = q.query.toLowerCase();
13036
+ const matches = [];
13037
+ for (const [ref, node] of Object.entries(content.document.graph.nodes)) {
13038
+ const view = authoringNode(content, ref);
13039
+ if (q.type != null && q.type != view.type) continue;
13040
+ const fields = {
13041
+ name: view.name,
13042
+ description: view.description ?? "",
13043
+ inputs: JSON.stringify(view.inputs),
13044
+ config: JSON.stringify(view.config),
13045
+ ...Object.fromEntries(Object.keys(view.texts).map((field) => [field, textAt(content, node, field)]))
13046
+ };
13047
+ for (const [field, value] of Object.entries(fields)) for (const [index, line] of value.split("\n").entries()) {
13048
+ const at = line.toLowerCase().indexOf(needle);
13049
+ if (at >= 0) matches.push({
13050
+ node: ref,
13051
+ field,
13052
+ line: index + 1,
13053
+ excerpt: line.slice(Math.max(0, at - 100), at + Math.max(needle.length, 100))
13054
+ });
13055
+ }
13056
+ }
13057
+ const end = q.offset + q.limit;
13058
+ return {
13059
+ matches: matches.slice(q.offset, end),
13060
+ total: matches.length,
13061
+ ...end < matches.length ? { nextOffset: end } : {}
13062
+ };
13063
+ }
13064
+ function merge(base, patch) {
13065
+ if (patch == null || typeof patch != "object" || Array.isArray(patch)) return patch;
13066
+ const result = { ...record(base) };
13067
+ for (const [key, value] of Object.entries(patch)) {
13068
+ if ([
13069
+ "__proto__",
13070
+ "constructor",
13071
+ "prototype"
13072
+ ].includes(key)) fail("edit.invalid-field", `Invalid field ${key}.`);
13073
+ Object.defineProperty(result, key, {
13074
+ value: merge(result[key], value),
13075
+ enumerable: true,
13076
+ writable: true,
13077
+ configurable: true
13078
+ });
13079
+ }
13080
+ return result;
13081
+ }
13082
+ function clearPath(value, path) {
13083
+ let current = value;
13084
+ for (const part of path.slice(0, -1)) {
13085
+ if (!Object.hasOwn(current, part) || Array.isArray(current[part]) || current[part] == null || typeof current[part] != "object") fail("edit.invalid-field", `Cannot clear ${path.join(".")}.`);
13086
+ current = record(current[part]);
13087
+ }
13088
+ const last = path.at(-1);
13089
+ if (!Object.hasOwn(current, last)) fail("edit.invalid-field", `Cannot clear absent field ${path.join(".")}.`);
13090
+ delete current[last];
13091
+ }
13092
+ async function compileAuthoring(base, request, host) {
13093
+ const parsed = authoringRequestSchema.parse(request);
13094
+ let content = base, index = 0, sequence = 0;
13095
+ const operations = [], aliases = {};
13096
+ const touchedModules = /* @__PURE__ */ new Set();
13097
+ function fresh(label) {
13098
+ return host.id(`${index}:${label}:${sequence++}`);
13099
+ }
13100
+ function apply(changes) {
13101
+ const checked = decodeChangeOperations(changes);
13102
+ content = applyFlowChanges(content, checked);
13103
+ operations.push(...checked);
13104
+ }
13105
+ function resolve(ref) {
13106
+ return ref.startsWith("$") ? (Object.hasOwn(aliases, ref.slice(1)) ? aliases[ref.slice(1)] : void 0) ?? fail("node.alias-missing", `Unknown alias ${ref}.`) : ref;
13107
+ }
13108
+ function source(value) {
13109
+ if (value.kind == "output") {
13110
+ const ref = resolve(value.node);
13111
+ const choices = Object.keys(nodeOutputPorts(nodeAt(content, ref)));
13112
+ const port = value.port ?? (choices.length == 1 ? choices[0] : void 0);
13113
+ if (port == null) fail("source.port-required", "Choose an output name; this node does not have exactly one output.", {
13114
+ node: ref,
13115
+ choices
13116
+ });
13117
+ return {
13118
+ kind: "node",
13119
+ nodeId: ref,
13120
+ output: port,
13121
+ ...value.field == null ? {} : { field: value.field }
13122
+ };
13123
+ }
13124
+ const existing = Object.entries(content.document.bindings).find(([, binding]) => binding.target == value.name);
13125
+ const bindingId = existing?.[0] ?? fresh("binding");
13126
+ if (existing == null) apply([{
13127
+ kind: "binding.create",
13128
+ bindingId,
13129
+ binding: {
13130
+ kind: "variable",
13131
+ target: value.name
13132
+ }
13133
+ }]);
13134
+ return {
13135
+ kind: "binding",
13136
+ bindingId
13137
+ };
13138
+ }
13139
+ function replace(ref, node) {
13140
+ const before = nodeAt(content, ref);
13141
+ if (!dequal(before, node)) apply([{
13142
+ kind: "graph.node.replace",
13143
+ nodeId: ref,
13144
+ before,
13145
+ node
13146
+ }]);
13147
+ }
13148
+ function taskNode(ref, task) {
13149
+ const node = nodeAt(content, ref);
13150
+ if (node.kind != "task" || !("executor" in node.task)) fail("node.invalid-type", "Expected a managed node.");
13151
+ replace(ref, {
13152
+ ...node,
13153
+ task
13154
+ });
13155
+ }
13156
+ async function connectorTask(config, name) {
13157
+ const action = await host.action(String(config.action));
13158
+ return {
13159
+ name,
13160
+ executor: {
13161
+ kind: "connector",
13162
+ action: action.actionId,
13163
+ ...config.connectionId == null ? {} : { connectionId: String(config.connectionId) }
13164
+ },
13165
+ inputs: Object.entries(action.inputs).map(([handle, port]) => Object.assign({ handle }, port)),
13166
+ outputs: Object.entries(action.outputs).map(([handle, port]) => Object.assign({ handle }, port))
13167
+ };
13168
+ }
13169
+ async function configure(ref, patch = {}, clear = []) {
13170
+ const node = nodeAt(content, ref), view = authoringNode(content, ref), type = view.type;
13171
+ const update = record(merge({
13172
+ name: view.name,
13173
+ ...view.description == null ? {} : { description: view.description },
13174
+ ...view.icon == null ? {} : { icon: view.icon },
13175
+ ...view.timeoutMs == null ? {} : { timeoutMs: view.timeoutMs },
13176
+ ...view.maxExecutions == null ? {} : { maxExecutions: view.maxExecutions },
13177
+ config: view.config
13178
+ }, patch));
13179
+ const explicit = (key) => Object.hasOwn(record(patch.config), key) || clear.some((path) => path[0] == "config" && path[1] == key);
13180
+ if (type == "openapi" && Object.hasOwn(record(patch.config), "authentication")) record(update.config).authentication = record(patch.config).authentication;
13181
+ for (const path of clear) clearPath(update, path);
13182
+ if (typeof update.name != "string") fail("node.name-required", "Node name cannot be cleared.");
13183
+ const config = authoringConfigurations[type].parse(update.config);
13184
+ const { config: _, ...metadata } = update;
13185
+ const { name: _name, description: _description, icon: _icon, ...rest } = node;
13186
+ let next = {
13187
+ ...rest,
13188
+ ...metadata
13189
+ };
13190
+ if ("inputs" in node) {
13191
+ const clean = { ...next };
13192
+ if (!Object.hasOwn(update, "timeoutMs")) delete clean.timeoutMs;
13193
+ if (!Object.hasOwn(update, "maxExecutions")) delete clean.maxExecutions;
13194
+ next = clean;
13195
+ } else if (update.timeoutMs != null || update.maxExecutions != null) fail("node.invalid-field", "Trigger nodes do not have execution limits.");
13196
+ function taskInputs(task, reserved = []) {
13197
+ if (node.kind != "task") throw new Error("Expected a task.");
13198
+ const fields = record(config.inputs);
13199
+ for (const key of reserved) if (Object.hasOwn(fields, key)) fail("input.reserved", `Configure ${key} through config.${key} or input.set.`, {
13200
+ node: ref,
13201
+ input: key
13202
+ });
13203
+ const extraNames = new Set(node.additionalInputs?.map((port) => port.handle) ?? []);
13204
+ const main = Object.fromEntries(Object.entries(fields).filter(([key]) => !extraNames.has(key)));
13205
+ for (const port of task.inputs) if ("handle" in port && (reserved.includes(port.handle) || extraNames.has(port.handle) && Object.hasOwn(fields, port.handle))) main[port.handle] = fieldsView([port])[port.handle];
13206
+ if (node.additionalInputs != null) {
13207
+ const extra = Object.fromEntries(Object.entries(fields).filter(([key]) => extraNames.has(key)));
13208
+ for (const port of node.additionalInputs) if (reserved.includes(port.handle)) extra[port.handle] = fieldsView([port])[port.handle];
13209
+ next = {
13210
+ ...next,
13211
+ additionalInputs: fieldsToPorts(extra, node.additionalInputs)
13212
+ };
13213
+ }
13214
+ return fieldsToPorts(main, task.inputs);
13215
+ }
13216
+ if (node.kind == "task" && "moduleId" in node.task) {
13217
+ const inputs = taskInputs(node.task);
13218
+ next = {
13219
+ ...next,
13220
+ task: {
13221
+ moduleId: node.task.moduleId,
13222
+ name: String(update.name),
13223
+ ...config,
13224
+ inputs,
13225
+ outputs: fieldsToPorts(config.outputs, node.task.outputs)
13226
+ }
13227
+ };
13228
+ } else if (node.kind == "task" && "executor" in node.task) {
13229
+ const before = node.task;
13230
+ let task;
13231
+ if (type == "connector") task = config.action == (before.executor.kind == "connector" ? before.executor.action : "") ? {
13232
+ ...before,
13233
+ name: String(update.name),
13234
+ executor: {
13235
+ kind: "connector",
13236
+ ...config
13237
+ }
13238
+ } : await connectorTask(config, String(update.name));
13239
+ else if (type == "decision") task = decisionTask(config.questions, String(update.name));
13240
+ else if (type == "openapi") task = await prepareOpenApiTask(config, before, (url) => host.openapi(url), String(update.name), {
13241
+ authentication: explicit("authentication"),
13242
+ serverUrl: explicit("serverUrl")
13243
+ });
13244
+ else if (type == "llm") {
13245
+ task = prepareLlmConfiguration(config, before, String(update.name));
13246
+ task = {
13247
+ ...task,
13248
+ inputs: taskInputs(task, llmReservedInputs)
13249
+ };
13250
+ } else {
13251
+ const { inputs: _inputs, resultSchema, notification, tools, ...executor } = config;
13252
+ const prepared = {
13253
+ ...executor,
13254
+ kind: type,
13255
+ ...before.executor.kind == "agent" ? { prompt: before.executor.prompt } : {}
13256
+ };
13257
+ if (type == "agent") {
13258
+ const previous = before.executor.kind == "agent" ? before.executor : void 0;
13259
+ Object.assign(prepared, { tools: await prepareAgentTools(tools, previous?.tools ?? [], (id) => host.action(id), () => fresh("tool")) });
13260
+ Reflect.deleteProperty(prepared, "notification");
13261
+ if (notification != null) {
13262
+ if (dequal(record(view.config).notification, notification) && previous?.notification != null) Object.assign(prepared, { notification: previous.notification });
13263
+ else {
13264
+ const settings = record(notification);
13265
+ const definition = await connectorTask(settings, `${update.name} notification`);
13266
+ Object.assign(prepared, { notification: {
13267
+ action: settings.action,
13268
+ ...settings.connectionId == null ? {} : { connectionId: settings.connectionId },
13269
+ inputDefinitions: definition.inputs,
13270
+ messageHandle: settings.messageHandle,
13271
+ inputs: settings.inputs
13272
+ } });
13273
+ }
13274
+ }
13275
+ }
13276
+ const outputs = dequal(record(view.config).resultSchema, resultSchema) ? before.outputs : before.outputs.map((port) => "handle" in port ? {
13277
+ ...port,
13278
+ jsonSchema: resultSchema
13279
+ } : port);
13280
+ task = {
13281
+ name: String(update.name),
13282
+ inputs: type == "agent" ? taskInputs(before) : before.inputs,
13283
+ outputs,
13284
+ executor: prepared
13285
+ };
13286
+ }
13287
+ next = {
13288
+ ...next,
13289
+ task
13290
+ };
13291
+ } else switch (node.kind) {
13292
+ case "condition":
13293
+ next = {
13294
+ ...next,
13295
+ ...prepareConditionConfiguration(config, source)
13296
+ };
13297
+ break;
13298
+ case "value": {
13299
+ const fields = { ...record(config.outputs) };
13300
+ for (const key of Object.keys(record(config.values))) if (!Object.hasOwn(fields, key)) fields[key] = {};
13301
+ const values = fieldsToPorts(fields, node.values.map(({ value: _value, ...port }) => port)).filter((port) => "handle" in port).map((port) => Object.assign({}, port, Object.hasOwn(record(config.values), port.handle) ? { value: record(config.values)[port.handle] } : {}));
13302
+ next = {
13303
+ ...next,
13304
+ values
13305
+ };
13306
+ break;
13307
+ }
13308
+ case "wait":
13309
+ case "approval":
13310
+ next = {
13311
+ ...next,
13312
+ inputDefinitions: fieldsToPorts(config.inputs, node.inputDefinitions)
13313
+ };
13314
+ break;
13315
+ case "webhook": {
13316
+ const { body, ...settings } = config;
13317
+ const { options: _options, ...withoutOptions } = next;
13318
+ next = {
13319
+ ...withoutOptions,
13320
+ ...settings,
13321
+ bodyFields: fieldsToPorts(body, node.bodyFields)
13322
+ };
13323
+ break;
13324
+ }
13325
+ case "cron":
13326
+ next = {
13327
+ ...next,
13328
+ cronTimes: config.schedule
13329
+ };
13330
+ break;
13331
+ case "poll":
13332
+ case "integration": {
13333
+ if (config.key != node.definition.key) fail("trigger.key-immutable", "Create a new node to change its Trigger type.");
13334
+ const { connectionId: _connection, ...withoutConnection } = next;
13335
+ next = {
13336
+ ...withoutConnection,
13337
+ ...config.connectionId == null ? {} : { connectionId: config.connectionId },
13338
+ ...node.kind == "poll" ? { pollTimes: config.schedule } : {}
13339
+ };
13340
+ break;
13341
+ }
13342
+ default: {
13343
+ const fields = { ...next };
13344
+ for (const key of Object.keys(record(view.config))) delete fields[key];
13345
+ next = {
13346
+ ...fields,
13347
+ ...config
13348
+ };
13349
+ }
13350
+ }
13351
+ replace(ref, next);
13352
+ }
13353
+ async function setText(ref, field, text) {
13354
+ const node = nodeAt(content, ref), before = textAt(content, node, field);
13355
+ if (before == text) return;
13356
+ if (field == "code" && node.kind == "task" && "moduleId" in node.task) {
13357
+ const moduleId = node.task.moduleId, module = content.modules[moduleId];
13358
+ const shared = Object.values(content.document.graph.nodes).some((n) => n.kind == "task" && "moduleId" in n.task && n.task.moduleId == moduleId && n !== node) || Object.values(content.modules).some((m) => m.imports.includes(moduleId));
13359
+ const imports$1 = await imports(text);
13360
+ if (shared) {
13361
+ const id = fresh("module");
13362
+ apply([{
13363
+ kind: "module.create",
13364
+ moduleId: id,
13365
+ module: {
13366
+ ...module,
13367
+ source: text,
13368
+ imports: imports$1
13369
+ }
13370
+ }]);
13371
+ replace(ref, {
13372
+ ...node,
13373
+ task: {
13374
+ ...node.task,
13375
+ moduleId: id
13376
+ }
13377
+ });
13378
+ } else apply([{
13379
+ kind: "module.source.replace",
13380
+ moduleId,
13381
+ beforeSource: before,
13382
+ beforeImports: module.imports,
13383
+ source: text,
13384
+ imports: imports$1
13385
+ }]);
13386
+ } else if (node.kind == "task" && "executor" in node.task) {
13387
+ const task = node.task;
13388
+ taskNode(ref, {
13389
+ ...task,
13390
+ executor: {
13391
+ ...task.executor,
13392
+ prompt: text
13393
+ }
13394
+ });
13395
+ } else if (node.kind == "wait" || node.kind == "approval") replace(ref, {
13396
+ ...node,
13397
+ prompt: text
13398
+ });
13399
+ }
13400
+ async function setInput(ref, input, value) {
13401
+ const node = nodeAt(content, ref);
13402
+ if (node.kind == "condition") fail("input.unsupported", "Edit the branch condition operands through config.branches.", {
13403
+ node: ref,
13404
+ field: "config.branches"
13405
+ });
13406
+ if (node.kind == "poll" || node.kind == "integration") {
13407
+ if (!Object.hasOwn(inputDefinitions(node), input)) fail("input.not-found", `Unknown input ${input}.`, {
13408
+ node: ref,
13409
+ input,
13410
+ choices: Object.keys(inputDefinitions(node))
13411
+ });
13412
+ if (value.kind != "value" && value.kind != "unset" && value.kind != "default") fail("input.source-unsupported", "Trigger parameters accept only value, unset or default; they cannot depend on execution outputs or variables.", {
13413
+ node: ref,
13414
+ input,
13415
+ allowed: [
13416
+ "value",
13417
+ "unset",
13418
+ "default"
13419
+ ]
13420
+ });
13421
+ const config = { ...node.config };
13422
+ if (value.kind == "default") delete config[input];
13423
+ else config[input] = value;
13424
+ replace(ref, {
13425
+ ...node,
13426
+ config
13427
+ });
13428
+ return;
13429
+ }
13430
+ if (!Object.hasOwn(inputDefinitions(node), input)) {
13431
+ const type = typeOf(node);
13432
+ if (![
13433
+ "agent",
13434
+ "code",
13435
+ "llm",
13436
+ "wait",
13437
+ "approval"
13438
+ ].includes(type)) fail("input.not-found", `Unknown input ${input}.`, {
13439
+ node: ref,
13440
+ input,
13441
+ choices: Object.keys(inputDefinitions(node))
13442
+ });
13443
+ if (type == "llm" && llmReservedInputs.includes(input)) fail("input.not-found", `Missing built-in LLM input ${input}.`, {
13444
+ node: ref,
13445
+ input,
13446
+ choices: Object.keys(inputDefinitions(node))
13447
+ });
13448
+ await configure(ref, { config: { inputs: { [input]: {} } } });
13449
+ }
13450
+ const mapping = value.kind == "default" ? void 0 : value.kind == "value" || value.kind == "unset" ? value : {
13451
+ kind: "sources",
13452
+ sources: (value.kind == "sources" ? value.sources : [value]).map(source)
13453
+ };
13454
+ const before = nodeInputMappings(nodeAt(content, ref))[input];
13455
+ if (!dequal(before, mapping)) apply([{
13456
+ kind: "graph.node.input.set",
13457
+ nodeId: ref,
13458
+ handle: input,
13459
+ before,
13460
+ ...mapping == null ? {} : { value: mapping }
13461
+ }]);
13462
+ }
13463
+ for (const edit of parsed.edits) {
13464
+ try {
13465
+ switch (edit.op) {
13466
+ case "node.add": {
13467
+ if (Object.hasOwn(aliases, edit.as)) fail("node.alias-duplicate", `Duplicate alias ${edit.as}.`);
13468
+ const nodeId = host.id(`node:${edit.as}`), identity = {
13469
+ nodeId,
13470
+ moduleId: fresh("module")
13471
+ }, name = edit.name;
13472
+ aliases[edit.as] = nodeId;
13473
+ const config = edit.config ?? {};
13474
+ let changes;
13475
+ switch (edit.type) {
13476
+ case "code":
13477
+ changes = createCodeTask(identity, name, void 0, {
13478
+ inputs: [],
13479
+ outputs: config.outputs == null ? defaultCodeTaskPorts.outputs : []
13480
+ });
13481
+ break;
13482
+ case "agent":
13483
+ changes = createAgentTask(identity, name, {
13484
+ inputs: [],
13485
+ prompt: edit.prompt ?? ""
13486
+ });
13487
+ break;
13488
+ case "llm":
13489
+ changes = createLlmTask(identity, name, "chat", "Generated response.").map((change) => change.kind == "graph.node.create" && change.node.kind == "task" && "executor" in change.node.task ? Object.assign({}, change, { node: Object.assign({}, change.node, { task: initialAuthoringLlmTask(change.node.task) }) }) : change);
13490
+ break;
13491
+ case "decision":
13492
+ changes = createDecisionTask(identity, name);
13493
+ break;
13494
+ case "connector":
13495
+ changes = createManagedTask(identity, await connectorTask(config, name));
13496
+ break;
13497
+ case "openapi":
13498
+ changes = createManagedTask(identity, await prepareOpenApiTask(authoringConfigurations.openapi.parse(config), void 0, (url) => host.openapi(url), name));
13499
+ break;
13500
+ case "condition":
13501
+ changes = createCondition(nodeId, name);
13502
+ break;
13503
+ case "value":
13504
+ changes = createValue(nodeId, name, []);
13505
+ break;
13506
+ case "wait":
13507
+ changes = createWait(nodeId, name);
13508
+ break;
13509
+ case "approval":
13510
+ changes = createApproval(nodeId, name);
13511
+ break;
13512
+ case "poll":
13513
+ case "integration": {
13514
+ const definition = host.trigger(String(config.key));
13515
+ if (definition.type != edit.type) fail("trigger.type-mismatch", "Trigger key has a different type.");
13516
+ changes = createProviderTrigger(nodeId, definition, {
13517
+ name,
13518
+ config: {}
13519
+ });
13520
+ break;
13521
+ }
13522
+ default: changes = [{
13523
+ kind: "graph.node.create",
13524
+ nodeId,
13525
+ node: {
13526
+ kind: edit.type,
13527
+ name,
13528
+ ...edit.type == "cron" ? { cronTimes: [{
13529
+ type: "every",
13530
+ unit: "hour",
13531
+ value: 1
13532
+ }] } : {},
13533
+ ...edit.type == "webhook" ? {
13534
+ method: "POST",
13535
+ bodyFields: []
13536
+ } : {}
13537
+ }
13538
+ }];
13539
+ }
13540
+ apply(changes);
13541
+ await configure(nodeId, { config });
13542
+ const added = nodeAt(content, nodeId);
13543
+ if (added.kind == "task") replace(nodeId, {
13544
+ ...added,
13545
+ inputs: {}
13546
+ });
13547
+ if (edit.code != null) await setText(nodeId, "code", edit.code);
13548
+ if (edit.prompt != null) await setText(nodeId, "prompt", edit.prompt);
13549
+ for (const [input, binding] of Object.entries(edit.inputs ?? {})) await setInput(nodeId, input, binding);
13550
+ break;
13551
+ }
13552
+ case "node.update":
13553
+ await configure(resolve(edit.node), edit.set, edit.clear);
13554
+ break;
13555
+ case "node.remove": {
13556
+ const ref = resolve(edit.node), node = nodeAt(content, ref);
13557
+ if (node.kind == "task" && "moduleId" in node.task) touchedModules.add(node.task.moduleId);
13558
+ apply([{
13559
+ kind: "graph.node.delete",
13560
+ nodeId: ref
13561
+ }]);
13562
+ break;
13563
+ }
13564
+ case "input.set":
13565
+ await setInput(resolve(edit.node), edit.input, edit.source);
13566
+ break;
13567
+ case "edge.connect":
13568
+ case "edge.disconnect": {
13569
+ const from = resolve(edit.source), to = resolve(edit.target);
13570
+ nodeAt(content, from);
13571
+ nodeAt(content, to);
13572
+ const edge = {
13573
+ source: from,
13574
+ target: to,
13575
+ ...edit.branch == null ? {} : { sourceHandle: edit.branch }
13576
+ };
13577
+ const exists = content.document.graph.edges.some((e) => dequal(e, edge));
13578
+ if (edit.op == "edge.connect" != exists) apply([{
13579
+ kind: edit.op == "edge.connect" ? "graph.edge.connect" : "graph.edge.disconnect",
13580
+ edge
13581
+ }]);
13582
+ break;
13583
+ }
13584
+ case "text.set":
13585
+ await setText(resolve(edit.node), edit.field, edit.text);
13586
+ break;
13587
+ case "text.edit": {
13588
+ const ref = resolve(edit.node), value = textAt(content, nodeAt(content, ref), edit.field), count = value.split(edit.oldText).length - 1;
13589
+ if (count != 1) fail("text.match-count", `Expected one exact match, found ${count}. Read the field and include more context.`, {
13590
+ node: ref,
13591
+ field: edit.field,
13592
+ matches: count
13593
+ });
13594
+ await setText(ref, edit.field, value.replace(edit.oldText, () => edit.newText));
13595
+ break;
13596
+ }
13597
+ }
13598
+ } catch (error) {
13599
+ if (error instanceof AuthoringError || error instanceof AuthoringToolInputError || error instanceof AuthoringOpenApiAuthenticationError) throw new AuthoringError(error.code, error.message, {
13600
+ ...error.details,
13601
+ editIndex: index
13602
+ });
13603
+ throw new AuthoringError("edit.invalid", error instanceof Error ? error.message : String(error), { editIndex: index });
13604
+ }
13605
+ index++;
13606
+ }
13607
+ for (const moduleId of touchedModules) if (!Object.values(content.document.graph.nodes).some((n) => n.kind == "task" && "moduleId" in n.task && n.task.moduleId == moduleId) && !Object.values(content.modules).some((m) => m.imports.includes(moduleId))) apply([{
13608
+ kind: "module.delete",
13609
+ moduleId
13610
+ }]);
13611
+ const cleaned = cleanVariableBindings(base, operations);
13612
+ return {
13613
+ operations: cleaned,
13614
+ content: cleaned.length == 0 ? base : applyFlowChanges(base, cleaned),
13615
+ nodes: aliases
13616
+ };
13617
+ }
13618
+ var escapePointer = (value) => value.replaceAll("~", "~0").replaceAll("/", "~1");
13619
+ function authoringDiagnostics(content, diagnostics) {
13620
+ const nodes = Object.entries(content.document.graph.nodes);
13621
+ return diagnostics.map((diagnostic) => {
13622
+ const affected = nodes.filter(([id, node]) => {
13623
+ const roots = [`/document/graph/nodes/${escapePointer(id)}`];
13624
+ if (node.kind == "task" && "moduleId" in node.task) roots.push(`/modules/${escapePointer(node.task.moduleId)}`);
13625
+ return roots.some((root) => diagnostic.path == root || diagnostic.path.startsWith(`${root}/`));
13626
+ });
13627
+ const message = diagnostic.message.replace(/(CodeModule|Managed Task|Task|Binding) "([^"\n]+)"/g, (_, kind, id) => {
13628
+ if (kind == "Binding") return `Variable "${content.document.bindings[id]?.target ?? "unresolved"}"`;
13629
+ const owners = nodes.filter(([, n]) => n.kind == "task" && kind == "CodeModule" && "moduleId" in n.task && n.task.moduleId == id);
13630
+ return owners.length ? `${kind == "CodeModule" ? "Code for" : "Node"} ${owners.map(([ref, n]) => JSON.stringify(n.name ?? ref)).join(", ")}` : kind == "CodeModule" ? "Referenced code" : "Node configuration";
13631
+ }).replaceAll("CodeModule", "Code");
13632
+ const parts = diagnostic.path.split("/").map((part) => part.replaceAll("~1", "/").replaceAll("~0", "~"));
13633
+ return {
13634
+ code: diagnostic.code,
13635
+ message,
13636
+ nodes: affected.map(([id]) => id),
13637
+ field: affected[0] == null ? "config" : authoringDiagnosticField(content, affected[0][1], parts),
13638
+ ...diagnostic.line ? {
13639
+ line: diagnostic.line,
13640
+ column: diagnostic.column
13641
+ } : {}
13642
+ };
13643
+ });
13644
+ }
13645
+ //#endregion
13646
+ //#region src/execution/common/wait.ts
13647
+ /** Shared by decision entry points, the editor, and durable decision storage. */
13648
+ var waitCommentSchema = string().trim().refine((value) => [...value].length <= 2e3, "Wait comment must contain at most 2,000 Unicode code points.").nullable().optional();
13649
+ //#endregion
13650
+ //#region src/control/common/draftOperations.ts
13651
+ var text = string().min(1);
13652
+ var json$1 = json$5();
13653
+ var triggerCreate = strictObject({
13654
+ kind: literal("graph.trigger.create"),
13655
+ nodeId: text,
13656
+ key: text,
13657
+ connectionId: text.optional(),
13658
+ name: text.optional(),
13659
+ config: record$3(text, json$1),
13660
+ schedule: triggerScheduleSchema.readonly().optional()
13661
+ });
13662
+ function decodeDraftOperations(value) {
13663
+ checkJsonDepth(value);
13664
+ return array(unknown()).min(1).parse(value).map((candidate, index) => {
13665
+ const { kind } = parseOperation(candidate, index, object$1({ kind: text }).parse);
13666
+ return kind == "graph.trigger.create" ? parseOperation(candidate, index, triggerCreate.parse) : decodeChangeOperation(candidate, index);
13667
+ });
13668
+ }
13669
+ function draftOperationsSchema(kind) {
13670
+ if (kind != null && kind != "graph.trigger.create") return changeOperationsSchema(kind);
13671
+ const trigger = toJSONSchema(triggerCreate);
13672
+ if (kind == "graph.trigger.create") return trigger;
13673
+ const schema = changeOperationsSchema();
13674
+ return {
13675
+ ...schema,
13676
+ items: { anyOf: [schema.items, trigger] }
13677
+ };
13678
+ }
13679
+ function resolveDraftOperations(operations, definition) {
13680
+ return operations.flatMap((operation) => {
13681
+ if (operation.kind != "graph.trigger.create") return [operation];
13682
+ const snapshot = definition(operation.key);
13683
+ if (snapshot.type != "poll" && operation.schedule != null) throw new Error("Only Poll triggers accept a schedule.");
13684
+ return createProviderTrigger(operation.nodeId, snapshot, operation);
13685
+ });
13686
+ }
13687
+ //#endregion
13688
+ //#region src/control/common/eventSourceSchemas.ts
13689
+ var id$1 = string().min(1).max(256);
13690
+ var eventType = string().regex(/^[a-z][a-z0-9_.]{0,127}$/);
13691
+ var name = string().trim().min(1).max(128);
13692
+ var secret = string().min(1).max(256);
13693
+ var createEventSourceSchema = strictObject({
13694
+ version: literal(1),
13695
+ name,
13696
+ connectionId: id$1,
13697
+ teamId: id$1.nullable(),
13698
+ verificationToken: secret,
13699
+ encryptKey: secret,
13700
+ eventTypes: array(eventType).min(1).max(200).refine((values) => new Set(values).size == values.length),
13701
+ manageSubscriptions: boolean()
13702
+ });
13703
+ var updateEventSourceSchema = strictObject({
13704
+ version: literal(1),
13705
+ expectedRevision: int().positive(),
13706
+ name,
13707
+ enabled: boolean(),
13708
+ eventTypes: array(eventType).min(1).max(200).refine((values) => new Set(values).size == values.length),
13709
+ verificationToken: secret.optional(),
13710
+ encryptKey: secret.optional()
13711
+ });
13712
+ var eventSourceRevisionSchema = strictObject({
13713
+ version: literal(1),
13714
+ expectedRevision: int().positive()
13715
+ });
13716
+ //#endregion
10951
13717
  //#region src/control/common/authoringExamples.ts
10952
13718
  var descriptions = {
10953
13719
  "manual": "A Manual start node.",
@@ -11212,16 +13978,21 @@ function authoringExample(name) {
11212
13978
  //#endregion
11213
13979
  //#region src/control/common/requests.ts
11214
13980
  var waitActionBodySchema = strictObject({ comment: waitCommentSchema });
11215
- var json = json$3();
13981
+ var json = json$5();
11216
13982
  var id = string().min(1);
11217
13983
  var version = literal(1);
11218
13984
  var flowName = id.refine((value) => value == value.trim() && resourceNameIssue(value) == null, "Flow name is invalid.");
11219
- var inputs = record$1(string(), record$1(string(), json));
13985
+ var inputs = record$3(string(), record$3(string(), json));
11220
13986
  var trigger = strictObject({
11221
13987
  nodeId: id,
11222
- outputs: record$1(string(), json)
13988
+ outputs: record$3(string(), json)
11223
13989
  });
11224
13990
  var schemas = {
13991
+ authoringCheck: authoringCheckSchema,
13992
+ authoringEdit: authoringRequestSchema,
13993
+ authoringRead: authoringReadSchema,
13994
+ authoringSearch: authoringSearchSchema,
13995
+ authoringSchema: authoringSchemaQuery,
11225
13996
  loadOpenApiDocument: strictObject({
11226
13997
  url: string().min(1).max(8192),
11227
13998
  version
@@ -11254,7 +14025,7 @@ var schemas = {
11254
14025
  }),
11255
14026
  updatePresentation: strictObject({
11256
14027
  expectedRevision: int().positive(),
11257
- value: record$1(string(), json),
14028
+ value: record$3(string(), json),
11258
14029
  version
11259
14030
  }),
11260
14031
  checkFlow: strictObject({
@@ -11322,6 +14093,11 @@ function decoder(schema) {
11322
14093
  return (value) => schema.parse(value);
11323
14094
  }
11324
14095
  var controlRequests = {
14096
+ authoringCheck: decoder(schemas.authoringCheck),
14097
+ authoringEdit: decoder(schemas.authoringEdit),
14098
+ authoringRead: decoder(schemas.authoringRead),
14099
+ authoringSearch: decoder(schemas.authoringSearch),
14100
+ authoringSchema: decoder(schemas.authoringSchema),
11325
14101
  loadOpenApiDocument: decoder(schemas.loadOpenApiDocument),
11326
14102
  createEventSource: decoder(schemas.createEventSource),
11327
14103
  updateEventSource: decoder(schemas.updateEventSource),
@@ -11353,7 +14129,7 @@ var controlRequests = {
11353
14129
  versionOnly: decoder(schemas.versionOnly)
11354
14130
  };
11355
14131
  function controlRequestSchema(name) {
11356
- const schema = toJSONSchema(schemas[name]);
14132
+ const schema = toJSONSchema(schemas[name], { io: "input" });
11357
14133
  if (name == "changeDraft") return {
11358
14134
  ...schema,
11359
14135
  properties: {
@@ -11364,4 +14140,4 @@ function controlRequestSchema(name) {
11364
14140
  return schema;
11365
14141
  }
11366
14142
  //#endregion
11367
- export { authoringExample, authoringExamples, controlRequestSchema, controlRequests, decodeDraftOperations, draftOperationsSchema, resolveDraftOperations, waitActionBodySchema };
14143
+ export { AuthoringError, authoringCheckResponse, authoringCheckSchema, authoringConfigurations, authoringDiagnosticSchema, authoringDiagnostics, authoringEditResponse, authoringEditSchema, authoringExample, authoringExamples, authoringNode, authoringReadResponse, authoringReadSchema, authoringRequestContract, authoringRequestSchema, authoringSchema, authoringSchemaQuery, authoringSearchResponse, authoringSearchSchema, authoringSourceSchema, authoringTypes, compileAuthoring, controlRequestSchema, controlRequests, decodeDraftOperations, draftOperationsSchema, readAuthoring, resolveDraftOperations, searchAuthoring, waitActionBodySchema };