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

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 (146) hide show
  1. package/README.md +3 -1
  2. package/dist/browser/{ContentIcon-FCpKiwjp.js → ContentIcon-VZQO8VZU.js} +9 -6
  3. package/dist/browser/{FlowCanvas-dzRBnlUT.js → FlowCanvas-BNGDMaWr.js} +75 -63
  4. package/dist/browser/{createResourceDialog-BeYDdUl-.js → createResourceDialog-BmtakfVg.js} +63 -57
  5. package/dist/browser/{dialog-ZtpsFbl4.js → dialog-BcFBfRB1.js} +126 -32
  6. package/dist/browser/{exportSvg-DqXw1yf-.js → exportSvg-CG8hEUNk.js} +2 -2
  7. package/dist/browser/{flowChanges-b_5UobFj.js → flowChanges-BGo_4Ypo.js} +6063 -11285
  8. package/dist/browser/{flowWorkspace-ItojZbO4.js → flowWorkspace-BFHGev7s.js} +1065 -2570
  9. package/dist/browser/preview.css +626 -653
  10. package/dist/browser/preview.js +1907 -9663
  11. package/dist/browser/theme.css +117 -263
  12. package/dist/browser/{tooltip-wZJRB9oP.js → tooltip-BAWSUexx.js} +2 -2
  13. package/dist/browser/{typeScriptSession-CSRwWmZm.js → typeScriptSession-CRoezJPN.js} +1 -1
  14. package/dist/browser/ui.css +464 -463
  15. package/dist/browser/ui.js +4 -3
  16. package/dist/browser/workbench.css +9891 -9897
  17. package/dist/browser/workbench.d.ts +6 -2
  18. package/dist/browser/workbench.js +838 -499
  19. package/dist/browser/{workbenchSelect-M441Lz0d.js → workbenchSelect-CjK-xdm3.js} +2 -2
  20. package/dist/command/index.js +48 -50
  21. package/dist/common/authoring.d.ts +5 -5
  22. package/dist/common/authoringExamples.d.ts +3 -2
  23. package/dist/common/authoringSchema.d.ts +26 -4
  24. package/dist/common/connector-proxy.d.ts +1 -1
  25. package/dist/common/control-api-conformance.js +352 -144
  26. package/dist/common/control-api-errors.d.ts +12 -0
  27. package/dist/common/control-api.d.ts +38 -4
  28. package/dist/common/control-api.js +373 -162
  29. package/dist/common/control-requests.d.ts +22 -3
  30. package/dist/common/control-requests.js +268 -28
  31. package/dist/common/cron-trigger.d.ts +2 -1
  32. package/dist/common/decision.d.ts +4 -4
  33. package/dist/common/decision.js +5 -2
  34. package/dist/common/engine-contract.d.ts +6 -1
  35. package/dist/common/event-source-definition.d.ts +1 -1
  36. package/dist/common/event-source-view.d.ts +22 -0
  37. package/dist/common/event-source.d.ts +1 -1
  38. package/dist/common/event-source.js +24 -65
  39. package/dist/common/event-sources.d.ts +0 -21
  40. package/dist/common/flow-authoring.js +90 -20
  41. package/dist/common/flow-change-schema.d.ts +9 -1
  42. package/dist/common/flow-change.d.ts +8 -202
  43. package/dist/common/flow-change.js +96 -24
  44. package/dist/common/flow-encoding.js +89 -21
  45. package/dist/common/flow-input-value.d.ts +1 -1
  46. package/dist/common/flow-model.d.ts +121 -0
  47. package/dist/common/flow-notifications.d.ts +1 -1
  48. package/dist/common/flow-retry.d.ts +2 -4
  49. package/dist/common/flow-semantics.js +161 -80
  50. package/dist/common/flow-state.d.ts +123 -0
  51. package/dist/common/flow-state.js +5852 -0
  52. package/dist/common/flow-workflowReferences.d.ts +8 -0
  53. package/dist/common/flowInspection.d.ts +1 -1
  54. package/dist/common/http-hosts.d.ts +6 -0
  55. package/dist/common/http-request.d.ts +13 -5
  56. package/dist/common/http-request.js +23 -5
  57. package/dist/common/integration-trigger.d.ts +2 -1
  58. package/dist/common/mcp.d.ts +96 -3
  59. package/dist/common/mcp.js +355 -142
  60. package/dist/common/openapi.d.ts +4 -4
  61. package/dist/common/openapi.js +4 -1
  62. package/dist/common/poll-trigger.d.ts +2 -1
  63. package/dist/common/run-events.js +1 -0
  64. package/dist/common/runtime-contract.d.ts +37 -1
  65. package/dist/common/runtime-contract.js +717 -72
  66. package/dist/common/runtime-nodejs-compat.d.ts +44 -0
  67. package/dist/common/runtime-nodejs-compat.js +5870 -0
  68. package/dist/common/scheduler-checkpoint.d.ts +1 -1
  69. package/dist/common/scheduler-node-execution.d.ts +2 -1
  70. package/dist/common/scheduler.d.ts +2 -2
  71. package/dist/common/scheduler.js +76 -6
  72. package/dist/common/state-conformance.d.ts +16 -0
  73. package/dist/common/tags.d.ts +4 -0
  74. package/dist/common/trigger-catalog.d.ts +1 -7
  75. package/dist/common/trigger-config-options.d.ts +1 -1
  76. package/dist/common/trigger-config.d.ts +1 -1
  77. package/dist/common/trigger-contract.d.ts +2 -1
  78. package/dist/common/trigger-localization.d.ts +8 -2
  79. package/dist/common/trigger-model.d.ts +101 -0
  80. package/dist/common/webhook-response.d.ts +1 -1
  81. package/dist/common/webhook-trigger.d.ts +3 -1
  82. package/dist/common/workflow.d.ts +3 -12
  83. package/dist/common/workflow.js +25 -23
  84. package/dist/index.d.ts +52 -14
  85. package/package.json +9 -1
  86. package/src/base/common/json.ts +1 -1
  87. package/src/connector/common/proxy.ts +1 -1
  88. package/src/control/common/api.ts +90 -16
  89. package/src/control/common/authoring.ts +6 -1
  90. package/src/control/common/authoringExamples.ts +8 -0
  91. package/src/control/common/authoringSchema.ts +26 -13
  92. package/src/control/common/authoringTools.ts +1 -1
  93. package/src/control/common/conformance.ts +1 -1
  94. package/src/control/common/connectorDecoders.ts +1 -1
  95. package/src/control/common/errors.ts +6 -0
  96. package/src/control/common/eventSources.ts +2 -29
  97. package/src/control/common/flowDecoders.ts +1 -0
  98. package/src/control/common/mcp.ts +16 -0
  99. package/src/control/common/requests.ts +10 -2
  100. package/src/control/common/tags.ts +20 -0
  101. package/src/control/common/triggerCatalog.ts +1 -8
  102. package/src/decision/common/decision.ts +15 -7
  103. package/src/event-source/common/definition.ts +1 -1
  104. package/src/event-source/common/index.ts +1 -1
  105. package/src/event-source/common/view.ts +20 -0
  106. package/src/execution/common/checkpoint.ts +1 -1
  107. package/src/execution/common/events.ts +3 -0
  108. package/src/execution/common/node-execution.ts +4 -1
  109. package/src/execution/common/scheduler.ts +3 -1
  110. package/src/flow/common/change.ts +60 -193
  111. package/src/flow/common/changeSchema.ts +39 -4
  112. package/src/flow/common/connectionUsage.ts +1 -1
  113. package/src/flow/common/errorHandling.ts +1 -1
  114. package/src/flow/common/inputValue.ts +1 -1
  115. package/src/flow/common/model.ts +130 -0
  116. package/src/flow/common/modules.ts +1 -1
  117. package/src/flow/common/portChanges.ts +1 -1
  118. package/src/flow/common/retry.ts +2 -4
  119. package/src/flow/common/semantics.ts +31 -4
  120. package/src/flow/common/webhookResponse.ts +1 -1
  121. package/src/flow/common/workflowReferences.ts +31 -0
  122. package/src/http/common/authBindings.ts +6 -9
  123. package/src/http/common/hosts.ts +13 -0
  124. package/src/http/common/httpRequest.ts +30 -15
  125. package/src/openapi/common/openapi.ts +9 -5
  126. package/src/{execution → runtime}/common/engineContract.ts +23 -15
  127. package/src/runtime/common/nodejsCompat.ts +275 -0
  128. package/src/runtime/common/nodejsGuest.generated.json +47 -0
  129. package/src/runtime/common/runtime.ts +1254 -0
  130. package/src/state/common/conformance.ts +86 -0
  131. package/src/state/common/state.ts +169 -0
  132. package/src/trigger/common/config.ts +1 -1
  133. package/src/trigger/common/configOptions.ts +1 -1
  134. package/src/trigger/common/contract.ts +2 -1
  135. package/src/trigger/common/cron.ts +2 -1
  136. package/src/trigger/common/integration.ts +2 -1
  137. package/src/trigger/common/model.ts +87 -0
  138. package/src/trigger/common/poll.ts +2 -1
  139. package/src/trigger/common/webhook.ts +3 -1
  140. package/src/trigger/providers/fieldDescriptions.ts +1 -1
  141. package/src/trigger/providers/localization.ts +9 -2
  142. package/src/trigger/providers/remote.ts +1 -1
  143. package/src/types/index.ts +55 -15
  144. package/src/workflow/common/workflow.ts +3 -44
  145. package/src/execution/common/runtime.ts +0 -563
  146. /package/src/{control → connector}/common/providerIconSprite.ts +0 -0
@@ -3973,6 +3973,9 @@ function hasRetiredRef(value) {
3973
3973
  }
3974
3974
  //#endregion
3975
3975
  //#region src/decision/common/decision.ts
3976
+ function isDecisionExecutor(executor) {
3977
+ return executor.kind === "decision";
3978
+ }
3976
3979
  var decisionLimits = {
3977
3980
  choice: 255,
3978
3981
  score: 10
@@ -3995,7 +3998,7 @@ function limitDecisionQuestions(questions) {
3995
3998
  }
3996
3999
  /** Loading an oversized task also updates its previously generated output schemas. */
3997
4000
  function limitDecisionTask(task) {
3998
- if (task.executor.kind !== "decision") return task;
4001
+ if (!isDecisionExecutor(task.executor)) return task;
3999
4002
  const original = task.executor.questions;
4000
4003
  const questions = limitDecisionQuestions(original);
4001
4004
  if (questions === original) return task;
@@ -4120,7 +4123,7 @@ function decisionTask(questions = [defaultDecisionQuestion()], name = "AI Decisi
4120
4123
  }
4121
4124
  function decisionTaskIssues(task) {
4122
4125
  task = limitDecisionTask(task);
4123
- if (task.executor.kind !== "decision") return [];
4126
+ if (!isDecisionExecutor(task.executor)) return [];
4124
4127
  const expected = decisionTask(task.executor.questions, task.name);
4125
4128
  return [...decisionQuestionIssues(task.executor.questions), ...!dequal(task.inputs, expected.inputs) || !dequal(task.outputs, expected.outputs) ? [{
4126
4129
  field: "ports",
@@ -9809,6 +9812,14 @@ function httpHeaderNameIssue(name, names) {
9809
9812
  if (names.some((candidate) => candidate.toLowerCase() === name.toLowerCase())) return "duplicate";
9810
9813
  }
9811
9814
  //#endregion
9815
+ //#region src/http/common/hosts.ts
9816
+ /** Hosts of a Code `http` Capability: lowercase DNS names or IPv4 addresses; `*.example.com` matches subdomains only. */
9817
+ var httpHostPattern = /^(?:\*\.)?(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
9818
+ /** Wildcards must name a registrable suffix, so `*.com` is rejected. */
9819
+ function isHttpHost(value) {
9820
+ return httpHostPattern.test(value) && (!value.startsWith("*.") || value.slice(2).includes("."));
9821
+ }
9822
+ //#endregion
9812
9823
  //#region src/http/common/httpRequest.ts
9813
9824
  var parameterSchema = strictObject({
9814
9825
  mode: _enum(["fields", "object"]).default("fields"),
@@ -10189,6 +10200,9 @@ function schema$1(doc, schemaValue) {
10189
10200
  ...Object.keys(defs).length ? { $defs: defs } : {}
10190
10201
  };
10191
10202
  }
10203
+ function isOpenApiExecutor(executor) {
10204
+ return executor.kind == "openapi";
10205
+ }
10192
10206
  function parameters(config) {
10193
10207
  const doc = parseOpenApi(config.document);
10194
10208
  const { item, op } = operation(doc, config.path, config.method);
@@ -10310,7 +10324,7 @@ function inlineSchema(value, index) {
10310
10324
  }
10311
10325
  /** The canvas validator and property panel share the same configuration contract. */
10312
10326
  function openApiFieldIssues(task) {
10313
- if (task.executor.kind != "openapi") return [];
10327
+ if (!isOpenApiExecutor(task.executor)) return [];
10314
10328
  const config = task.executor;
10315
10329
  let field = "sourceUrl";
10316
10330
  try {
@@ -10348,66 +10362,71 @@ function openApiFieldIssues(task) {
10348
10362
  function openApiIssues(task) {
10349
10363
  return openApiFieldIssues(task).map((issue) => issue.message);
10350
10364
  }
10351
- //#endregion
10352
- //#region src/workflow/common/workflow.ts
10353
- var portSchema = object$1({
10354
- handle: string().min(1),
10355
- jsonSchema: json$1(),
10356
- nullable: boolean(),
10357
- description: string().optional()
10365
+ strictObject({
10366
+ scope: _enum(["draft", "live"]),
10367
+ values: boolean().optional()
10358
10368
  });
10359
10369
  strictObject({
10360
- inputs: array(portSchema).nullable(),
10361
- outputs: array(portSchema).nullable()
10370
+ scope: _enum(["draft", "live"]),
10371
+ key: string().min(1).refine((key) => new TextEncoder().encode(key).length <= 256).optional()
10362
10372
  });
10363
- object$1({
10364
- version: literal(1),
10365
- flowId: string().min(1),
10366
- name: string(),
10367
- revisionId: string().min(1),
10368
- publicationId: string().min(1),
10369
- inputs: array(portSchema),
10370
- outputs: array(portSchema).nullable()
10373
+ strictObject({
10374
+ scope: _enum(["draft", "live"]),
10375
+ space: string().regex(/^(flow|node:.+)$/)
10376
+ });
10377
+ var dedupeConfigSchema = strictObject({
10378
+ field: string().default(""),
10379
+ mode: _enum(["new", "increasing"]).default("new"),
10380
+ space: _enum(["node", "flow"]).default("node")
10371
10381
  });
10382
+ var dedupeExecutorSchema = dedupeConfigSchema.extend({ kind: literal("dedupe") });
10383
+ function dedupeTask(config = dedupeConfigSchema.parse({}), name = "Remove Duplicates") {
10384
+ return {
10385
+ name,
10386
+ executor: {
10387
+ ...config,
10388
+ kind: "dedupe"
10389
+ },
10390
+ inputs: [{
10391
+ handle: "items",
10392
+ jsonSchema: { type: "array" },
10393
+ nullable: false
10394
+ }],
10395
+ outputs: ["items", "duplicates"].map((handle) => ({
10396
+ handle,
10397
+ jsonSchema: { type: "array" },
10398
+ nullable: false
10399
+ }))
10400
+ };
10401
+ }
10372
10402
  object$1({
10373
10403
  version: literal(1),
10374
- direction: _enum(["incoming", "outgoing"]),
10375
- total: int().nonnegative(),
10376
- nextOffset: int().nonnegative().optional(),
10377
- references: array(object$1({
10378
- flowId: string(),
10379
- name: string().nullable(),
10380
- available: boolean(),
10381
- draft: boolean(),
10382
- live: object$1({
10383
- publicationId: string(),
10384
- enabled: boolean()
10385
- }).nullable()
10404
+ scope: _enum(["draft", "live"]),
10405
+ limits: object$1({
10406
+ maxValueBytes: number().positive(),
10407
+ maxValues: number().int().positive(),
10408
+ maxSpaces: number().int().positive(),
10409
+ maxIdentities: number().positive(),
10410
+ maxRunWrites: number().positive()
10411
+ }),
10412
+ values: array(object$1({
10413
+ key: string(),
10414
+ size: number().nonnegative(),
10415
+ updatedAt: number(),
10416
+ value: json$1().optional()
10417
+ })),
10418
+ spaces: array(object$1({
10419
+ space: string(),
10420
+ mode: _enum(["new", "increasing"]),
10421
+ count: number().nonnegative(),
10422
+ watermark: union([
10423
+ string(),
10424
+ number(),
10425
+ _null()
10426
+ ]),
10427
+ updatedAt: number()
10386
10428
  }))
10387
10429
  });
10388
- /** Workflow declarations share discovery across authoring, admission and resource indexing. */
10389
- function nodeWorkflowReferences(node) {
10390
- if (node.kind != "task") return [];
10391
- if ("moduleId" in node.task) return (node.task.capabilities ?? []).flatMap((item, index) => item.kind == "workflow" ? [{
10392
- target: item,
10393
- path: `task/capabilities/${index}`,
10394
- tool: item.name
10395
- }] : []);
10396
- if (node.task.executor.kind == "workflow") return [{
10397
- target: {
10398
- ...node.task.executor,
10399
- inputs: node.task.inputs.filter((port) => "handle" in port),
10400
- outputs: node.task.outputs.filter((port) => "handle" in port)
10401
- },
10402
- path: "task/executor"
10403
- }];
10404
- if (node.task.executor.kind == "agent") return node.task.executor.tools.flatMap((item, index) => item.kind == "workflow" ? [{
10405
- target: item,
10406
- path: `task/executor/tools/${index}`,
10407
- tool: item.name
10408
- }] : []);
10409
- return [];
10410
- }
10411
10430
  //#endregion
10412
10431
  //#region src/flow/common/inputValue.ts
10413
10432
  /** An explicit clear suppresses the default; absent mappings still inherit it. */
@@ -10664,7 +10683,14 @@ var workflowCapabilitySchema = strictObject({
10664
10683
  inputs: array(port),
10665
10684
  outputs: array(port).nullable()
10666
10685
  });
10667
- var capability = union([connectorCapabilitySchema, workflowCapabilitySchema]);
10686
+ var capability = union([
10687
+ connectorCapabilitySchema,
10688
+ workflowCapabilitySchema,
10689
+ strictObject({
10690
+ kind: literal("http"),
10691
+ hosts: array(text.refine(isHttpHost, "Use a lowercase host name or IPv4 address, optionally prefixed by \"*.\" for subdomains.")).min(1).max(20).describe("Hosts Code may call with context.fetch. \"*.example.com\" matches subdomains only.")
10692
+ })
10693
+ ]);
10668
10694
  var inline = object$1({
10669
10695
  ...ports,
10670
10696
  name: text,
@@ -10775,7 +10801,8 @@ var managedFields = object$1({
10775
10801
  flowId: text,
10776
10802
  revisionId: text
10777
10803
  }),
10778
- httpRequestExecutorSchema
10804
+ httpRequestExecutorSchema,
10805
+ dedupeExecutorSchema
10779
10806
  ])
10780
10807
  });
10781
10808
  var managed = managedFields.transform(limitDecisionTask);
@@ -11044,7 +11071,9 @@ object$1({
11044
11071
  literal(8),
11045
11072
  literal(9),
11046
11073
  literal(10),
11047
- literal(11)
11074
+ literal(11),
11075
+ literal(12),
11076
+ literal(13)
11048
11077
  ]),
11049
11078
  document,
11050
11079
  modules: record$1(text, module)
@@ -11390,7 +11419,7 @@ var nodeErrorSchema = {
11390
11419
  }
11391
11420
  };
11392
11421
  function supportsNodeErrorHandling(node) {
11393
- return supportsNodeRetry(node);
11422
+ return supportsNodeRetry(node) || node.kind === "task" && "executor" in node.task && node.task.executor.kind === "dedupe";
11394
11423
  }
11395
11424
  function nodeSystemOutputPorts(node) {
11396
11425
  return supportsNodeErrorHandling(node) && node.onError == "error" ? { error: {
@@ -11399,13 +11428,15 @@ function nodeSystemOutputPorts(node) {
11399
11428
  } } : {};
11400
11429
  }
11401
11430
  //#endregion
11431
+ //#region src/flow/common/model.ts
11432
+ function portsByHandle(ports) {
11433
+ return Object.fromEntries(ports.flatMap((port) => "handle" in port ? [[port.handle, port]] : []));
11434
+ }
11435
+ //#endregion
11402
11436
  //#region src/flow/common/change.ts
11403
11437
  function validVariableName(value) {
11404
11438
  return value.length <= 256 && /^[A-Za-z_][A-Za-z0-9_]*$/.test(value) && value.slice(0, 3).toUpperCase() != "OO_";
11405
11439
  }
11406
- function portsByHandle(ports) {
11407
- return Object.fromEntries(ports.flatMap((port) => "handle" in port ? [[port.handle, port]] : []));
11408
- }
11409
11440
  var workflowToolNamePattern = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
11410
11441
  function workflowToolNameIssue(name, otherNames = []) {
11411
11442
  if (!workflowToolNamePattern.test(name)) return "invalid";
@@ -11421,6 +11452,8 @@ function decodeTaskCapabilities(value) {
11421
11452
  if (workflowToolNameIssue(item.name, names)) throw new TypeError("Workflow tool names must be unique provider-compatible names.");
11422
11453
  names.add(item.name);
11423
11454
  }
11455
+ const http = parsed.filter((item) => item.kind == "http");
11456
+ if (http.length > 1 || http.some((item) => new Set(item.hosts).size != item.hosts.length)) throw new TypeError("Code declares HTTP hosts once, without duplicates.");
11424
11457
  let connectorIndex = 0;
11425
11458
  return parsed.map((item) => item.kind == "connector" ? connectors[connectorIndex++] : item);
11426
11459
  }
@@ -11549,6 +11582,31 @@ function isTriggerNode(node) {
11549
11582
  ].includes(node.kind);
11550
11583
  }
11551
11584
  //#endregion
11585
+ //#region src/flow/common/workflowReferences.ts
11586
+ /** Workflow declarations share discovery across authoring, admission and resource indexing. */
11587
+ function nodeWorkflowReferences(node) {
11588
+ if (node.kind != "task") return [];
11589
+ if ("moduleId" in node.task) return (node.task.capabilities ?? []).flatMap((item, index) => item.kind == "workflow" ? [{
11590
+ target: item,
11591
+ path: `task/capabilities/${index}`,
11592
+ tool: item.name
11593
+ }] : []);
11594
+ if (node.task.executor.kind == "workflow") return [{
11595
+ target: {
11596
+ ...node.task.executor,
11597
+ inputs: node.task.inputs.filter((port) => "handle" in port),
11598
+ outputs: node.task.outputs.filter((port) => "handle" in port)
11599
+ },
11600
+ path: "task/executor"
11601
+ }];
11602
+ if (node.task.executor.kind == "agent") return node.task.executor.tools.flatMap((item, index) => item.kind == "workflow" ? [{
11603
+ target: item,
11604
+ path: `task/executor/tools/${index}`,
11605
+ tool: item.name
11606
+ }] : []);
11607
+ return [];
11608
+ }
11609
+ //#endregion
11552
11610
  //#region src/flow/common/promptTemplate.ts
11553
11611
  var promptReferencePattern = /\{\{\s*([^{}\s]+)\s*\}\}/g;
11554
11612
  function renderPrompt(template, input) {
@@ -11643,7 +11701,7 @@ function clearNodeConnections(graph, connectionId) {
11643
11701
  return [id, node];
11644
11702
  }
11645
11703
  const capabilities = node.task.capabilities?.map((capability) => {
11646
- if (capability.kind == "workflow") return capability;
11704
+ if (capability.kind == "workflow" || capability.kind == "http") return capability;
11647
11705
  if (!("mode" in capability)) {
11648
11706
  if ("action" in capability) {
11649
11707
  const { connectionId: selected, ...rest } = capability;
@@ -11888,22 +11946,25 @@ function normalizeTriggerOutputs(trigger, outputs) {
11888
11946
  return matchesTriggerOutputs(trigger, normalized) ? normalized : void 0;
11889
11947
  }
11890
11948
  //#endregion
11891
- //#region src/execution/common/engineContract.ts
11892
- var currentEngineContract = "open-flow-engine/v8";
11949
+ //#region src/runtime/common/engineContract.ts
11950
+ /** v10 adds persistent Flow State to the published v9 Node compatibility and fetch contract. */
11951
+ var currentEngineContract = "open-flow-engine/v10";
11952
+ /** The published v8 Node compatibility contract, retained for existing Publications and Runs. */
11893
11953
  var nodejsEngineContract = "open-flow-engine/v8/nodejs-compat-v1";
11894
- var currentContract = {
11954
+ var platformSource = (contract) => `export const engineContract = ${JSON.stringify(contract)}
11955
+ export function identity(value) { return value }
11956
+ `;
11957
+ var v8Contract = {
11895
11958
  workflowTools: true,
11896
11959
  httpRequests: true,
11897
11960
  waitAutoContinue: true,
11898
11961
  webhookResponses: true,
11899
11962
  platformExports: /* @__PURE__ */ new Set(["engineContract", "identity"]),
11900
11963
  platformModule: "open-flow:platform",
11901
- platformSource: `export const engineContract = ${JSON.stringify(currentEngineContract)}
11902
- export function identity(value) { return value }
11903
- `
11964
+ platformSource: platformSource("open-flow-engine/v8")
11904
11965
  };
11905
11966
  var nodejsContract = {
11906
- ...currentContract,
11967
+ ...v8Contract,
11907
11968
  builtinModules: new Set([
11908
11969
  "assert",
11909
11970
  "assert/strict",
@@ -11930,28 +11991,36 @@ var nodejsContract = {
11930
11991
  "util",
11931
11992
  "zlib"
11932
11993
  ].flatMap((name) => [name, `node:${name}`])),
11933
- platformSource: `export const engineContract = ${JSON.stringify(nodejsEngineContract)}
11934
- export function identity(value) { return value }
11935
- `
11994
+ platformSource: platformSource(nodejsEngineContract)
11995
+ };
11996
+ var v9Contract = {
11997
+ ...nodejsContract,
11998
+ codeFetch: true,
11999
+ platformSource: platformSource("open-flow-engine/v9")
12000
+ };
12001
+ var currentContract = {
12002
+ ...v9Contract,
12003
+ flowState: true,
12004
+ platformSource: platformSource(currentEngineContract)
11936
12005
  };
11937
12006
  function findEngineContract(contract) {
11938
- if (contract == "open-flow-engine/v8") return currentContract;
12007
+ if (contract == "open-flow-engine/v10") return currentContract;
12008
+ if (contract == "open-flow-engine/v9") return v9Contract;
12009
+ if (contract == "open-flow-engine/v8") return v8Contract;
11939
12010
  if (contract == "open-flow-engine/v8/nodejs-compat-v1") return nodejsContract;
11940
12011
  if (contract == "open-flow-engine/v7" || contract == "open-flow-engine/v7/nodejs-compat-v1") return {
11941
- ...contract.endsWith("/nodejs-compat-v1") ? nodejsContract : currentContract,
12012
+ ...contract.endsWith("/nodejs-compat-v1") ? nodejsContract : v8Contract,
11942
12013
  workflowTools: false,
11943
12014
  httpRequests: false,
11944
- platformSource: `export const engineContract = ${JSON.stringify(contract)}\nexport function identity(value) { return value }\n`
12015
+ platformSource: platformSource(contract)
11945
12016
  };
11946
12017
  if (contract == "open-flow-engine/v6" || contract == "open-flow-engine/v6/nodejs-compat-v1") return {
11947
- ...contract == "open-flow-engine/v6" ? currentContract : nodejsContract,
12018
+ ...contract == "open-flow-engine/v6" ? v8Contract : nodejsContract,
11948
12019
  workflowTools: false,
11949
12020
  httpRequests: false,
11950
12021
  waitAutoContinue: false,
11951
12022
  webhookResponses: false,
11952
- platformSource: `export const engineContract = ${JSON.stringify(contract)}
11953
- export function identity(value) { return value }
11954
- `
12023
+ platformSource: platformSource(contract)
11955
12024
  };
11956
12025
  }
11957
12026
  //#endregion
@@ -24938,6 +25007,16 @@ async function validateFlow(revision, engine) {
24938
25007
  message,
24939
25008
  path: `/document/graph/nodes/${nodeId}/task/executor`
24940
25009
  });
25010
+ if (task.executor.kind === "dedupe") {
25011
+ const expected = dedupeTask(task.executor);
25012
+ if (!dequal(httpPortContracts(task.inputs), httpPortContracts(expected.inputs)) || !dequal(httpPortContracts(task.outputs), httpPortContracts(expected.outputs))) checked.diagnostics.push({
25013
+ code: "dedupe.ports-invalid",
25014
+ column: 0,
25015
+ line: 1,
25016
+ message: "Deduplication ports must match the fixed contract.",
25017
+ path: `/document/graph/nodes/${nodeId}/task`
25018
+ });
25019
+ }
24941
25020
  if (task.executor.kind == "http-request") {
24942
25021
  for (const issue of httpRequestIssues(task.executor)) checked.diagnostics.push({
24943
25022
  code: "http-request.config-invalid",
@@ -25072,7 +25151,9 @@ var httpPortContracts = (ports) => ports.filter((port) => "handle" in port).map(
25072
25151
  async function prepareFlow(revision, engineContract, triggerId) {
25073
25152
  const engine = findEngineContract(engineContract);
25074
25153
  if (engine == null) return { kind: "engine-unsupported" };
25154
+ if (!engine.flowState && Object.values(revision.document.graph.nodes).some((node) => node.kind === "task" && "executor" in node.task && node.task.executor.kind === "dedupe")) return { kind: "engine-unsupported" };
25075
25155
  if (!engine.httpRequests && Object.values(revision.document.graph.nodes).some((node) => node.kind == "task" && "executor" in node.task && node.task.executor.kind == "http-request")) return { kind: "engine-unsupported" };
25156
+ if (!engine.codeFetch && Object.values(revision.document.graph.nodes).some((node) => node.kind == "task" && "moduleId" in node.task && node.task.capabilities?.some((item) => item.kind == "http"))) return { kind: "engine-unsupported" };
25076
25157
  if (!engine.workflowTools && Object.values(revision.document.graph.nodes).some((node) => nodeWorkflowReferences(node).some((ref) => ref.tool != null))) return { kind: "engine-unsupported" };
25077
25158
  if (triggerId != null) {
25078
25159
  const trigger = revision.document.graph.nodes[triggerId];
@@ -0,0 +1,123 @@
1
+ import type { JsonValue, ManagedTaskDefinitionOf } from './flow-model.js';
2
+ import { z } from 'zod';
3
+ export { stateConformanceCases, type StateConformanceHarness } from './state-conformance.js';
4
+ export type StateScope = 'draft' | 'live';
5
+ export declare const stateQuerySchema: z.ZodObject<{
6
+ scope: z.ZodEnum<{
7
+ draft: "draft";
8
+ live: "live";
9
+ }>;
10
+ values: z.ZodOptional<z.ZodBoolean>;
11
+ }, z.core.$strict>;
12
+ export declare const stateClearSchema: z.ZodObject<{
13
+ scope: z.ZodEnum<{
14
+ draft: "draft";
15
+ live: "live";
16
+ }>;
17
+ key: z.ZodOptional<z.ZodString>;
18
+ }, z.core.$strict>;
19
+ export declare const dedupeClearSchema: z.ZodObject<{
20
+ scope: z.ZodEnum<{
21
+ draft: "draft";
22
+ live: "live";
23
+ }>;
24
+ space: z.ZodString;
25
+ }, z.core.$strict>;
26
+ export type DedupeIdentity = string | number;
27
+ export declare const dedupeConfigSchema: z.ZodObject<{
28
+ field: z.ZodDefault<z.ZodString>;
29
+ mode: z.ZodDefault<z.ZodEnum<{
30
+ increasing: "increasing";
31
+ new: "new";
32
+ }>>;
33
+ space: z.ZodDefault<z.ZodEnum<{
34
+ flow: "flow";
35
+ node: "node";
36
+ }>>;
37
+ }, z.core.$strict>;
38
+ export type DedupeConfig = z.infer<typeof dedupeConfigSchema>;
39
+ export interface DedupeExecutor extends DedupeConfig {
40
+ readonly kind: 'dedupe';
41
+ }
42
+ export declare const dedupeExecutorSchema: z.ZodObject<{
43
+ field: z.ZodDefault<z.ZodString>;
44
+ mode: z.ZodDefault<z.ZodEnum<{
45
+ increasing: "increasing";
46
+ new: "new";
47
+ }>>;
48
+ space: z.ZodDefault<z.ZodEnum<{
49
+ flow: "flow";
50
+ node: "node";
51
+ }>>;
52
+ kind: z.ZodLiteral<"dedupe">;
53
+ }, z.core.$strict>;
54
+ export declare function dedupeTask(config?: DedupeConfig, name?: string): ManagedTaskDefinitionOf<DedupeExecutor>;
55
+ export declare class StateError extends Error {
56
+ readonly retryable = false;
57
+ readonly catchable: boolean;
58
+ readonly code: 'capability.invalid' | 'capability.denied' | 'dedupe.full' | 'limit-exceeded';
59
+ constructor(code: StateError['code'], message: string);
60
+ }
61
+ export declare function stateKey(key: unknown): string;
62
+ export declare function dedupeIdentities(value: unknown): DedupeIdentity[];
63
+ export declare function hashIdentities(ids: readonly DedupeIdentity[]): Promise<Uint8Array[]>;
64
+ export declare function watermarkValue(id: DedupeIdentity): number;
65
+ export declare function increasingIdentities(ids: readonly DedupeIdentity[], watermark: DedupeIdentity | null): {
66
+ inserted: boolean[];
67
+ watermark: DedupeIdentity | null;
68
+ };
69
+ export declare function itemIdentities(items: JsonValue, field: string): DedupeIdentity[];
70
+ export interface FlowStateView {
71
+ readonly version: 1;
72
+ readonly scope: StateScope;
73
+ readonly limits: {
74
+ readonly maxValueBytes: number;
75
+ readonly maxValues: number;
76
+ readonly maxSpaces: number;
77
+ readonly maxIdentities: number;
78
+ readonly maxRunWrites: number;
79
+ };
80
+ readonly values: readonly {
81
+ readonly key: string;
82
+ readonly size: number;
83
+ readonly updatedAt: number;
84
+ readonly value?: JsonValue;
85
+ }[];
86
+ readonly spaces: readonly {
87
+ readonly space: string;
88
+ readonly mode: 'new' | 'increasing';
89
+ readonly count: number;
90
+ readonly watermark: DedupeIdentity | null;
91
+ readonly updatedAt: number;
92
+ }[];
93
+ }
94
+ export declare const flowStateViewSchema: z.ZodObject<{
95
+ version: z.ZodLiteral<1>;
96
+ scope: z.ZodEnum<{
97
+ draft: "draft";
98
+ live: "live";
99
+ }>;
100
+ limits: z.ZodObject<{
101
+ maxValueBytes: z.ZodNumber;
102
+ maxValues: z.ZodNumber;
103
+ maxSpaces: z.ZodNumber;
104
+ maxIdentities: z.ZodNumber;
105
+ maxRunWrites: z.ZodNumber;
106
+ }, z.core.$strip>;
107
+ values: z.ZodArray<z.ZodObject<{
108
+ key: z.ZodString;
109
+ size: z.ZodNumber;
110
+ updatedAt: z.ZodNumber;
111
+ value: z.ZodOptional<z.ZodJSONSchema>;
112
+ }, z.core.$strip>>;
113
+ spaces: z.ZodArray<z.ZodObject<{
114
+ space: z.ZodString;
115
+ mode: z.ZodEnum<{
116
+ increasing: "increasing";
117
+ new: "new";
118
+ }>;
119
+ count: z.ZodNumber;
120
+ watermark: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodNull]>;
121
+ updatedAt: z.ZodNumber;
122
+ }, z.core.$strip>>;
123
+ }, z.core.$strip>;