@oomol-lab/open-flow 0.1.0-beta.77 → 0.1.0-beta.79

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 (64) hide show
  1. package/README.md +2 -0
  2. package/dist/browser/{ContentIcon-VZQO8VZU.js → ContentIcon-CMn0c-kl.js} +93 -3
  3. package/dist/browser/{FlowCanvas-BNGDMaWr.js → FlowCanvas-BQGBcfoL.js} +1675 -591
  4. package/dist/browser/{createResourceDialog-BmtakfVg.js → createResourceDialog-DkovGogv.js} +3 -3
  5. package/dist/browser/{dialog-BcFBfRB1.js → dialog-CFFuRM8s.js} +37 -86
  6. package/dist/browser/{exportSvg-CG8hEUNk.js → exportSvg-CYwyYiuH.js} +2 -2
  7. package/dist/browser/{flowChanges-BGo_4Ypo.js → flowChanges-CN2R-m1M.js} +1258 -422
  8. package/dist/browser/{flowWorkspace-BFHGev7s.js → flowWorkspace-CXVL1FNv.js} +634 -628
  9. package/dist/browser/licenses.md +1 -1
  10. package/dist/browser/preview.css +512 -462
  11. package/dist/browser/preview.js +8183 -6384
  12. package/dist/browser/{tooltip-BAWSUexx.js → tooltip-BDcVTNpu.js} +65 -2
  13. package/dist/browser/{typeScriptSession-CRoezJPN.js → typeScriptSession-CoEIptNC.js} +1 -1
  14. package/dist/browser/ui.css +5 -24
  15. package/dist/browser/workbench.css +512 -462
  16. package/dist/browser/workbench.d.ts +2 -3
  17. package/dist/browser/workbench.js +65 -690
  18. package/dist/browser/{workbenchSelect-CjK-xdm3.js → workbenchSelect-CkOS95gX.js} +2 -2
  19. package/dist/command/index.js +31 -31
  20. package/dist/common/authoring.d.ts +3 -3
  21. package/dist/common/authoringExamples.d.ts +3 -3
  22. package/dist/common/authoringSchema.d.ts +14 -22
  23. package/dist/common/control-api-conformance.js +91 -25
  24. package/dist/common/control-api.d.ts +8 -3
  25. package/dist/common/control-api.js +51 -25
  26. package/dist/common/control-requests.d.ts +9 -3
  27. package/dist/common/control-requests.js +54 -42
  28. package/dist/common/flow-authoring.js +32 -19
  29. package/dist/common/flow-change.d.ts +1 -1
  30. package/dist/common/flow-change.js +32 -19
  31. package/dist/common/flow-encoding.js +31 -18
  32. package/dist/common/flow-semantics.js +41 -26
  33. package/dist/common/flow-state.d.ts +49 -43
  34. package/dist/common/flow-state.js +95 -110
  35. package/dist/common/mcp.d.ts +35 -4
  36. package/dist/common/mcp.js +51 -26
  37. package/dist/common/run-events.js +19 -9
  38. package/dist/common/runtime-contract.d.ts +4 -1
  39. package/dist/common/runtime-contract.js +66 -17
  40. package/dist/common/runtime-nodejs-compat.js +11 -12
  41. package/dist/common/scheduler.d.ts +2 -1
  42. package/dist/common/scheduler.js +82 -55
  43. package/dist/common/state-conformance.d.ts +3 -3
  44. package/dist/index.d.ts +1 -0
  45. package/package.json +1 -1
  46. package/src/control/common/api.ts +36 -7
  47. package/src/control/common/authoring.ts +6 -5
  48. package/src/control/common/authoringExamples.ts +6 -5
  49. package/src/control/common/authoringSchema.ts +7 -7
  50. package/src/control/common/conformance.ts +31 -0
  51. package/src/control/common/mcp.ts +7 -2
  52. package/src/control/common/requests.ts +10 -1
  53. package/src/execution/common/events.ts +22 -10
  54. package/src/execution/common/node-execution.ts +1 -1
  55. package/src/execution/common/scheduler.ts +28 -14
  56. package/src/flow/common/change.ts +1 -1
  57. package/src/flow/common/changeSchema.ts +4 -4
  58. package/src/flow/common/errorHandling.ts +1 -1
  59. package/src/flow/common/semantics.ts +12 -6
  60. package/src/runtime/common/nodejsGuest.generated.json +11 -12
  61. package/src/runtime/common/runtime.ts +45 -12
  62. package/src/state/common/conformance.ts +32 -21
  63. package/src/state/common/state.ts +85 -80
  64. package/src/types/index.ts +1 -0
@@ -5773,24 +5773,31 @@ function dequal(foo, bar) {
5773
5773
  }
5774
5774
  return foo !== foo && bar !== bar;
5775
5775
  }
5776
+ //#endregion
5777
+ //#region src/state/common/state.ts
5778
+ var stateReadLimits = {
5779
+ maxKeys: 16,
5780
+ maxBytes: 1048576
5781
+ };
5782
+ var keySchema = string$1().min(1).refine((value) => new TextEncoder().encode(value).length <= 256);
5776
5783
  strictObject({
5777
5784
  scope: _enum(["draft", "live"]),
5778
- values: boolean().optional()
5785
+ values: literal(false).optional()
5779
5786
  });
5780
5787
  strictObject({
5781
5788
  scope: _enum(["draft", "live"]),
5782
- key: string$1().min(1).refine((key) => new TextEncoder().encode(key).length <= 256).optional()
5789
+ keys: array(keySchema).min(1).max(stateReadLimits.maxKeys).refine((keys) => new Set(keys).size === keys.length, "State keys must be distinct.")
5783
5790
  });
5784
5791
  strictObject({
5785
5792
  scope: _enum(["draft", "live"]),
5786
- space: string$1().regex(/^(flow|node:.+)$/)
5793
+ key: keySchema.optional()
5787
5794
  });
5788
- var dedupeConfigSchema = strictObject({
5789
- field: string$1().default(""),
5790
- mode: _enum(["new", "increasing"]).default("new"),
5791
- space: _enum(["node", "flow"]).default("node")
5795
+ strictObject({
5796
+ scope: _enum(["draft", "live"]),
5797
+ space: string$1().regex(/^(flow|node:.+)$/)
5792
5798
  });
5793
- var dedupeExecutorSchema = dedupeConfigSchema.extend({ kind: literal("dedupe") });
5799
+ var skipDuplicatesConfigSchema = strictObject({ fields: array(string$1().refine((field) => field.length > 0 && field.split(".").every((part) => part.length > 0), "Use a nonempty dot-separated field path.")).refine((fields) => new Set(fields).size === fields.length, "Identity fields must be distinct.").default([]) });
5800
+ var skipDuplicatesExecutorSchema = skipDuplicatesConfigSchema.extend({ kind: literal("skip-duplicates") });
5794
5801
  var flowStateViewSchema = object({
5795
5802
  version: literal(1),
5796
5803
  scope: _enum(["draft", "live"]),
@@ -5801,24 +5808,30 @@ var flowStateViewSchema = object({
5801
5808
  maxIdentities: number().positive(),
5802
5809
  maxRunWrites: number().positive()
5803
5810
  }),
5804
- values: array(object({
5811
+ values: array(strictObject({
5805
5812
  key: string$1(),
5806
5813
  size: number().nonnegative(),
5807
- updatedAt: number(),
5808
- value: json$3().optional()
5814
+ updatedAt: number()
5809
5815
  })),
5810
5816
  spaces: array(object({
5811
5817
  space: string$1(),
5812
- mode: _enum(["new", "increasing"]),
5813
5818
  count: number().nonnegative(),
5814
- watermark: union([
5815
- string$1(),
5816
- number(),
5817
- _null()
5818
- ]),
5819
+ pendingCount: number().nonnegative(),
5820
+ reservedCount: number().nonnegative(),
5819
5821
  updatedAt: number()
5820
5822
  }))
5821
5823
  });
5824
+ var flowStateValuesSchema = object({
5825
+ version: literal(1),
5826
+ scope: _enum(["draft", "live"]),
5827
+ values: array(strictObject({
5828
+ key: keySchema,
5829
+ value: json$3()
5830
+ })).min(1).max(stateReadLimits.maxKeys)
5831
+ }).refine((response) => {
5832
+ const encoder = new TextEncoder();
5833
+ return response.values.reduce((bytes, item) => bytes + (item.value === null ? 0 : encoder.encode(JSON.stringify(item.value)).byteLength), 0) <= stateReadLimits.maxBytes;
5834
+ }, "State values exceed the 1 MiB read limit.");
5822
5835
  //#endregion
5823
5836
  //#region src/json-schema-subset/utils.ts
5824
5837
  var nextId = 0;
@@ -9098,7 +9111,7 @@ var managedFields = object({
9098
9111
  revisionId: text
9099
9112
  }),
9100
9113
  httpRequestExecutorSchema,
9101
- dedupeExecutorSchema
9114
+ skipDuplicatesExecutorSchema
9102
9115
  ])
9103
9116
  });
9104
9117
  var managed = managedFields.transform(limitDecisionTask);
@@ -9570,7 +9583,7 @@ array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, sha
9570
9583
  ...shape
9571
9584
  })])).values()])).min(1);
9572
9585
  function checkModelVersion(content) {
9573
- if (content.modelVersion < 13 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind === "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind === "dedupe")) throw new Error("Deduplication requires Flow model v13.");
9586
+ if (content.modelVersion < 13 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind === "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind === "skip-duplicates")) throw new Error("Skip Duplicates requires Flow model v13.");
9574
9587
  if (content.modelVersion < 12 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && "moduleId" in candidateNode.task && candidateNode.task.capabilities?.some((item) => item.kind == "http"))) throw new TypeError("Code HTTP access requires Flow model version 12.");
9575
9588
  if (content.modelVersion < 11 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind == "http-request")) throw new TypeError("HTTP Request requires Flow model version 11.");
9576
9589
  if (content.modelVersion < 11 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && ("moduleId" in candidateNode.task ? candidateNode.task.capabilities?.some((item) => item.kind == "workflow") : candidateNode.task.executor.kind == "agent" && candidateNode.task.executor.tools.some((item) => item.kind == "workflow")))) throw new TypeError("Workflow tools require Flow model version 11.");
@@ -9639,7 +9652,7 @@ var type = _enum([
9639
9652
  "decision",
9640
9653
  "openapi",
9641
9654
  "http-request",
9642
- "dedupe",
9655
+ "skip-duplicates",
9643
9656
  "condition",
9644
9657
  "value",
9645
9658
  "wait",
@@ -9770,7 +9783,7 @@ var authoringConfigurations = {
9770
9783
  "connector": authoringDefinitionSchemas.connector.omit({ outputMode: true }).strict(),
9771
9784
  "openapi": authoringOpenApiSchema,
9772
9785
  "http-request": httpRequestConfigSchema,
9773
- "dedupe": dedupeConfigSchema,
9786
+ "skip-duplicates": skipDuplicatesConfigSchema,
9774
9787
  "agent": authoringDefinitionSchemas.agent.omit({
9775
9788
  prompt: true,
9776
9789
  tools: true
@@ -12557,7 +12570,7 @@ function decodeRunEvent(value) {
12557
12570
  switch (kind) {
12558
12571
  case "node.started": {
12559
12572
  const nodeKind = payload.nodeKind;
12560
- if (nodeKind !== void 0 && nodeKind !== "approval" && nodeKind !== "condition" && nodeKind !== "connector" && nodeKind !== "javascript" && nodeKind !== "decision" && nodeKind !== "openapi" && nodeKind !== "http-request" && nodeKind !== "dedupe" && nodeKind !== "llm" && nodeKind !== "agent" && nodeKind !== "value" && nodeKind !== "outputs" && nodeKind !== "webhook-response" && nodeKind !== "workflow" && nodeKind !== "wait") return invalidResponse();
12573
+ if (nodeKind !== void 0 && nodeKind !== "approval" && nodeKind !== "condition" && nodeKind !== "connector" && nodeKind !== "javascript" && nodeKind !== "decision" && nodeKind !== "openapi" && nodeKind !== "http-request" && nodeKind !== "skip-duplicates" && nodeKind !== "llm" && nodeKind !== "agent" && nodeKind !== "value" && nodeKind !== "outputs" && nodeKind !== "webhook-response" && nodeKind !== "workflow" && nodeKind !== "wait") return invalidResponse();
12561
12574
  return {
12562
12575
  ...base,
12563
12576
  kind,
@@ -12782,12 +12795,13 @@ var ControlClient = class {
12782
12795
  })
12783
12796
  }));
12784
12797
  }
12785
- async createFlow(name, idempotencyKey = `flow-${randomId()}`, teamId, tagIds) {
12798
+ async createFlow(name, idempotencyKey = `flow-${randomId()}`, teamId, tagIds, initialPresentation) {
12786
12799
  return flow(await this.request("/v1/flows", {
12787
12800
  body: JSON.stringify({
12788
12801
  name,
12789
12802
  ...teamId == null ? {} : { teamId },
12790
12803
  ...tagIds == null ? {} : { tagIds },
12804
+ ...initialPresentation == null ? {} : { presentation: initialPresentation },
12791
12805
  version: 1
12792
12806
  }),
12793
12807
  headers: { "idempotency-key": idempotencyKey },
@@ -12869,10 +12883,22 @@ var ControlClient = class {
12869
12883
  })
12870
12884
  }));
12871
12885
  }
12872
- async getFlowState(flowId, scope, values = false) {
12873
- const result = flowStateViewSchema.safeParse(await this.request(`/v1/flows/${segment(flowId)}/state?scope=${scope}&values=${values}`));
12886
+ async getFlowState(flowId, scope) {
12887
+ const result = flowStateViewSchema.safeParse(await this.request(`/v1/flows/${segment(flowId)}/state?scope=${scope}`));
12874
12888
  return result.success && result.data.scope === scope ? result.data : invalidResponse();
12875
12889
  }
12890
+ async getFlowStateValues(flowId, scope, keys, signal) {
12891
+ const result = flowStateValuesSchema.safeParse(await this.request(`/v1/flows/${segment(flowId)}/state/read`, {
12892
+ method: "POST",
12893
+ body: JSON.stringify({
12894
+ version: 1,
12895
+ scope,
12896
+ keys
12897
+ }),
12898
+ signal
12899
+ }));
12900
+ return result.success && result.data.scope === scope && result.data.values.length === keys.length && result.data.values.every((item, index) => item.key === keys[index]) ? result.data : invalidResponse();
12901
+ }
12876
12902
  async clearFlowState(flowId, scope, key) {
12877
12903
  const source = record(await this.request(`/v1/flows/${segment(flowId)}/state?scope=${scope}${key == null ? "" : `&key=${encodeURIComponent(key)}`}`, { method: "DELETE" }));
12878
12904
  if (source.version !== 1 || source.cleared !== true) invalidResponse();
@@ -10,6 +10,11 @@ export declare const waitActionBodySchema: {
10
10
  };
11
11
  };
12
12
  export declare const controlRequests: {
13
+ readFlowState: (value: unknown) => {
14
+ scope: "draft" | "live";
15
+ keys: string[];
16
+ version: 1;
17
+ };
13
18
  canvas: (value: unknown) => {
14
19
  command: {
15
20
  type: "focus";
@@ -35,7 +40,7 @@ export declare const controlRequests: {
35
40
  edits: ({
36
41
  op: "node.add";
37
42
  as: string;
38
- type: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "dedupe" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow";
43
+ type: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "skip-duplicates" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow";
39
44
  name: string;
40
45
  onError?: "error" | "stop" | undefined;
41
46
  retry?: {
@@ -178,12 +183,12 @@ export declare const controlRequests: {
178
183
  authoringSearch: (value: unknown) => {
179
184
  revision?: string | undefined;
180
185
  query: string;
181
- type?: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "dedupe" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow" | undefined;
186
+ type?: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "skip-duplicates" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow" | undefined;
182
187
  offset: number;
183
188
  limit: number;
184
189
  };
185
190
  authoringSchema: (value: unknown) => {
186
- type?: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "dedupe" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow" | undefined;
191
+ type?: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "skip-duplicates" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow" | undefined;
187
192
  action?: string | undefined;
188
193
  };
189
194
  loadOpenApiDocument: (value: unknown) => {
@@ -207,6 +212,7 @@ export declare const controlRequests: {
207
212
  name: string;
208
213
  teamId?: string | undefined;
209
214
  tagIds?: string[] | undefined;
215
+ presentation?: Record<string, JsonValue> | undefined;
210
216
  version: 1;
211
217
  };
212
218
  saveTag: (value: unknown) => {
@@ -12473,30 +12473,37 @@ function httpRequestInputs(mappings, previous, next) {
12473
12473
  const rename = candidate != null && ["query.", "header."].some((prefix) => candidate.every((name) => name.startsWith(prefix))) ? candidate : void 0;
12474
12474
  return remapInputMappings(mappings, next.inputs, rename);
12475
12475
  }
12476
+ //#endregion
12477
+ //#region src/state/common/state.ts
12478
+ var stateReadLimits = {
12479
+ maxKeys: 16,
12480
+ maxBytes: 1048576
12481
+ };
12482
+ var keySchema = string().min(1).refine((value) => new TextEncoder().encode(value).length <= 256);
12476
12483
  strictObject({
12477
12484
  scope: _enum(["draft", "live"]),
12478
- values: boolean().optional()
12485
+ values: literal(false).optional()
12486
+ });
12487
+ var stateReadSchema = strictObject({
12488
+ scope: _enum(["draft", "live"]),
12489
+ keys: array(keySchema).min(1).max(stateReadLimits.maxKeys).refine((keys) => new Set(keys).size === keys.length, "State keys must be distinct.")
12479
12490
  });
12480
12491
  strictObject({
12481
12492
  scope: _enum(["draft", "live"]),
12482
- key: string().min(1).refine((key) => new TextEncoder().encode(key).length <= 256).optional()
12493
+ key: keySchema.optional()
12483
12494
  });
12484
12495
  strictObject({
12485
12496
  scope: _enum(["draft", "live"]),
12486
12497
  space: string().regex(/^(flow|node:.+)$/)
12487
12498
  });
12488
- var dedupeConfigSchema = strictObject({
12489
- field: string().default(""),
12490
- mode: _enum(["new", "increasing"]).default("new"),
12491
- space: _enum(["node", "flow"]).default("node")
12492
- });
12493
- var dedupeExecutorSchema = dedupeConfigSchema.extend({ kind: literal("dedupe") });
12494
- function dedupeTask(config = dedupeConfigSchema.parse({}), name = "Remove Duplicates") {
12499
+ var skipDuplicatesConfigSchema = strictObject({ fields: array(string().refine((field) => field.length > 0 && field.split(".").every((part) => part.length > 0), "Use a nonempty dot-separated field path.")).refine((fields) => new Set(fields).size === fields.length, "Identity fields must be distinct.").default([]) });
12500
+ var skipDuplicatesExecutorSchema = skipDuplicatesConfigSchema.extend({ kind: literal("skip-duplicates") });
12501
+ function skipDuplicatesTask(config = skipDuplicatesConfigSchema.parse({}), name = "Skip Duplicates") {
12495
12502
  return {
12496
12503
  name,
12497
12504
  executor: {
12498
12505
  ...config,
12499
- kind: "dedupe"
12506
+ kind: "skip-duplicates"
12500
12507
  },
12501
12508
  inputs: [{
12502
12509
  handle: "items",
@@ -12520,24 +12527,30 @@ object$1({
12520
12527
  maxIdentities: number().positive(),
12521
12528
  maxRunWrites: number().positive()
12522
12529
  }),
12523
- values: array(object$1({
12530
+ values: array(strictObject({
12524
12531
  key: string(),
12525
12532
  size: number().nonnegative(),
12526
- updatedAt: number(),
12527
- value: json$5().optional()
12533
+ updatedAt: number()
12528
12534
  })),
12529
12535
  spaces: array(object$1({
12530
12536
  space: string(),
12531
- mode: _enum(["new", "increasing"]),
12532
12537
  count: number().nonnegative(),
12533
- watermark: union([
12534
- string(),
12535
- number(),
12536
- _null()
12537
- ]),
12538
+ pendingCount: number().nonnegative(),
12539
+ reservedCount: number().nonnegative(),
12538
12540
  updatedAt: number()
12539
12541
  }))
12540
12542
  });
12543
+ object$1({
12544
+ version: literal(1),
12545
+ scope: _enum(["draft", "live"]),
12546
+ values: array(strictObject({
12547
+ key: keySchema,
12548
+ value: json$5()
12549
+ })).min(1).max(stateReadLimits.maxKeys)
12550
+ }).refine((response) => {
12551
+ const encoder = new TextEncoder();
12552
+ return response.values.reduce((bytes, item) => bytes + (item.value === null ? 0 : encoder.encode(JSON.stringify(item.value)).byteLength), 0) <= stateReadLimits.maxBytes;
12553
+ }, "State values exceed the 1 MiB read limit.");
12541
12554
  function checkJsonDepth(value, depth = 0) {
12542
12555
  if (depth > 64) throw new TypeError("Value exceeds the maximum JSON depth.");
12543
12556
  if (value != null && typeof value == "object") for (const child of Object.values(value)) checkJsonDepth(child, depth + 1);
@@ -12858,7 +12871,7 @@ var managedFields = object$1({
12858
12871
  revisionId: text$1
12859
12872
  }),
12860
12873
  httpRequestExecutorSchema,
12861
- dedupeExecutorSchema
12874
+ skipDuplicatesExecutorSchema
12862
12875
  ])
12863
12876
  });
12864
12877
  var managed = managedFields.transform(limitDecisionTask);
@@ -13354,7 +13367,7 @@ function changeOperationsSchema(kind) {
13354
13367
  return toJSONSchema(schema, { io: "input" });
13355
13368
  }
13356
13369
  function checkModelVersion(content) {
13357
- if (content.modelVersion < 13 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind === "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind === "dedupe")) throw new Error("Deduplication requires Flow model v13.");
13370
+ if (content.modelVersion < 13 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind === "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind === "skip-duplicates")) throw new Error("Skip Duplicates requires Flow model v13.");
13358
13371
  if (content.modelVersion < 12 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && "moduleId" in candidateNode.task && candidateNode.task.capabilities?.some((item) => item.kind == "http"))) throw new TypeError("Code HTTP access requires Flow model version 12.");
13359
13372
  if (content.modelVersion < 11 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind == "http-request")) throw new TypeError("HTTP Request requires Flow model version 11.");
13360
13373
  if (content.modelVersion < 11 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && ("moduleId" in candidateNode.task ? candidateNode.task.capabilities?.some((item) => item.kind == "workflow") : candidateNode.task.executor.kind == "agent" && candidateNode.task.executor.tools.some((item) => item.kind == "workflow")))) throw new TypeError("Workflow tools require Flow model version 11.");
@@ -14039,7 +14052,7 @@ var authoringTypes = [
14039
14052
  "decision",
14040
14053
  "openapi",
14041
14054
  "http-request",
14042
- "dedupe",
14055
+ "skip-duplicates",
14043
14056
  "condition",
14044
14057
  "value",
14045
14058
  "wait",
@@ -14171,7 +14184,7 @@ var authoringConfigurations = {
14171
14184
  "connector": authoringDefinitionSchemas.connector.omit({ outputMode: true }).strict(),
14172
14185
  "openapi": authoringOpenApiSchema,
14173
14186
  "http-request": httpRequestConfigSchema,
14174
- "dedupe": dedupeConfigSchema,
14187
+ "skip-duplicates": skipDuplicatesConfigSchema,
14175
14188
  "agent": authoringDefinitionSchemas.agent.omit({
14176
14189
  prompt: true,
14177
14190
  tools: true
@@ -14391,7 +14404,7 @@ function authoringSchema(kind) {
14391
14404
  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."
14392
14405
  } : {
14393
14406
  type: kind,
14394
- onError: kind == "dedupe" || retryNodeTypes.some((nodeType) => nodeType == kind) ? { enum: ["stop", "error"] } : false,
14407
+ onError: kind == "skip-duplicates" || retryNodeTypes.some((nodeType) => nodeType == kind) ? { enum: ["stop", "error"] } : false,
14395
14408
  retry: retryNodeTypes.some((nodeType) => nodeType == kind) ? toJSONSchema(retryConfigurationSchema) : false,
14396
14409
  inputSources: ["poll", "integration"].includes(kind) ? [
14397
14410
  "value",
@@ -14421,7 +14434,7 @@ function authoringSchema(kind) {
14421
14434
  "wait",
14422
14435
  "approval"
14423
14436
  ].includes(kind),
14424
- guidance: kind == "webhook-response" ? "Prepare an HTTP response using fixed inputs body (any JSON, default empty text), statusCode (number, default 200) and headers (scalar-valued object, default {}). Select this node in Webhook options.responseBody as {kind: \"webhook-response\", nodeId: \"node reference\", timeoutMs: 30000}. Its first completion responds immediately while the Run continues. It has no business outputs. Multiple response nodes are allowed; each Webhook selects one reachable node." : kind == "outputs" ? "Declare output fields through config.outputDefs. Set their values through node.add.inputs or input.set. Outputs is a singleton execution sink; it waits for its predecessors and produces workflow business outputs independently of node logs. No downstream edges or data references to Outputs are allowed." : kind == "webhook" ? "Use options.responseBody: {kind: \"webhook-response\", nodeId: \"node ID or $alias\", timeoutMs: 30000} to respond on the selected node’s first completion while the Run continues. Body, statusCode and headers come exclusively from that node; clear workflow-output-only status/header references when switching. Alternatively configure options.responseBody as {kind: \"workflow-outputs\", output?: \"top-level output name\", timeoutMs?: 30000} to respond after the Run succeeds. Omit output for the complete object. Connect Webhook to Outputs. Timeout is 1000–60000 ms; HTTP timeout does not cancel the Run. Strings return text; other values return JSON. Only in this mode, options.responseStatusCodeOutput can select a numeric top-level workflow output as the HTTP status, overriding the preserved fixed responseStatusCode (default 200). Its runtime value must be an integer from 200 to 599, excluding 204, 205, 304; missing or invalid values return 500. Use responseHeaders for fixed text headers. In workflow-output mode, responseHeaderOutputs maps header names to top-level output names; values can be string, number or boolean and are converted to text. Alternatively responseHeadersSource: {kind: \"workflow-outputs\", output?: \"object field\"} replaces the entire header object (omit output for all outputs), preserving but ignoring per-header settings. Missing, null, complex or invalid header values return 500 without fallback. Header restrictions and Content-Type policy still apply. Omit responseBody for immediate responseData. Clear options.responseBody, options.responseStatusCodeOutput, options.responseHeadersSource and options.responseHeaderOutputs explicitly to switch back." : kind == "start" ? "Declare workflow inputs through config.inputDefs; read them in Start node details. REST calls and manual runs supply them as trigger.outputs. Downstream nodes bind these parameters as Start outputs. Start has no input sources or defaults; non-nullable parameters are required, and omitted nullable parameters become null." : 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 == "dedupe" ? "Bind an items array. Configure field (dot-separated identity path, empty for scalar items), mode (new or increasing), and space (node or flow). Outputs are items and duplicates. History persists immediately; downstream failures do not roll it back. Increasing mode accepts finite numbers or RFC 3339 timestamps, never mixed types." : kind == "http-request" ? "Configure method, query/headers modes and names, bodyFormat, authentication, responseFormat and statusPolicy. Bind url, query.<name>/header.<name> or whole query/headers objects, body and auth.token (Basic: auth.username/auth.password). Credentials accept variables or upstream outputs only. Outputs: body, statusCode, headers. Authentication is replaced as a complete choice." : 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." : kind == "workflow" ? "Select another workflow with config.flowId. A workflow cannot call itself, including in a disconnected node. Owned unpublished or unavailable targets may be saved as incomplete drafts. Use node.refresh to load the current published interface." : kind == "agent" ? "Tools accept Connector Actions or {kind: \"workflow\", flowId, name, description, approval, inputs}. Workflow parameter sources use model, input or value. The platform derives the interface. Refresh a workflow tool with node.refresh and tool: its name." : kind == "code" ? codeGuidance : "Supply business configuration and input data. Fixed definitions are assembled by the tool. Existing constraints and defaults are preserved on partial updates.",
14437
+ guidance: kind == "webhook-response" ? "Prepare an HTTP response using fixed inputs body (any JSON, default empty text), statusCode (number, default 200) and headers (scalar-valued object, default {}). Select this node in Webhook options.responseBody as {kind: \"webhook-response\", nodeId: \"node reference\", timeoutMs: 30000}. Its first completion responds immediately while the Run continues. It has no business outputs. Multiple response nodes are allowed; each Webhook selects one reachable node." : kind == "outputs" ? "Declare output fields through config.outputDefs. Set their values through node.add.inputs or input.set. Outputs is a singleton execution sink; it waits for its predecessors and produces workflow business outputs independently of node logs. No downstream edges or data references to Outputs are allowed." : kind == "webhook" ? "Use options.responseBody: {kind: \"webhook-response\", nodeId: \"node ID or $alias\", timeoutMs: 30000} to respond on the selected node’s first completion while the Run continues. Body, statusCode and headers come exclusively from that node; clear workflow-output-only status/header references when switching. Alternatively configure options.responseBody as {kind: \"workflow-outputs\", output?: \"top-level output name\", timeoutMs?: 30000} to respond after the Run succeeds. Omit output for the complete object. Connect Webhook to Outputs. Timeout is 1000–60000 ms; HTTP timeout does not cancel the Run. Strings return text; other values return JSON. Only in this mode, options.responseStatusCodeOutput can select a numeric top-level workflow output as the HTTP status, overriding the preserved fixed responseStatusCode (default 200). Its runtime value must be an integer from 200 to 599, excluding 204, 205, 304; missing or invalid values return 500. Use responseHeaders for fixed text headers. In workflow-output mode, responseHeaderOutputs maps header names to top-level output names; values can be string, number or boolean and are converted to text. Alternatively responseHeadersSource: {kind: \"workflow-outputs\", output?: \"object field\"} replaces the entire header object (omit output for all outputs), preserving but ignoring per-header settings. Missing, null, complex or invalid header values return 500 without fallback. Header restrictions and Content-Type policy still apply. Omit responseBody for immediate responseData. Clear options.responseBody, options.responseStatusCodeOutput, options.responseHeadersSource and options.responseHeaderOutputs explicitly to switch back." : kind == "start" ? "Declare workflow inputs through config.inputDefs; read them in Start node details. REST calls and manual runs supply them as trigger.outputs. Downstream nodes bind these parameters as Start outputs. Start has no input sources or defaults; non-nullable parameters are required, and omitted nullable parameters become null." : 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 == "skip-duplicates" ? "Bind an items array. Configure fields as dot-separated identity paths; an empty list uses each scalar item. Outputs are items and duplicates. History belongs to this node and commits only when the Run completes successfully. Fields accept strings or finite numbers; missing or complex values reject the batch." : kind == "http-request" ? "Configure method, query/headers modes and names, bodyFormat, authentication, responseFormat and statusPolicy. Bind url, query.<name>/header.<name> or whole query/headers objects, body and auth.token (Basic: auth.username/auth.password). Credentials accept variables or upstream outputs only. Outputs: body, statusCode, headers. Authentication is replaced as a complete choice." : 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." : kind == "workflow" ? "Select another workflow with config.flowId. A workflow cannot call itself, including in a disconnected node. Owned unpublished or unavailable targets may be saved as incomplete drafts. Use node.refresh to load the current published interface." : kind == "agent" ? "Tools accept Connector Actions or {kind: \"workflow\", flowId, name, description, approval, inputs}. Workflow parameter sources use model, input or value. The platform derives the interface. Refresh a workflow tool with node.refresh and tool: its name." : kind == "code" ? codeGuidance : "Supply business configuration and input data. Fixed definitions are assembled by the tool. Existing constraints and defaults are preserved on partial updates.",
14425
14438
  example: {
14426
14439
  op: "node.add",
14427
14440
  as: "step",
@@ -14444,12 +14457,8 @@ function authoringSchema(kind) {
14444
14457
  }]
14445
14458
  } },
14446
14459
  "integration": { config: { key: "<Trigger key>" } },
14447
- "dedupe": {
14448
- config: {
14449
- field: "id",
14450
- mode: "new",
14451
- space: "node"
14452
- },
14460
+ "skip-duplicates": {
14461
+ config: { fields: ["id"] },
14453
14462
  inputs: { items: {
14454
14463
  kind: "value",
14455
14464
  value: [{ id: "a" }, { id: "b" }]
@@ -14714,7 +14723,7 @@ var nodeErrorSchema = {
14714
14723
  }
14715
14724
  };
14716
14725
  function supportsNodeErrorHandling(node) {
14717
- return supportsNodeRetry(node) || node.kind === "task" && "executor" in node.task && node.task.executor.kind === "dedupe";
14726
+ return supportsNodeRetry(node) || node.kind === "task" && "executor" in node.task && node.task.executor.kind === "skip-duplicates";
14718
14727
  }
14719
14728
  function nodeSystemOutputPorts(node) {
14720
14729
  return supportsNodeErrorHandling(node) && node.onError == "error" ? { error: {
@@ -16600,7 +16609,7 @@ function authoringNode(content, ref) {
16600
16609
  inputs: fieldsView([...task.inputs, ...node.kind == "task" ? node.additionalInputs ?? [] : []].filter((port) => !("handle" in port) || !llmReservedInputs.includes(port.handle)))
16601
16610
  };
16602
16611
  else if (task.executor.kind == "workflow") config = { flowId: task.executor.flowId };
16603
- else if (task.executor.kind == "http-request" || task.executor.kind == "dedupe") {
16612
+ else if (task.executor.kind == "http-request" || task.executor.kind == "skip-duplicates") {
16604
16613
  const { kind: _kind, ...settings } = task.executor;
16605
16614
  config = settings;
16606
16615
  } else if (task.executor.kind == "openapi") config = { ...openApiConfigView(task.executor) };
@@ -16990,12 +16999,12 @@ async function compileAuthoring(base, request, host) {
16990
16999
  };
16991
17000
  } else task = await connectorTask(config, String(update.name));
16992
17001
  } else if (type == "decision") task = decisionTask(config.questions, String(update.name));
16993
- else if (type == "dedupe") task = {
17002
+ else if (type == "skip-duplicates") task = {
16994
17003
  ...before,
16995
17004
  name: String(update.name),
16996
17005
  executor: {
16997
- kind: "dedupe",
16998
- ...dedupeConfigSchema.parse(config)
17006
+ kind: "skip-duplicates",
17007
+ ...skipDuplicatesConfigSchema.parse(config)
16999
17008
  }
17000
17009
  };
17001
17010
  else if (type == "http-request") {
@@ -17345,8 +17354,8 @@ async function compileAuthoring(base, request, host) {
17345
17354
  case "connector":
17346
17355
  changes = createManagedTask(identity, await connectorTask(config, name));
17347
17356
  break;
17348
- case "dedupe":
17349
- changes = createManagedTask(identity, dedupeTask(dedupeConfigSchema.parse(config), name));
17357
+ case "skip-duplicates":
17358
+ changes = createManagedTask(identity, skipDuplicatesTask(skipDuplicatesConfigSchema.parse(config), name));
17350
17359
  break;
17351
17360
  case "http-request":
17352
17361
  changes = createManagedTask(identity, httpRequestTask(httpRequestConfigSchema.parse(config), name));
@@ -17569,7 +17578,7 @@ var descriptions = {
17569
17578
  "poll": "Gmail polling by key; replace CONNECTION_ID with an active Gmail connection.",
17570
17579
  "integration": "Telegram webhook integration by key; replace CONNECTION_ID with an active Telegram connection.",
17571
17580
  "decision": "AI Decision evaluates named questions against target and returns a complete answer object per output. Configure target before running.",
17572
- "dedupe": "Filter items using persistent history. Records immediately, including when downstream work fails. Empty field uses each scalar item as identity.",
17581
+ "skip-duplicates": "Skip items already recorded by successful Runs. Configure identity fields; an empty list uses each string or numeric item. History is private to the node and only commits after Run success.",
17573
17582
  "http-request": "A single HTTP request. Bind url and request inputs; outputs are body, statusCode and headers.",
17574
17583
  "openapi": "A fixed JSON API operation. Replace the example document and URL before running.",
17575
17584
  "connector": "A Connector Task and its node. Replace ACTION_ID, CONNECTION_ID and port definitions using connector_get / connector show. Set connectionId to an empty string to defer account configuration; execution will require an account.",
@@ -17614,10 +17623,10 @@ function authoringExample(name) {
17614
17623
  instructions: "Does the customer need support?"
17615
17624
  }]);
17616
17625
  break;
17617
- case "dedupe":
17618
- operations = [...createManagedTask({ nodeId: "dedupe" }, dedupeTask()), {
17626
+ case "skip-duplicates":
17627
+ operations = [...createManagedTask({ nodeId: "skip-duplicates" }, skipDuplicatesTask()), {
17619
17628
  kind: "graph.node.input.set",
17620
- nodeId: "dedupe",
17629
+ nodeId: "skip-duplicates",
17621
17630
  handle: "items",
17622
17631
  value: {
17623
17632
  kind: "value",
@@ -17880,6 +17889,7 @@ var trigger = strictObject({
17880
17889
  outputs: record$3(string(), json)
17881
17890
  });
17882
17891
  var schemas = {
17892
+ readFlowState: stateReadSchema.extend({ version }),
17883
17893
  canvas: strictObject({
17884
17894
  command: canvasCommandSchema,
17885
17895
  version
@@ -17907,6 +17917,7 @@ var schemas = {
17907
17917
  name: flowName,
17908
17918
  teamId: id.optional(),
17909
17919
  tagIds: tagIds.optional(),
17920
+ presentation: record$3(string(), json).optional(),
17910
17921
  version
17911
17922
  }),
17912
17923
  saveTag: strictObject({
@@ -18018,6 +18029,7 @@ function decoder(schema) {
18018
18029
  return (value) => schema.parse(value);
18019
18030
  }
18020
18031
  var controlRequests = {
18032
+ readFlowState: decoder(schemas.readFlowState),
18021
18033
  canvas: decoder(schemas.canvas),
18022
18034
  authoringCheck: decoder(schemas.authoringCheck),
18023
18035
  authoringEdit: decoder(schemas.authoringEdit),
@@ -8760,23 +8760,30 @@ var httpRequestExecutorSchema = strictObject({
8760
8760
  ]).default("auto"),
8761
8761
  statusPolicy: _enum(["success", "all"]).default("success")
8762
8762
  }).extend({ kind: literal("http-request") });
8763
+ //#endregion
8764
+ //#region src/state/common/state.ts
8765
+ var stateReadLimits = {
8766
+ maxKeys: 16,
8767
+ maxBytes: 1048576
8768
+ };
8769
+ var keySchema = string().min(1).refine((value) => new TextEncoder().encode(value).length <= 256);
8770
+ strictObject({
8771
+ scope: _enum(["draft", "live"]),
8772
+ values: literal(false).optional()
8773
+ });
8763
8774
  strictObject({
8764
8775
  scope: _enum(["draft", "live"]),
8765
- values: boolean().optional()
8776
+ keys: array(keySchema).min(1).max(stateReadLimits.maxKeys).refine((keys) => new Set(keys).size === keys.length, "State keys must be distinct.")
8766
8777
  });
8767
8778
  strictObject({
8768
8779
  scope: _enum(["draft", "live"]),
8769
- key: string().min(1).refine((key) => new TextEncoder().encode(key).length <= 256).optional()
8780
+ key: keySchema.optional()
8770
8781
  });
8771
8782
  strictObject({
8772
8783
  scope: _enum(["draft", "live"]),
8773
8784
  space: string().regex(/^(flow|node:.+)$/)
8774
8785
  });
8775
- var dedupeExecutorSchema = strictObject({
8776
- field: string().default(""),
8777
- mode: _enum(["new", "increasing"]).default("new"),
8778
- space: _enum(["node", "flow"]).default("node")
8779
- }).extend({ kind: literal("dedupe") });
8786
+ var skipDuplicatesExecutorSchema = strictObject({ fields: array(string().refine((field) => field.length > 0 && field.split(".").every((part) => part.length > 0), "Use a nonempty dot-separated field path.")).refine((fields) => new Set(fields).size === fields.length, "Identity fields must be distinct.").default([]) }).extend({ kind: literal("skip-duplicates") });
8780
8787
  object({
8781
8788
  version: literal(1),
8782
8789
  scope: _enum(["draft", "live"]),
@@ -8787,24 +8794,30 @@ object({
8787
8794
  maxIdentities: number().positive(),
8788
8795
  maxRunWrites: number().positive()
8789
8796
  }),
8790
- values: array(object({
8797
+ values: array(strictObject({
8791
8798
  key: string(),
8792
8799
  size: number().nonnegative(),
8793
- updatedAt: number(),
8794
- value: json$1().optional()
8800
+ updatedAt: number()
8795
8801
  })),
8796
8802
  spaces: array(object({
8797
8803
  space: string(),
8798
- mode: _enum(["new", "increasing"]),
8799
8804
  count: number().nonnegative(),
8800
- watermark: union([
8801
- string(),
8802
- number(),
8803
- _null()
8804
- ]),
8805
+ pendingCount: number().nonnegative(),
8806
+ reservedCount: number().nonnegative(),
8805
8807
  updatedAt: number()
8806
8808
  }))
8807
8809
  });
8810
+ object({
8811
+ version: literal(1),
8812
+ scope: _enum(["draft", "live"]),
8813
+ values: array(strictObject({
8814
+ key: keySchema,
8815
+ value: json$1()
8816
+ })).min(1).max(stateReadLimits.maxKeys)
8817
+ }).refine((response) => {
8818
+ const encoder = new TextEncoder();
8819
+ return response.values.reduce((bytes, item) => bytes + (item.value === null ? 0 : encoder.encode(JSON.stringify(item.value)).byteLength), 0) <= stateReadLimits.maxBytes;
8820
+ }, "State values exceed the 1 MiB read limit.");
8808
8821
  function checkJsonDepth(value, depth = 0) {
8809
8822
  if (depth > 64) throw new TypeError("Value exceeds the maximum JSON depth.");
8810
8823
  if (value != null && typeof value == "object") for (const child of Object.values(value)) checkJsonDepth(child, depth + 1);
@@ -9101,7 +9114,7 @@ var managedFields = object({
9101
9114
  revisionId: text
9102
9115
  }),
9103
9116
  httpRequestExecutorSchema,
9104
- dedupeExecutorSchema
9117
+ skipDuplicatesExecutorSchema
9105
9118
  ])
9106
9119
  });
9107
9120
  var managed = managedFields.transform(limitDecisionTask);
@@ -9573,7 +9586,7 @@ array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, sha
9573
9586
  ...shape
9574
9587
  })])).values()])).min(1);
9575
9588
  function checkModelVersion(content) {
9576
- if (content.modelVersion < 13 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind === "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind === "dedupe")) throw new Error("Deduplication requires Flow model v13.");
9589
+ if (content.modelVersion < 13 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind === "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind === "skip-duplicates")) throw new Error("Skip Duplicates requires Flow model v13.");
9577
9590
  if (content.modelVersion < 12 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && "moduleId" in candidateNode.task && candidateNode.task.capabilities?.some((item) => item.kind == "http"))) throw new TypeError("Code HTTP access requires Flow model version 12.");
9578
9591
  if (content.modelVersion < 11 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && "executor" in candidateNode.task && candidateNode.task.executor.kind == "http-request")) throw new TypeError("HTTP Request requires Flow model version 11.");
9579
9592
  if (content.modelVersion < 11 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && ("moduleId" in candidateNode.task ? candidateNode.task.capabilities?.some((item) => item.kind == "workflow") : candidateNode.task.executor.kind == "agent" && candidateNode.task.executor.tools.some((item) => item.kind == "workflow")))) throw new TypeError("Workflow tools require Flow model version 11.");
@@ -9652,7 +9665,7 @@ function setConditionInput(node, handle, mapping) {
9652
9665
  //#endregion
9653
9666
  //#region src/flow/common/errorHandling.ts
9654
9667
  function supportsNodeErrorHandling(node) {
9655
- return supportsNodeRetry(node) || node.kind === "task" && "executor" in node.task && node.task.executor.kind === "dedupe";
9668
+ return supportsNodeRetry(node) || node.kind === "task" && "executor" in node.task && node.task.executor.kind === "skip-duplicates";
9656
9669
  }
9657
9670
  //#endregion
9658
9671
  //#region src/flow/common/change.ts
@@ -71,7 +71,7 @@ export interface ConditionNode extends GraphNodeBase {
71
71
  readonly matchMode: 'first' | 'all';
72
72
  readonly kind: 'condition';
73
73
  }
74
- export type ManagedTaskExecutor = import('./http-request.js').HttpRequestExecutor | import('./flow-state.js').DedupeExecutor | WorkflowExecutor | import('./decision.js').DecisionExecutor | import('./openapi.js').OpenApiExecutor | {
74
+ export type ManagedTaskExecutor = import('./http-request.js').HttpRequestExecutor | import('./flow-state.js').SkipDuplicatesExecutor | WorkflowExecutor | import('./decision.js').DecisionExecutor | import('./openapi.js').OpenApiExecutor | {
75
75
  readonly kind: 'connector';
76
76
  readonly action: string;
77
77
  readonly connectionId?: string;