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

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 (43) hide show
  1. package/README.md +1 -1
  2. package/dist/browser/{createResourceDialog-4H5_lZ6s.js → createResourceDialog-Btjes3wD.js} +2 -2
  3. package/dist/browser/flow-authoring-edge.d.ts +3 -3
  4. package/dist/browser/flow-authoring-node.d.ts +26 -46
  5. package/dist/browser/flow-authoring.js +9155 -21002
  6. package/dist/browser/flow-change-schema.d.ts +1 -1
  7. package/dist/browser/flow-change.d.ts +14 -104
  8. package/dist/browser/flow-change.js +121 -296
  9. package/dist/browser/{flowChanges-ZzG-f9cg.js → flowChanges-BxutPLYO.js} +1494 -1830
  10. package/dist/browser/{flowWorkspace-ChpRaTMX.js → flowWorkspace-Dg4mqfa6.js} +118 -293
  11. package/dist/browser/{icons-CdAB9wyS.js → icons-p2A9zs8t.js} +126 -317
  12. package/dist/browser/lib-DrKav3HG.js +11403 -0
  13. package/dist/browser/preview.css +1 -1
  14. package/dist/browser/preview.js +9308 -9565
  15. package/dist/browser/ui-idTooltip.d.ts +11 -0
  16. package/dist/browser/ui.d.ts +5 -0
  17. package/dist/browser/ui.js +83 -1
  18. package/dist/browser/workbench.css +1 -1
  19. package/dist/browser/workbench.js +210 -411
  20. package/dist/browser/{workbenchSelect-BRZN4ish.js → workbenchSelect-LRp_Xjeq.js} +1 -1
  21. package/dist/common/control-api-conformance.js +212 -245
  22. package/dist/common/control-api.d.ts +6 -6
  23. package/dist/common/control-api.js +216 -250
  24. package/dist/common/control-requests.js +468 -1476
  25. package/dist/common/decision.js +6325 -6369
  26. package/dist/common/flow-agent.d.ts +1 -1
  27. package/dist/common/flow-connectionUsage.d.ts +1 -2
  28. package/dist/common/flow-encoding.d.ts +2 -4
  29. package/dist/common/flow-encoding.js +119 -180
  30. package/dist/common/flow-graph.d.ts +10 -10
  31. package/dist/common/flow-semantics.d.ts +4 -9
  32. package/dist/common/flow-semantics.js +9024 -9230
  33. package/dist/common/flowInspection.d.ts +3 -21
  34. package/dist/common/integration-trigger.js +8642 -8686
  35. package/dist/common/mcp.d.ts +0 -1
  36. package/dist/common/mcp.js +117 -140
  37. package/dist/common/openapi.js +6325 -6369
  38. package/dist/common/poll-trigger.js +8642 -8686
  39. package/dist/common/run-events.js +0 -1
  40. package/dist/common/scheduler.d.ts +3 -9
  41. package/dist/common/scheduler.js +116 -207
  42. package/dist/common/webhook-trigger.js +6325 -6369
  43. package/package.json +1 -1
@@ -83,7 +83,6 @@ export declare const mcpTools: {
83
83
  flowId: string;
84
84
  revisionId: string;
85
85
  nodeId: string;
86
- subflowId?: string | undefined;
87
86
  };
88
87
  } | {
89
88
  issues: {
@@ -2780,6 +2780,9 @@ function handlePipeResult(left, next, ctx) {
2780
2780
  issues: left.issues
2781
2781
  }, ctx);
2782
2782
  }
2783
+ var $ZodPreprocess = /*@__PURE__*/ $constructor("$ZodPreprocess", (inst, def) => {
2784
+ $ZodPipe.init(inst, def);
2785
+ });
2783
2786
  var $ZodReadonly = /*@__PURE__*/ $constructor("$ZodReadonly", (inst, def) => {
2784
2787
  $ZodType.init(inst, def);
2785
2788
  defineLazyInternal(inst, "propValues", (zod) => zod.def.innerType._zod.propValues);
@@ -5580,7 +5583,7 @@ var ZodRecord = /*@__PURE__*/ $constructor("ZodRecord", (inst, def) => {
5580
5583
  inst.keyType = def.keyType;
5581
5584
  inst.valueType = def.valueType;
5582
5585
  });
5583
- function record$1(keyType, valueType, params) {
5586
+ function record$2(keyType, valueType, params) {
5584
5587
  if (!valueType || !valueType._zod) return new ZodRecord({
5585
5588
  type: "record",
5586
5589
  keyType: string$1(),
@@ -5789,6 +5792,10 @@ function pipe(in_, out) {
5789
5792
  out
5790
5793
  });
5791
5794
  }
5795
+ var ZodPreprocess = /*@__PURE__*/ $constructor("ZodPreprocess", (inst, def) => {
5796
+ ZodPipe.init(inst, def);
5797
+ $ZodPreprocess.init(inst, def);
5798
+ });
5792
5799
  var ZodReadonly = /*@__PURE__*/ $constructor("ZodReadonly", (inst, def) => {
5793
5800
  $ZodReadonly.init(inst, def);
5794
5801
  ZodType.init(inst, def);
@@ -5832,11 +5839,18 @@ function json$3(params) {
5832
5839
  boolean(),
5833
5840
  _null(),
5834
5841
  array(jsonSchema),
5835
- record$1(string$1(), jsonSchema)
5842
+ record$2(string$1(), jsonSchema)
5836
5843
  ]);
5837
5844
  });
5838
5845
  return jsonSchema;
5839
5846
  }
5847
+ function preprocess(fn, schema) {
5848
+ return new ZodPreprocess({
5849
+ type: "pipe",
5850
+ in: transform(fn),
5851
+ out: schema
5852
+ });
5853
+ }
5840
5854
  //#endregion
5841
5855
  //#region ../../node_modules/.bun/dequal@2.0.3/node_modules/dequal/lite/index.mjs
5842
5856
  var has = Object.prototype.hasOwnProperty;
@@ -5881,9 +5895,9 @@ var waitCommentSchema = string$1().trim().refine((value) => [...value].length <=
5881
5895
  //#region src/openapi/common/authBindings.ts
5882
5896
  /** Never allow credentials to enter a Revision as literal node inputs. */
5883
5897
  function assertOpenApiAuthBindings(document) {
5884
- for (const graph of [document.graph, ...Object.values(document.subflows).map((subflow) => subflow.graph)]) for (const node of Object.values(graph.nodes)) {
5885
- if (node.kind != "task" || node.taskId == null || document.tasks[node.taskId]?.executor.kind != "openapi") continue;
5886
- for (const [handle, mapping] of Object.entries(node.inputs)) if (handle.startsWith("auth.") && (mapping.kind == "value" || mapping.kind == "sources" && mapping.sources.some((source) => source.kind == "flow"))) throw new TypeError("OpenAPI authentication accepts deployment variables and upstream outputs only.");
5898
+ for (const node of Object.values(document.graph.nodes)) {
5899
+ if (node.kind != "task" || !("executor" in node.task) || node.task.executor.kind != "openapi") continue;
5900
+ 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.");
5887
5901
  }
5888
5902
  }
5889
5903
  //#endregion
@@ -8533,7 +8547,7 @@ var isObject = (x) => x !== null && typeof x === "object";
8533
8547
  var isPlainObject = (x) => isObject(x) && !isArray(x);
8534
8548
  var toPlainObject = (x) => isPlainObject(x) ? x : void 0;
8535
8549
  //#endregion
8536
- //#region src/manifest/common/schemaComparer.ts
8550
+ //#region src/flow/common/schemaComparer.ts
8537
8551
  function isStringLikeSchema(value) {
8538
8552
  return toPlainObject(value)?.type === "string";
8539
8553
  }
@@ -8776,24 +8790,15 @@ var group = object({
8776
8790
  collapsed: boolean().optional(),
8777
8791
  group: text
8778
8792
  });
8779
- var nodeSource = object({
8793
+ var source = union([object({
8780
8794
  kind: literal("node"),
8781
8795
  nodeId: text,
8782
8796
  output: text,
8783
8797
  field: text.optional()
8784
- });
8785
- var flowSource = object({
8786
- kind: literal("flow"),
8787
- input: text
8788
- });
8789
- var source = union([
8790
- nodeSource,
8791
- flowSource,
8792
- object({
8793
- kind: literal("binding"),
8794
- bindingId: text
8795
- })
8796
- ]);
8798
+ }), object({
8799
+ kind: literal("binding"),
8800
+ bindingId: text
8801
+ })]);
8797
8802
  var fixedInput = union([object({ kind: literal("unset") }), object({
8798
8803
  kind: literal("value"),
8799
8804
  value: json$2
@@ -8802,7 +8807,7 @@ var mapping = union([fixedInput, object({
8802
8807
  kind: literal("sources"),
8803
8808
  sources: array(source)
8804
8809
  })]);
8805
- var inputs = record$1(text, mapping);
8810
+ var inputs = record$2(text, mapping);
8806
8811
  var ports$1 = {
8807
8812
  inputs: array(union([input, group])),
8808
8813
  outputs: array(union([port$1, group]))
@@ -8930,9 +8935,11 @@ var managed = object({
8930
8935
  inputs: array(input.extend({ source: agentInput }))
8931
8936
  })),
8932
8937
  notification: object({
8933
- taskId: text,
8938
+ action: text,
8939
+ connectionId: text.optional(),
8940
+ inputDefinitions: array(input),
8934
8941
  messageHandle: text,
8935
- inputs: record$1(text, agentValue)
8942
+ inputs: record$2(text, agentValue)
8936
8943
  }).optional()
8937
8944
  })
8938
8945
  ])
@@ -8987,7 +8994,7 @@ var webhookOptions = object({
8987
8994
  allowedOrigins: strings.optional(),
8988
8995
  noResponseBody: never().optional(),
8989
8996
  responseData: text.optional(),
8990
- responseHeaders: record$1(text, text).optional(),
8997
+ responseHeaders: record$2(text, text).optional(),
8991
8998
  responseStatusCode: number().int().min(200).max(599).optional()
8992
8999
  });
8993
9000
  var webhook = {
@@ -9043,7 +9050,7 @@ var base = {
9043
9050
  var node = union([
9044
9051
  object({
9045
9052
  ...base,
9046
- inputs: record$1(text, never()),
9053
+ inputs: record$2(text, never()),
9047
9054
  kind: literal("condition"),
9048
9055
  ...condition
9049
9056
  }),
@@ -9053,21 +9060,10 @@ var node = union([
9053
9060
  kind: literal("value"),
9054
9061
  values: array(input)
9055
9062
  }),
9056
- object({
9057
- ...base,
9058
- kind: literal("subflow"),
9059
- subflowId: text
9060
- }),
9061
9063
  object({
9062
9064
  ...base,
9063
9065
  kind: literal("task"),
9064
- task: inline,
9065
- additionalInputs: array(input).optional()
9066
- }),
9067
- object({
9068
- ...base,
9069
- kind: literal("task"),
9070
- taskId: text,
9066
+ task: union([inline, managed]),
9071
9067
  additionalInputs: array(input).optional()
9072
9068
  }),
9073
9069
  strictObject({
@@ -9103,7 +9099,7 @@ var node = union([
9103
9099
  ...trigger,
9104
9100
  kind: literal("poll"),
9105
9101
  connectionId: text.min(1).optional(),
9106
- config: record$1(text, fixedInput),
9102
+ config: record$2(text, fixedInput),
9107
9103
  definition: object({
9108
9104
  ...definition,
9109
9105
  type: literal("poll")
@@ -9114,7 +9110,7 @@ var node = union([
9114
9110
  ...trigger,
9115
9111
  kind: literal("integration"),
9116
9112
  connectionId: text.min(1).optional(),
9117
- config: record$1(text, fixedInput),
9113
+ config: record$2(text, fixedInput),
9118
9114
  definition: object({
9119
9115
  ...definition,
9120
9116
  type: literal("integration"),
@@ -9122,10 +9118,6 @@ var node = union([
9122
9118
  })
9123
9119
  })
9124
9120
  ]);
9125
- var target = union([object({ kind: literal("flow") }), object({
9126
- kind: literal("subflow"),
9127
- id: text
9128
- })]);
9129
9121
  var edge = object({
9130
9122
  source: text,
9131
9123
  target: text,
@@ -9133,15 +9125,10 @@ var edge = object({
9133
9125
  });
9134
9126
  var at = {
9135
9127
  nodeId: text,
9136
- target
9128
+ target: never().optional()
9137
9129
  };
9138
- var subflow = object({
9139
- name: text,
9140
- inputs: array(input),
9141
- outputs: array(port$1.extend({ sources: array(union([nodeSource, flowSource])) }))
9142
- });
9143
9130
  var graph = object({
9144
- nodes: record$1(text, node),
9131
+ nodes: record$2(text, node),
9145
9132
  edges: array(edge).default([])
9146
9133
  });
9147
9134
  var binding = object({
@@ -9153,29 +9140,40 @@ var module = object({
9153
9140
  imports: strings,
9154
9141
  source: text
9155
9142
  });
9156
- var document = object({
9157
- bindings: record$1(text, binding),
9158
- graph,
9159
- subflows: record$1(text, subflow.extend({ graph })),
9160
- tasks: record$1(text, managed)
9161
- });
9143
+ var document = preprocess(rejectRetiredDefinitions, object({
9144
+ bindings: record$2(text, binding),
9145
+ graph
9146
+ }));
9162
9147
  var revision = object({
9163
9148
  modelVersion: union([
9164
9149
  literal(2),
9165
9150
  literal(4),
9166
- literal(5)
9151
+ literal(5),
9152
+ literal(6)
9167
9153
  ]),
9168
9154
  document,
9169
- modules: record$1(text, module)
9155
+ modules: record$2(text, module)
9170
9156
  });
9171
9157
  revision.extend({
9172
9158
  kind: literal("open-flow-flow-revision"),
9173
9159
  version: literal(1)
9174
9160
  });
9161
+ function rejectRetiredDefinitions(value) {
9162
+ const candidate = record$1(value);
9163
+ 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.");
9164
+ if (Object.values(record$1(record$1(candidate.graph).nodes)).some((candidateNode) => Object.hasOwn(record$1(candidateNode), "taskId"))) throw new TypeError("Task references are no longer supported.");
9165
+ const subflows = candidate.subflows;
9166
+ 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.");
9167
+ if (Object.values(record$1(record$1(candidate.graph).nodes)).some((candidateNode) => record$1(candidateNode).kind === "subflow")) throw new TypeError("Subflow nodes are no longer supported.");
9168
+ return value;
9169
+ }
9170
+ function record$1(value) {
9171
+ return value != null && typeof value == "object" && !Array.isArray(value) ? value : {};
9172
+ }
9175
9173
  function decodeRevisionContent(value) {
9176
9174
  checkJsonDepth(value);
9177
9175
  const content = revision.parse(value);
9178
- checkErrorModelVersion(content);
9176
+ checkModelVersion(content);
9179
9177
  assertOpenApiAuthBindings(content.document);
9180
9178
  return content;
9181
9179
  }
@@ -9196,12 +9194,12 @@ var shapes = {
9196
9194
  value: text
9197
9195
  },
9198
9196
  "graph.edge.connect": {
9199
- target,
9200
- edge
9197
+ edge,
9198
+ target: never().optional()
9201
9199
  },
9202
9200
  "graph.edge.disconnect": {
9203
- target,
9204
- edge
9201
+ edge,
9202
+ target: never().optional()
9205
9203
  },
9206
9204
  "graph.node.create": {
9207
9205
  ...at,
@@ -9265,13 +9263,11 @@ var shapes = {
9265
9263
  },
9266
9264
  "graph.node.resolution.set": {
9267
9265
  ...at,
9268
- target: object({ kind: literal("flow") }),
9269
9266
  before: object(wait),
9270
9267
  value: object(wait)
9271
9268
  },
9272
9269
  "graph.node.webhook.set": {
9273
9270
  ...at,
9274
- target: object({ kind: literal("flow") }),
9275
9271
  before: object(webhook),
9276
9272
  value: object(webhook)
9277
9273
  },
@@ -9318,58 +9314,19 @@ var shapes = {
9318
9314
  imports: strings,
9319
9315
  source: text
9320
9316
  },
9321
- "subflow.create": {
9322
- subflowId: text,
9323
- subflow: subflow.extend({ graph })
9324
- },
9325
- "subflow.definition.set": {
9326
- subflowId: text,
9327
- before: subflow,
9328
- definition: subflow
9329
- },
9330
- "subflow.delete": { subflowId: text },
9331
- "task.create": {
9332
- taskId: text,
9333
- task: managed
9334
- },
9335
- "task.delete": { taskId: text },
9336
- "task.connector.connection.set": {
9337
- taskId: text,
9338
- before: text.optional(),
9339
- value: text.optional()
9340
- },
9341
- "task.decision.set": {
9342
- taskId: text,
9343
- before: managed,
9344
- value: managed
9345
- },
9346
- "task.openapi.set": {
9347
- taskId: text,
9348
- before: managed,
9349
- value: managed
9350
- },
9351
- "task.agent.set": {
9352
- taskId: text,
9353
- before: managed,
9354
- value: managed
9355
- },
9356
- "task.llm.mode.set": {
9357
- taskId: text,
9358
- before: _enum(["chat", "json"]),
9359
- value: _enum(["chat", "json"])
9360
- },
9361
- "task.name.set": {
9362
- taskId: text,
9363
- before: text,
9364
- value: text
9317
+ "graph.node.task.set": {
9318
+ ...at,
9319
+ before: union([inline, managed]),
9320
+ value: union([inline, managed])
9365
9321
  }
9366
9322
  };
9367
9323
  array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, shape instanceof ZodType ? shape : object({
9368
9324
  kind: literal(kind),
9369
9325
  ...shape
9370
9326
  })])).values()])).min(1);
9371
- function checkErrorModelVersion(content) {
9372
- if (content.modelVersion < 5 && [content.document.graph, ...Object.values(content.document.subflows).map((item) => item.graph)].some((item) => Object.values(item.nodes).some((itemNode) => itemNode.kind == "error"))) throw new TypeError("Error workflows require Flow model version 5.");
9327
+ function checkModelVersion(content) {
9328
+ if (content.modelVersion < 6 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && "executor" in candidateNode.task)) throw new TypeError("Node-owned managed Tasks require Flow model version 6.");
9329
+ if (content.modelVersion < 5 && Object.values(content.document.graph.nodes).some((itemNode) => itemNode.kind == "error")) throw new TypeError("Error workflows require Flow model version 5.");
9373
9330
  }
9374
9331
  //#endregion
9375
9332
  //#region src/flow/common/change.ts
@@ -9507,22 +9464,32 @@ var ApiError = class extends Error {
9507
9464
  };
9508
9465
  //#endregion
9509
9466
  //#region src/control/common/decoding.ts
9510
- function invalidResponse() {
9511
- throw new ApiError(502, "response.invalid", "The Control API returned an invalid response.");
9467
+ var InvalidResponseError = class extends ApiError {
9468
+ constructor(detail) {
9469
+ super(502, "response.invalid", `The Control API returned an invalid response.${detail == null ? "" : ` ${detail}`}`);
9470
+ this.detail = detail;
9471
+ }
9472
+ };
9473
+ function invalidResponse(detail) {
9474
+ throw new InvalidResponseError(detail);
9512
9475
  }
9513
9476
  function record(value) {
9514
- if (value == null || typeof value != "object" || Array.isArray(value)) return invalidResponse();
9477
+ if (value == null || typeof value != "object" || Array.isArray(value)) return invalidResponse("Expected an object.");
9515
9478
  return value;
9516
9479
  }
9517
9480
  function string(value) {
9518
- return typeof value == "string" && value.length > 0 ? value : invalidResponse();
9481
+ return typeof value == "string" && value.length > 0 ? value : invalidResponse("Expected a non-empty string.");
9519
9482
  }
9520
9483
  function exact(value, keys) {
9521
9484
  const actual = Object.keys(value);
9522
- if (actual.length != keys.length || actual.some((key) => !keys.includes(key))) invalidResponse();
9485
+ if (actual.length != keys.length || actual.some((key) => !keys.includes(key))) {
9486
+ const missing = keys.filter((key) => !Object.hasOwn(value, key));
9487
+ const unexpected = actual.filter((key) => !keys.includes(key));
9488
+ invalidResponse([missing.length > 0 ? `Missing fields: ${missing.join(", ")}.` : "", unexpected.length > 0 ? `Unexpected fields: ${unexpected.join(", ")}.` : ""].filter(Boolean).join(" "));
9489
+ }
9523
9490
  }
9524
9491
  function integer(value) {
9525
- return Number.isSafeInteger(value) ? value : invalidResponse();
9492
+ return Number.isSafeInteger(value) ? value : invalidResponse("Expected a safe integer.");
9526
9493
  }
9527
9494
  function jsonValue(value) {
9528
9495
  if (value === null || typeof value == "boolean" || typeof value == "string") return value;
@@ -9557,10 +9524,19 @@ function accessPermissions(value) {
9557
9524
  "configured",
9558
9525
  "proxy"
9559
9526
  ]);
9560
- if (!Array.isArray(source.triggerIds) || typeof source.allTriggers != "boolean" || !Array.isArray(source.actionIds) || typeof source.allActions != "boolean" || typeof source.configured != "boolean" || typeof source.proxy != "boolean") return invalidResponse();
9527
+ if (!Array.isArray(source.actionIds)) return invalidResponse("permissions.actionIds: expected an array.");
9528
+ if (!Array.isArray(source.triggerIds)) return invalidResponse("permissions.triggerIds: expected an array.");
9529
+ if (typeof source.allActions != "boolean") return invalidResponse("permissions.allActions: expected a boolean.");
9530
+ if (typeof source.allTriggers != "boolean") return invalidResponse("permissions.allTriggers: expected a boolean.");
9531
+ if (typeof source.configured != "boolean") return invalidResponse("permissions.configured: expected a boolean.");
9532
+ if (typeof source.proxy != "boolean") return invalidResponse("permissions.proxy: expected a boolean.");
9561
9533
  const actionIds = source.actionIds.map(string);
9562
9534
  const triggerIds = source.triggerIds.map(string);
9563
- if (new Set(actionIds).size != actionIds.length || source.allActions && actionIds.length != 0 || new Set(triggerIds).size != triggerIds.length || source.allTriggers && triggerIds.length != 0 || source.proxy && (!source.allActions || !source.allTriggers || source.configured)) return invalidResponse();
9535
+ if (new Set(actionIds).size != actionIds.length) return invalidResponse("permissions.actionIds: duplicate IDs.");
9536
+ if (source.allActions && actionIds.length != 0) return invalidResponse("permissions.actionIds: must be empty when allActions is true.");
9537
+ if (new Set(triggerIds).size != triggerIds.length) return invalidResponse("permissions.triggerIds: duplicate IDs.");
9538
+ if (source.allTriggers && triggerIds.length != 0) return invalidResponse("permissions.triggerIds: must be empty when allTriggers is true.");
9539
+ if (source.proxy && (!source.allActions || !source.allTriggers || source.configured)) return invalidResponse("permissions.proxy: requires allActions=true, allTriggers=true and configured=false.");
9564
9540
  return {
9565
9541
  actionIds,
9566
9542
  triggerIds,
@@ -9590,15 +9566,15 @@ function accessBinding(value, candidate) {
9590
9566
  "providerId",
9591
9567
  ...candidate ? [] : ["status"]
9592
9568
  ]);
9593
- if (policyRevision != null && typeof policyRevision != "string") return invalidResponse();
9594
- if (candidate && isDefault !== void 0 && typeof isDefault != "boolean") return invalidResponse();
9595
- if (permissionGroupName !== void 0 && permissionGroupName !== null && typeof permissionGroupName != "string") return invalidResponse();
9569
+ if (policyRevision != null && typeof policyRevision != "string") return invalidResponse("policyRevision: expected a string.");
9570
+ if (candidate && isDefault !== void 0 && typeof isDefault != "boolean") return invalidResponse("isDefault: expected a boolean.");
9571
+ if (permissionGroupName !== void 0 && permissionGroupName !== null && typeof permissionGroupName != "string") return invalidResponse("permissionGroupName: expected a string or null.");
9596
9572
  if (!candidate && status != "active" && status != "forbidden" && status != "invalid" && status != "missing") return invalidResponse();
9597
9573
  let bindingSource;
9598
9574
  try {
9599
9575
  bindingSource = parseProviderAccessSource(source.source);
9600
9576
  } catch {
9601
- return invalidResponse();
9577
+ return invalidResponse("source: expected { kind: 'admin-delegation' } or { kind: 'policy', ruleId: string | null }.");
9602
9578
  }
9603
9579
  return {
9604
9580
  accessBindingId: string(source.accessBindingId),
@@ -9614,7 +9590,7 @@ function accessBinding(value, candidate) {
9614
9590
  };
9615
9591
  }
9616
9592
  function accessMode(value) {
9617
- if (value != "implicit" && value != "selectable") return invalidResponse();
9593
+ if (value != "implicit" && value != "selectable") return invalidResponse("mode: expected implicit or selectable.");
9618
9594
  return value;
9619
9595
  }
9620
9596
  function connectorAccess(value) {
@@ -9723,10 +9699,12 @@ function connectorAccessCandidates(value, providerId) {
9723
9699
  "providerId",
9724
9700
  "version"
9725
9701
  ]);
9726
- if (source.version != 1 || string(source.providerId) != providerId || !Array.isArray(source.candidates)) return invalidResponse();
9702
+ if (source.version != 1) return invalidResponse("version: expected 1.");
9703
+ if (string(source.providerId) != providerId) return invalidResponse("providerId: does not match the requested provider.");
9704
+ if (!Array.isArray(source.candidates)) return invalidResponse("candidates: expected an array.");
9727
9705
  const candidates = source.candidates.map((candidate) => accessBinding(candidate, true));
9728
- if (candidates.some((candidate) => candidate.providerId != providerId)) return invalidResponse();
9729
- if (new Set(candidates.map((candidate) => candidate.accessBindingId)).size != candidates.length) return invalidResponse();
9706
+ if (candidates.some((candidate) => candidate.providerId != providerId)) return invalidResponse("candidates[].providerId: does not match the requested provider.");
9707
+ if (new Set(candidates.map((candidate) => candidate.accessBindingId)).size != candidates.length) return invalidResponse("candidates[].accessBindingId: duplicate IDs.");
9730
9708
  return {
9731
9709
  candidates,
9732
9710
  mode: accessMode(source.mode),
@@ -9737,12 +9715,13 @@ function connectorAccessCandidates(value, providerId) {
9737
9715
  function connectorAccessCandidatesBatch(value, providerIds) {
9738
9716
  const source = record(value);
9739
9717
  exact(source, ["results", "version"]);
9740
- if (source.version != 1 || !Array.isArray(source.results)) return invalidResponse();
9718
+ if (source.version != 1) return invalidResponse("version: expected 1.");
9719
+ if (!Array.isArray(source.results)) return invalidResponse("results: expected an array.");
9741
9720
  const remaining = new Set(providerIds);
9742
9721
  const results = source.results.map((entry) => {
9743
9722
  const item = record(entry);
9744
9723
  const providerId = string(item.providerId);
9745
- if (!remaining.delete(providerId)) return invalidResponse();
9724
+ if (!remaining.delete(providerId)) return invalidResponse("results[].providerId: duplicate or unrequested provider.");
9746
9725
  if (!Object.hasOwn(item, "error")) return connectorAccessCandidates(item, providerId);
9747
9726
  exact(item, ["providerId", "error"]);
9748
9727
  const error = record(item.error);
@@ -9755,7 +9734,7 @@ function connectorAccessCandidatesBatch(value, providerIds) {
9755
9734
  }
9756
9735
  };
9757
9736
  });
9758
- if (remaining.size != 0) return invalidResponse();
9737
+ if (remaining.size != 0) return invalidResponse("results: missing requested providers.");
9759
9738
  return {
9760
9739
  results,
9761
9740
  version: 1
@@ -10938,7 +10917,7 @@ function decodeRunEvent(value) {
10938
10917
  switch (kind) {
10939
10918
  case "node.started": {
10940
10919
  const nodeKind = payload.nodeKind;
10941
- if (nodeKind !== void 0 && nodeKind !== "approval" && nodeKind !== "condition" && nodeKind !== "connector" && nodeKind !== "javascript" && nodeKind !== "decision" && nodeKind !== "openapi" && nodeKind !== "llm" && nodeKind !== "agent" && nodeKind !== "subflow" && nodeKind !== "value" && nodeKind !== "wait") return invalidResponse();
10920
+ if (nodeKind !== void 0 && nodeKind !== "approval" && nodeKind !== "condition" && nodeKind !== "connector" && nodeKind !== "javascript" && nodeKind !== "decision" && nodeKind !== "openapi" && nodeKind !== "llm" && nodeKind !== "agent" && nodeKind !== "value" && nodeKind !== "wait") return invalidResponse();
10942
10921
  return {
10943
10922
  ...base,
10944
10923
  kind,
@@ -11679,7 +11658,6 @@ var mcpConformanceCases = [
11679
11658
  const flow = await client.createFlow("MCP Run listing");
11680
11659
  const changed = await client.changeDraft(flow.flowId, flow.draftRevisionId, [{
11681
11660
  kind: "graph.node.create",
11682
- target: { kind: "flow" },
11683
11661
  nodeId: "start",
11684
11662
  node: {
11685
11663
  kind: "manual",
@@ -11823,15 +11801,14 @@ var mcpTools = {
11823
11801
  cursor: id.optional(),
11824
11802
  limit: pageLimit
11825
11803
  }), true),
11826
- flow_get: tool("Read a compact Draft graph with input bindings, port handles, subflows and Live status. Use full=true for complete Revision content, schemas, source code and exact before values required by complex edits. Unreadable Drafts return draft=null and draftIssue; flow.live still identifies the published version. Use draft.revisionId as the base of an edit.", strictObject({
11804
+ flow_get: tool("Read a compact Draft graph with input bindings, port handles and Live status. Use full=true for complete Revision content, schemas, source code and exact before values required by complex edits. Unreadable Drafts return draft=null and draftIssue; flow.live still identifies the published version. Use draft.revisionId as the base of an edit.", strictObject({
11827
11805
  flowId: flow,
11828
11806
  full: boolean().optional()
11829
11807
  }), true),
11830
- flow_node_get: tool("Read one node and its Task definition or code module from a fixed Revision. Omit subflowId for the root graph. Use revisionId from flow_get; the returned node contains exact before values for edits.", strictObject({
11808
+ flow_node_get: tool("Read one node and its Task definition or code module from a fixed Revision. Use revisionId from flow_get; the returned node contains exact before values for edits.", strictObject({
11831
11809
  flowId: flow,
11832
11810
  revisionId: id,
11833
- nodeId: id,
11834
- subflowId: id.optional()
11811
+ nodeId: id
11835
11812
  }), true),
11836
11813
  flow_schema: tool("Get an operation schema by kind, or a complete apply batch by example (connector, poll, poll-notification, code, wait). Use example=index to list examples. graph.trigger.create resolves a provider key into a fixed definition at commit.", strictObject({
11837
11814
  kind: id.optional(),
@@ -11873,18 +11850,18 @@ var mcpTools = {
11873
11850
  revisionId: id,
11874
11851
  trigger: strictObject({
11875
11852
  nodeId: id,
11876
- outputs: record$1(string$1(), json)
11853
+ outputs: record$2(string$1(), json)
11877
11854
  }),
11878
- inputs: record$1(string$1(), record$1(string$1(), json)).default({}),
11855
+ inputs: record$2(string$1(), record$2(string$1(), json)).default({}),
11879
11856
  idempotencyKey: mutationKey
11880
11857
  }), strictObject({
11881
11858
  source: literal("live"),
11882
11859
  publicationId: id,
11883
11860
  trigger: strictObject({
11884
11861
  nodeId: id,
11885
- outputs: record$1(string$1(), json)
11862
+ outputs: record$2(string$1(), json)
11886
11863
  }),
11887
- inputs: record$1(string$1(), record$1(string$1(), json)).default({}),
11864
+ inputs: record$2(string$1(), record$2(string$1(), json)).default({}),
11888
11865
  idempotencyKey: mutationKey
11889
11866
  })]).meta({ type: "object" }), false),
11890
11867
  run_list: tool("List Runs for a Flow, optionally filtered by status. Continue with nextCursor; cursors are compatible with the Control API.", strictObject({