@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
@@ -10,7 +10,7 @@ export declare class AuthoringError extends Error {
10
10
  }
11
11
  export declare function authoringNode(content: RevisionContent, ref: string): {
12
12
  ref: string;
13
- type: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "dedupe" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow";
13
+ 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";
14
14
  name: string;
15
15
  readOnly: boolean;
16
16
  description?: string | undefined;
@@ -98,7 +98,7 @@ export declare function readAuthoring(content: RevisionContent, query?: Authorin
98
98
  text?: undefined;
99
99
  nodes: {
100
100
  ref: string;
101
- type: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "dedupe" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow";
101
+ 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";
102
102
  name: string;
103
103
  readOnly: boolean;
104
104
  description?: string | undefined;
@@ -174,7 +174,7 @@ export declare function readAuthoring(content: RevisionContent, query?: Authorin
174
174
  text?: undefined;
175
175
  nodes: {
176
176
  ref: string;
177
- type: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "dedupe" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow";
177
+ 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";
178
178
  name: string;
179
179
  readOnly: boolean;
180
180
  inputHandles: string[];
@@ -8,7 +8,7 @@ declare const descriptions: {
8
8
  readonly poll: 'Gmail polling by key; replace CONNECTION_ID with an active Gmail connection.';
9
9
  readonly integration: 'Telegram webhook integration by key; replace CONNECTION_ID with an active Telegram connection.';
10
10
  readonly decision: 'AI Decision evaluates named questions against target and returns a complete answer object per output. Configure target before running.';
11
- readonly dedupe: 'Filter items using persistent history. Records immediately, including when downstream work fails. Empty field uses each scalar item as identity.';
11
+ readonly '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.';
12
12
  readonly 'http-request': 'A single HTTP request. Bind url and request inputs; outputs are body, statusCode and headers.';
13
13
  readonly openapi: 'A fixed JSON API operation. Replace the example document and URL before running.';
14
14
  readonly 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.';
@@ -24,8 +24,8 @@ declare const descriptions: {
24
24
  };
25
25
  export declare const authoringExampleNames: (keyof typeof descriptions)[];
26
26
  export declare const authoringExamples: {
27
- name: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "dedupe" | "error" | "http-request" | "integration" | "llm-chat" | "llm-json" | "openapi" | "poll" | "poll-notification" | "start" | "value" | "wait" | "webhook" | "webhook-response";
28
- description: "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." | "A Flow Error node. Select upstream Flows, then publish and enable this Flow to listen for failures in their automatic runs." | "A JavaScript module and its node. Use Code for custom computation; use Connector Tasks for existing actions." | "A Start node with a required message parameter. Supply it through trigger.outputs." | "A Wait with a continue action and a built-in notification output." | "A Webhook start node." | "A condition with true and false execution branches." | "A fixed JSON API operation. Replace the example document and URL before running." | "A fixed value node." | "A single HTTP request. Bind url and request inputs; outputs are body, statusCode and headers." | "AI Decision evaluates named questions against target and returns a complete answer object per output. Configure target before running." | "An Agent with code computation enabled. Configure a model available in the deployment." | "An Approval with approve and reject decision branches and a built-in notification output." | "An HTTP response node with body, statusCode and headers inputs. Select it from a reachable Webhook." | "An LLM JSON Task and its node; configure a model available in the deployment." | "An LLM chat Task and its node; configure a model available in the deployment." | "An hourly scheduled start node." | "Filter items using persistent history. Records immediately, including when downstream work fails. Empty field uses each scalar item as identity." | "Gmail events → JavaScript text formatting → Connector notification. Replace connection/action IDs and match the notification input ports." | "Gmail polling by key; replace CONNECTION_ID with an active Gmail connection." | "Telegram webhook integration by key; replace CONNECTION_ID with an active Telegram connection.";
27
+ name: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "error" | "http-request" | "integration" | "llm-chat" | "llm-json" | "openapi" | "poll" | "poll-notification" | "skip-duplicates" | "start" | "value" | "wait" | "webhook" | "webhook-response";
28
+ description: "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." | "A Flow Error node. Select upstream Flows, then publish and enable this Flow to listen for failures in their automatic runs." | "A JavaScript module and its node. Use Code for custom computation; use Connector Tasks for existing actions." | "A Start node with a required message parameter. Supply it through trigger.outputs." | "A Wait with a continue action and a built-in notification output." | "A Webhook start node." | "A condition with true and false execution branches." | "A fixed JSON API operation. Replace the example document and URL before running." | "A fixed value node." | "A single HTTP request. Bind url and request inputs; outputs are body, statusCode and headers." | "AI Decision evaluates named questions against target and returns a complete answer object per output. Configure target before running." | "An Agent with code computation enabled. Configure a model available in the deployment." | "An Approval with approve and reject decision branches and a built-in notification output." | "An HTTP response node with body, statusCode and headers inputs. Select it from a reachable Webhook." | "An LLM JSON Task and its node; configure a model available in the deployment." | "An LLM chat Task and its node; configure a model available in the deployment." | "An hourly scheduled start node." | "Gmail events → JavaScript text formatting → Connector notification. Replace connection/action IDs and match the notification input ports." | "Gmail polling by key; replace CONNECTION_ID with an active Gmail connection." | "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." | "Telegram webhook integration by key; replace CONNECTION_ID with an active Telegram connection.";
29
29
  }[];
30
30
  export declare function authoringExample(name: string): {
31
31
  version: 1;
@@ -1,6 +1,6 @@
1
1
  import type { JsonValue } from '../index.js';
2
2
  import { z } from 'zod';
3
- export declare const authoringTypes: readonly ['start', 'outputs', 'webhook-response', 'workflow', 'webhook', 'cron', 'error', 'poll', 'integration', 'code', 'connector', 'agent', 'llm', 'decision', 'openapi', 'http-request', 'dedupe', 'condition', 'value', 'wait', 'approval'];
3
+ export declare const authoringTypes: readonly ['start', 'outputs', 'webhook-response', 'workflow', 'webhook', 'cron', 'error', 'poll', 'integration', 'code', 'connector', 'agent', 'llm', 'decision', 'openapi', 'http-request', 'skip-duplicates', 'condition', 'value', 'wait', 'approval'];
4
4
  declare const type: z.ZodEnum<{
5
5
  agent: "agent";
6
6
  approval: "approval";
@@ -9,7 +9,6 @@ declare const type: z.ZodEnum<{
9
9
  connector: "connector";
10
10
  cron: "cron";
11
11
  decision: "decision";
12
- dedupe: "dedupe";
13
12
  error: "error";
14
13
  "http-request": "http-request";
15
14
  integration: "integration";
@@ -17,6 +16,7 @@ declare const type: z.ZodEnum<{
17
16
  openapi: "openapi";
18
17
  outputs: "outputs";
19
18
  poll: "poll";
19
+ "skip-duplicates": "skip-duplicates";
20
20
  start: "start";
21
21
  value: "value";
22
22
  wait: "wait";
@@ -304,16 +304,8 @@ export declare const authoringConfigurations: {
304
304
  success: "success";
305
305
  }>>;
306
306
  }, z.core.$strict>;
307
- dedupe: z.ZodObject<{
308
- field: z.ZodDefault<z.ZodString>;
309
- mode: z.ZodDefault<z.ZodEnum<{
310
- increasing: "increasing";
311
- new: "new";
312
- }>>;
313
- space: z.ZodDefault<z.ZodEnum<{
314
- flow: "flow";
315
- node: "node";
316
- }>>;
307
+ 'skip-duplicates': z.ZodObject<{
308
+ fields: z.ZodDefault<z.ZodArray<z.ZodString>>;
317
309
  }, z.core.$strict>;
318
310
  agent: z.ZodObject<{
319
311
  code: z.ZodOptional<z.ZodBoolean>;
@@ -709,7 +701,6 @@ export declare const authoringEditSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
709
701
  connector: "connector";
710
702
  cron: "cron";
711
703
  decision: "decision";
712
- dedupe: "dedupe";
713
704
  error: "error";
714
705
  "http-request": "http-request";
715
706
  integration: "integration";
@@ -717,6 +708,7 @@ export declare const authoringEditSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
717
708
  openapi: "openapi";
718
709
  outputs: "outputs";
719
710
  poll: "poll";
711
+ "skip-duplicates": "skip-duplicates";
720
712
  start: "start";
721
713
  value: "value";
722
714
  wait: "wait";
@@ -881,7 +873,6 @@ export declare const authoringRequestSchema: z.ZodObject<{
881
873
  connector: "connector";
882
874
  cron: "cron";
883
875
  decision: "decision";
884
- dedupe: "dedupe";
885
876
  error: "error";
886
877
  "http-request": "http-request";
887
878
  integration: "integration";
@@ -889,6 +880,7 @@ export declare const authoringRequestSchema: z.ZodObject<{
889
880
  openapi: "openapi";
890
881
  outputs: "outputs";
891
882
  poll: "poll";
883
+ "skip-duplicates": "skip-duplicates";
892
884
  start: "start";
893
885
  value: "value";
894
886
  wait: "wait";
@@ -1067,7 +1059,6 @@ export declare const authoringSearchSchema: z.ZodObject<{
1067
1059
  connector: "connector";
1068
1060
  cron: "cron";
1069
1061
  decision: "decision";
1070
- dedupe: "dedupe";
1071
1062
  error: "error";
1072
1063
  "http-request": "http-request";
1073
1064
  integration: "integration";
@@ -1075,6 +1066,7 @@ export declare const authoringSearchSchema: z.ZodObject<{
1075
1066
  openapi: "openapi";
1076
1067
  outputs: "outputs";
1077
1068
  poll: "poll";
1069
+ "skip-duplicates": "skip-duplicates";
1078
1070
  start: "start";
1079
1071
  value: "value";
1080
1072
  wait: "wait";
@@ -1099,7 +1091,6 @@ export declare const authoringSchemaQuery: z.ZodObject<{
1099
1091
  connector: "connector";
1100
1092
  cron: "cron";
1101
1093
  decision: "decision";
1102
- dedupe: "dedupe";
1103
1094
  error: "error";
1104
1095
  "http-request": "http-request";
1105
1096
  integration: "integration";
@@ -1107,6 +1098,7 @@ export declare const authoringSchemaQuery: z.ZodObject<{
1107
1098
  openapi: "openapi";
1108
1099
  outputs: "outputs";
1109
1100
  poll: "poll";
1101
+ "skip-duplicates": "skip-duplicates";
1110
1102
  start: "start";
1111
1103
  value: "value";
1112
1104
  wait: "wait";
@@ -1132,7 +1124,6 @@ export declare function authoringRequestContract(name: string): {
1132
1124
  connector: "connector";
1133
1125
  cron: "cron";
1134
1126
  decision: "decision";
1135
- dedupe: "dedupe";
1136
1127
  error: "error";
1137
1128
  "http-request": "http-request";
1138
1129
  integration: "integration";
@@ -1140,6 +1131,7 @@ export declare function authoringRequestContract(name: string): {
1140
1131
  openapi: "openapi";
1141
1132
  outputs: "outputs";
1142
1133
  poll: "poll";
1134
+ "skip-duplicates": "skip-duplicates";
1143
1135
  start: "start";
1144
1136
  value: "value";
1145
1137
  wait: "wait";
@@ -1315,7 +1307,6 @@ export declare function authoringRequestContract(name: string): {
1315
1307
  connector: "connector";
1316
1308
  cron: "cron";
1317
1309
  decision: "decision";
1318
- dedupe: "dedupe";
1319
1310
  error: "error";
1320
1311
  "http-request": "http-request";
1321
1312
  integration: "integration";
@@ -1323,6 +1314,7 @@ export declare function authoringRequestContract(name: string): {
1323
1314
  openapi: "openapi";
1324
1315
  outputs: "outputs";
1325
1316
  poll: "poll";
1317
+ "skip-duplicates": "skip-duplicates";
1326
1318
  start: "start";
1327
1319
  value: "value";
1328
1320
  wait: "wait";
@@ -1416,7 +1408,7 @@ export declare function authoringRequestContract(name: string): {
1416
1408
  } | undefined;
1417
1409
  export declare function authoringSchema(kind?: AuthoringType): {
1418
1410
  type?: undefined;
1419
- types: readonly ["start", "outputs", "webhook-response", "workflow", "webhook", "cron", "error", "poll", "integration", "code", "connector", "agent", "llm", "decision", "openapi", "http-request", "dedupe", "condition", "value", "wait", "approval"];
1411
+ types: readonly ["start", "outputs", "webhook-response", "workflow", "webhook", "cron", "error", "poll", "integration", "code", "connector", "agent", "llm", "decision", "openapi", "http-request", "skip-duplicates", "condition", "value", "wait", "approval"];
1420
1412
  request: z.core.ZodStandardJSONSchemaPayload<z.ZodObject<{
1421
1413
  baseRevision: z.ZodString;
1422
1414
  requestId: z.ZodString;
@@ -1431,7 +1423,6 @@ export declare function authoringSchema(kind?: AuthoringType): {
1431
1423
  connector: "connector";
1432
1424
  cron: "cron";
1433
1425
  decision: "decision";
1434
- dedupe: "dedupe";
1435
1426
  error: "error";
1436
1427
  "http-request": "http-request";
1437
1428
  integration: "integration";
@@ -1439,6 +1430,7 @@ export declare function authoringSchema(kind?: AuthoringType): {
1439
1430
  openapi: "openapi";
1440
1431
  outputs: "outputs";
1441
1432
  poll: "poll";
1433
+ "skip-duplicates": "skip-duplicates";
1442
1434
  start: "start";
1443
1435
  value: "value";
1444
1436
  wait: "wait";
@@ -1601,7 +1593,7 @@ export declare function authoringSchema(kind?: AuthoringType): {
1601
1593
  } | {
1602
1594
  types?: undefined;
1603
1595
  request?: undefined;
1604
- type: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "dedupe" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow";
1596
+ 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";
1605
1597
  onError: boolean | {
1606
1598
  enum: string[];
1607
1599
  };
@@ -1615,7 +1607,7 @@ export declare function authoringSchema(kind?: AuthoringType): {
1615
1607
  example: {
1616
1608
  op: string;
1617
1609
  as: string;
1618
- type: "agent" | "approval" | "code" | "condition" | "connector" | "cron" | "decision" | "dedupe" | "error" | "http-request" | "integration" | "llm" | "openapi" | "outputs" | "poll" | "start" | "value" | "wait" | "webhook" | "webhook-response" | "workflow";
1610
+ 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";
1619
1611
  name: string;
1620
1612
  };
1621
1613
  configuration: z.core.ZodStandardJSONSchemaPayload<z.ZodObject<{}, z.core.$strict>>;
@@ -8628,24 +8628,31 @@ var httpRequestConfigSchema = strictObject({
8628
8628
  statusPolicy: _enum(["success", "all"]).default("success")
8629
8629
  });
8630
8630
  var httpRequestExecutorSchema = httpRequestConfigSchema.extend({ kind: literal("http-request") });
8631
+ //#endregion
8632
+ //#region src/state/common/state.ts
8633
+ var stateReadLimits = {
8634
+ maxKeys: 16,
8635
+ maxBytes: 1048576
8636
+ };
8637
+ var keySchema = string$1().min(1).refine((value) => new TextEncoder().encode(value).length <= 256);
8631
8638
  strictObject({
8632
8639
  scope: _enum(["draft", "live"]),
8633
- values: boolean().optional()
8640
+ values: literal(false).optional()
8634
8641
  });
8635
8642
  strictObject({
8636
8643
  scope: _enum(["draft", "live"]),
8637
- key: string$1().min(1).refine((key) => new TextEncoder().encode(key).length <= 256).optional()
8644
+ keys: array(keySchema).min(1).max(stateReadLimits.maxKeys).refine((keys) => new Set(keys).size === keys.length, "State keys must be distinct.")
8638
8645
  });
8639
8646
  strictObject({
8640
8647
  scope: _enum(["draft", "live"]),
8641
- space: string$1().regex(/^(flow|node:.+)$/)
8648
+ key: keySchema.optional()
8642
8649
  });
8643
- var dedupeConfigSchema = strictObject({
8644
- field: string$1().default(""),
8645
- mode: _enum(["new", "increasing"]).default("new"),
8646
- space: _enum(["node", "flow"]).default("node")
8650
+ strictObject({
8651
+ scope: _enum(["draft", "live"]),
8652
+ space: string$1().regex(/^(flow|node:.+)$/)
8647
8653
  });
8648
- var dedupeExecutorSchema = dedupeConfigSchema.extend({ kind: literal("dedupe") });
8654
+ 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([]) });
8655
+ var skipDuplicatesExecutorSchema = skipDuplicatesConfigSchema.extend({ kind: literal("skip-duplicates") });
8649
8656
  var flowStateViewSchema = object({
8650
8657
  version: literal(1),
8651
8658
  scope: _enum(["draft", "live"]),
@@ -8656,24 +8663,30 @@ var flowStateViewSchema = object({
8656
8663
  maxIdentities: number().positive(),
8657
8664
  maxRunWrites: number().positive()
8658
8665
  }),
8659
- values: array(object({
8666
+ values: array(strictObject({
8660
8667
  key: string$1(),
8661
8668
  size: number().nonnegative(),
8662
- updatedAt: number(),
8663
- value: json$4().optional()
8669
+ updatedAt: number()
8664
8670
  })),
8665
8671
  spaces: array(object({
8666
8672
  space: string$1(),
8667
- mode: _enum(["new", "increasing"]),
8668
8673
  count: number().nonnegative(),
8669
- watermark: union([
8670
- string$1(),
8671
- number(),
8672
- _null()
8673
- ]),
8674
+ pendingCount: number().nonnegative(),
8675
+ reservedCount: number().nonnegative(),
8674
8676
  updatedAt: number()
8675
8677
  }))
8676
8678
  });
8679
+ var flowStateValuesSchema = object({
8680
+ version: literal(1),
8681
+ scope: _enum(["draft", "live"]),
8682
+ values: array(strictObject({
8683
+ key: keySchema,
8684
+ value: json$4()
8685
+ })).min(1).max(stateReadLimits.maxKeys)
8686
+ }).refine((response) => {
8687
+ const encoder = new TextEncoder();
8688
+ return response.values.reduce((bytes, item) => bytes + (item.value === null ? 0 : encoder.encode(JSON.stringify(item.value)).byteLength), 0) <= stateReadLimits.maxBytes;
8689
+ }, "State values exceed the 1 MiB read limit.");
8677
8690
  function checkJsonDepth(value, depth = 0) {
8678
8691
  if (depth > 64) throw new TypeError("Value exceeds the maximum JSON depth.");
8679
8692
  if (value != null && typeof value == "object") for (const child of Object.values(value)) checkJsonDepth(child, depth + 1);
@@ -8963,7 +8976,7 @@ var managedFields = object({
8963
8976
  revisionId: text
8964
8977
  }),
8965
8978
  httpRequestExecutorSchema,
8966
- dedupeExecutorSchema
8979
+ skipDuplicatesExecutorSchema
8967
8980
  ])
8968
8981
  });
8969
8982
  var managed = managedFields.transform(limitDecisionTask);
@@ -9435,7 +9448,7 @@ array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, sha
9435
9448
  ...shape
9436
9449
  })])).values()])).min(1);
9437
9450
  function checkModelVersion(content) {
9438
- 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.");
9451
+ 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.");
9439
9452
  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.");
9440
9453
  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.");
9441
9454
  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.");
@@ -9649,7 +9662,7 @@ var type = _enum([
9649
9662
  "decision",
9650
9663
  "openapi",
9651
9664
  "http-request",
9652
- "dedupe",
9665
+ "skip-duplicates",
9653
9666
  "condition",
9654
9667
  "value",
9655
9668
  "wait",
@@ -9780,7 +9793,7 @@ var authoringConfigurations = {
9780
9793
  "connector": authoringDefinitionSchemas.connector.omit({ outputMode: true }).strict(),
9781
9794
  "openapi": authoringOpenApiSchema,
9782
9795
  "http-request": httpRequestConfigSchema,
9783
- "dedupe": dedupeConfigSchema,
9796
+ "skip-duplicates": skipDuplicatesConfigSchema,
9784
9797
  "agent": authoringDefinitionSchemas.agent.omit({
9785
9798
  prompt: true,
9786
9799
  tools: true
@@ -11866,7 +11879,7 @@ function decodeRunEvent(value) {
11866
11879
  switch (kind) {
11867
11880
  case "node.started": {
11868
11881
  const nodeKind = payload.nodeKind;
11869
- 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();
11882
+ 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();
11870
11883
  return {
11871
11884
  ...base,
11872
11885
  kind,
@@ -12091,12 +12104,13 @@ var ControlClient = class {
12091
12104
  })
12092
12105
  }));
12093
12106
  }
12094
- async createFlow(name, idempotencyKey = `flow-${randomId()}`, teamId, tagIds) {
12107
+ async createFlow(name, idempotencyKey = `flow-${randomId()}`, teamId, tagIds, initialPresentation) {
12095
12108
  return flow(await this.request("/v1/flows", {
12096
12109
  body: JSON.stringify({
12097
12110
  name,
12098
12111
  ...teamId == null ? {} : { teamId },
12099
12112
  ...tagIds == null ? {} : { tagIds },
12113
+ ...initialPresentation == null ? {} : { presentation: initialPresentation },
12100
12114
  version: 1
12101
12115
  }),
12102
12116
  headers: { "idempotency-key": idempotencyKey },
@@ -12178,10 +12192,22 @@ var ControlClient = class {
12178
12192
  })
12179
12193
  }));
12180
12194
  }
12181
- async getFlowState(flowId, scope, values = false) {
12182
- const result = flowStateViewSchema.safeParse(await this.request(`/v1/flows/${segment(flowId)}/state?scope=${scope}&values=${values}`));
12195
+ async getFlowState(flowId, scope) {
12196
+ const result = flowStateViewSchema.safeParse(await this.request(`/v1/flows/${segment(flowId)}/state?scope=${scope}`));
12183
12197
  return result.success && result.data.scope === scope ? result.data : invalidResponse();
12184
12198
  }
12199
+ async getFlowStateValues(flowId, scope, keys, signal) {
12200
+ const result = flowStateValuesSchema.safeParse(await this.request(`/v1/flows/${segment(flowId)}/state/read`, {
12201
+ method: "POST",
12202
+ body: JSON.stringify({
12203
+ version: 1,
12204
+ scope,
12205
+ keys
12206
+ }),
12207
+ signal
12208
+ }));
12209
+ 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();
12210
+ }
12185
12211
  async clearFlowState(flowId, scope, key) {
12186
12212
  const source = record$1(await this.request(`/v1/flows/${segment(flowId)}/state?scope=${scope}${key == null ? "" : `&key=${encodeURIComponent(key)}`}`, { method: "DELETE" }));
12187
12213
  if (source.version !== 1 || source.cleared !== true) invalidResponse();
@@ -12873,6 +12899,46 @@ function liveRunRequest(harness, publicationId, key) {
12873
12899
  });
12874
12900
  }
12875
12901
  var controlApiConformanceCases = [
12902
+ {
12903
+ name: "reads State metadata and bounded explicit keys without scope-wide value retrieval",
12904
+ async verify(harness) {
12905
+ const api = new ControlClient((url, init) => harness.request(new Request(new URL(url, harness.origin), init)));
12906
+ const flow = await api.createFlow("State reads");
12907
+ equal((await api.getFlowState(flow.flowId, "draft")).values, [], "New Flow State metadata");
12908
+ equal(await api.getFlowStateValues(flow.flowId, "live", ["second", "first"]), {
12909
+ version: 1,
12910
+ scope: "live",
12911
+ values: [{
12912
+ key: "second",
12913
+ value: null
12914
+ }, {
12915
+ key: "first",
12916
+ value: null
12917
+ }]
12918
+ }, "Missing named State keys");
12919
+ const metadata = await request(harness, `/v1/flows/${flow.flowId}/state?scope=draft&values=false`);
12920
+ await json(metadata, 200, "Legacy metadata-only query");
12921
+ equal(metadata.headers.get("cache-control"), "no-store", "State metadata cache policy");
12922
+ await error(await request(harness, `/v1/flows/${flow.flowId}/state?scope=draft&values=true`), 400, "flow.invalid", "Scope-wide State values");
12923
+ for (const input of [
12924
+ {
12925
+ scope: "draft",
12926
+ keys: []
12927
+ },
12928
+ { keys: ["key"] },
12929
+ {
12930
+ scope: "draft",
12931
+ keys: Array.from({ length: 17 }, (_, index) => String(index))
12932
+ }
12933
+ ]) await error(await request(harness, `/v1/flows/${flow.flowId}/state/read`, {
12934
+ method: "POST",
12935
+ body: JSON.stringify({
12936
+ version: 1,
12937
+ ...input
12938
+ })
12939
+ }), 400, "flow.invalid", "Invalid named State read");
12940
+ }
12941
+ },
12876
12942
  {
12877
12943
  name: "imports workflow files atomically and exports a new unpublished draft with its Presentation",
12878
12944
  async verify(harness) {
@@ -1,5 +1,5 @@
1
1
  import type { CanvasCommand } from './canvas-commands.js';
2
- import type { FlowStateView, StateScope } from './flow-state.js';
2
+ import type { FlowStateValues, FlowStateView, StateScope } from './flow-state.js';
3
3
  export type { CanvasCommand, CanvasCommandSubscriber } from './canvas-commands.js';
4
4
  import type { LiveDetails } from './liveDetails.js';
5
5
  export { liveEntries } from './liveDetails.js';
@@ -101,6 +101,10 @@ export interface PublicationPresentation {
101
101
  readonly version: 1;
102
102
  readonly presentation: Presentation | null;
103
103
  }
104
+ export interface FlowCreationOptions {
105
+ readonly tagIds?: readonly string[];
106
+ readonly presentation?: Readonly<Record<string, JsonValue>>;
107
+ }
104
108
  export interface Presentation {
105
109
  readonly revision: number;
106
110
  readonly updatedAt: string;
@@ -830,7 +834,7 @@ export declare class ControlClient {
830
834
  readonly idempotencyKey?: string;
831
835
  readonly tagIds?: readonly string[];
832
836
  }): Promise<Flow>;
833
- createFlow(name: string, idempotencyKey?: string, teamId?: string, tagIds?: readonly string[]): Promise<Flow>;
837
+ createFlow(name: string, idempotencyKey?: string, teamId?: string, tagIds?: readonly string[], initialPresentation?: Readonly<Record<string, JsonValue>>): Promise<Flow>;
834
838
  broadcastCanvas(flowId: string, command: CanvasCommand): Promise<CanvasBroadcast>;
835
839
  getFlow(flowId: string): Promise<Flow>;
836
840
  getErrorListeners(flowId: string, signal?: AbortSignal): Promise<readonly ErrorListener[]>;
@@ -843,7 +847,8 @@ export declare class ControlClient {
843
847
  deleteTag(tagId: string): Promise<void>;
844
848
  setFlowTags(flowId: string, tagIds: readonly string[]): Promise<Flow>;
845
849
  updateFlow(flowId: string, changes: FlowUpdate): Promise<Flow>;
846
- getFlowState(flowId: string, scope: StateScope, values?: boolean): Promise<FlowStateView>;
850
+ getFlowState(flowId: string, scope: StateScope): Promise<FlowStateView>;
851
+ getFlowStateValues(flowId: string, scope: StateScope, keys: readonly string[], signal?: AbortSignal): Promise<FlowStateValues>;
847
852
  clearFlowState(flowId: string, scope: StateScope, key?: string): Promise<void>;
848
853
  clearFlowDedupe(flowId: string, scope: StateScope, space: string): Promise<void>;
849
854
  renameFlow(flowId: string, name: string): Promise<Flow>;