@oomol-lab/open-flow 0.1.0-beta.69 → 0.1.0-beta.70

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 (49) hide show
  1. package/dist/browser/{ContentIcon-CsECY5id.js → ContentIcon-CUQHjQIw.js} +16 -8
  2. package/dist/browser/{FlowCanvas-C5X22xQ7.js → FlowCanvas-CqtUDPGj.js} +11 -26
  3. package/dist/browser/{createResourceDialog-Di5BBrQv.js → createResourceDialog-BAHYW9yu.js} +3 -3
  4. package/dist/browser/{dialog-Bjo-r9B0.js → dialog-DcGOzUP2.js} +162 -12
  5. package/dist/browser/{exportSvg-Cj6Spxx-.js → exportSvg-Dv5Qgrq7.js} +2 -2
  6. package/dist/browser/flow-authoring.js +95 -12
  7. package/dist/browser/flow-change-schema.d.ts +24 -1
  8. package/dist/browser/flow-change.d.ts +33 -4
  9. package/dist/browser/flow-change.js +96 -13
  10. package/dist/browser/{flowChanges-Dp-rcEJ6.js → flowChanges-CYyehKer.js} +2593 -2254
  11. package/dist/browser/{flowWorkspace-CB1QACku.js → flowWorkspace-qYUZPJHR.js} +1114 -392
  12. package/dist/browser/preview.css +225 -221
  13. package/dist/browser/preview.js +3781 -2655
  14. package/dist/browser/{tooltip-CJjYs_2I.js → tooltip-wZJRB9oP.js} +28 -1
  15. package/dist/browser/ui.css +8 -20
  16. package/dist/browser/workbench.css +225 -221
  17. package/dist/browser/workbench.js +31 -10
  18. package/dist/browser/{workbenchSelect-C3hxUcYm.js → workbenchSelect-D8_vP2p5.js} +2 -2
  19. package/dist/command/index.js +45 -45
  20. package/dist/common/authoring.d.ts +3 -3
  21. package/dist/common/authoringExamples.d.ts +3 -2
  22. package/dist/common/authoringSchema.d.ts +37 -374
  23. package/dist/common/control-api-conformance.js +151 -55
  24. package/dist/common/control-api.d.ts +12 -78
  25. package/dist/common/control-api.js +162 -39
  26. package/dist/common/control-requests.d.ts +3 -3
  27. package/dist/common/control-requests.js +221 -35
  28. package/dist/common/decision.js +85 -7
  29. package/dist/common/engine-contract.d.ts +4 -2
  30. package/dist/common/flow-encoding.js +110 -14
  31. package/dist/common/flow-graph.d.ts +3 -0
  32. package/dist/common/flow-semantics.js +273 -14
  33. package/dist/common/integration-trigger.js +85 -7
  34. package/dist/common/liveDetails.d.ts +15 -0
  35. package/dist/common/mcp.d.ts +3 -3
  36. package/dist/common/mcp.js +134 -38
  37. package/dist/common/openapi.js +85 -7
  38. package/dist/common/poll-trigger.js +85 -7
  39. package/dist/common/run-events.d.ts +2 -0
  40. package/dist/common/run-events.js +59 -2
  41. package/dist/common/runtime-contract.js +14 -4
  42. package/dist/common/scheduler.d.ts +6 -2
  43. package/dist/common/scheduler.js +178 -11
  44. package/dist/common/webhook-response.d.ts +43 -0
  45. package/dist/common/webhook-trigger.d.ts +12 -0
  46. package/dist/common/webhook-trigger.js +236 -9
  47. package/dist/common/workflow.js +85 -7
  48. package/package.json +1 -1
  49. package/skills/open-flow/references/flow-authoring.md +15 -10
@@ -23,7 +23,7 @@ function dequal(foo, bar) {
23
23
  }
24
24
  //#endregion
25
25
  //#region src/execution/common/engineContract.ts
26
- var currentEngineContract = "open-flow-engine/v6";
26
+ var currentEngineContract = "open-flow-engine/v7";
27
27
  `${JSON.stringify(currentEngineContract)}`, new Set([
28
28
  "assert",
29
29
  "assert/strict",
@@ -49,7 +49,7 @@ var currentEngineContract = "open-flow-engine/v6";
49
49
  "url",
50
50
  "util",
51
51
  "zlib"
52
- ].flatMap((name) => [name, `node:${name}`])), `${JSON.stringify("open-flow-engine/v6/nodejs-compat-v1")}`;
52
+ ].flatMap((name) => [name, `node:${name}`])), `${JSON.stringify("open-flow-engine/v7/nodejs-compat-v1")}`;
53
53
  //#endregion
54
54
  //#region src/openapi/common/authBindings.ts
55
55
  /** Never allow credentials to enter a Revision as literal node inputs. */
@@ -1081,7 +1081,7 @@ function timeSource(args) {
1081
1081
  function time(args) {
1082
1082
  return new RegExp(`^${timeSource(args)}$`);
1083
1083
  }
1084
- function datetime(args) {
1084
+ function datetime$1(args) {
1085
1085
  const opts = ["Z"];
1086
1086
  if (args.offset) opts.push(`([+-](?:[01]\\d|2[0-3]):[0-5]\\d)`);
1087
1087
  const qualified = `${timeSource({
@@ -1732,7 +1732,7 @@ var $ZodKSUID = /*@__PURE__*/ $constructor("$ZodKSUID", (inst, def) => {
1732
1732
  $ZodStringFormat.init(inst, def);
1733
1733
  });
1734
1734
  var $ZodISODateTime = /*@__PURE__*/ $constructor("$ZodISODateTime", (inst, def) => {
1735
- def.pattern ?? (def.pattern = datetime(def));
1735
+ def.pattern ?? (def.pattern = datetime$1(def));
1736
1736
  $ZodStringFormat.init(inst, def);
1737
1737
  });
1738
1738
  var $ZodISODate = /*@__PURE__*/ $constructor("$ZodISODate", (inst, def) => {
@@ -5729,6 +5729,11 @@ function preprocess(fn, schema) {
5729
5729
  });
5730
5730
  }
5731
5731
  //#endregion
5732
+ //#region ../../node_modules/.bun/zod@4.6.5/node_modules/zod/v4/classic/iso.js
5733
+ function datetime(params) {
5734
+ return /* @__PURE__ */ _isoDateTime(ZodISODateTime, params);
5735
+ }
5736
+ //#endregion
5732
5737
  //#region src/json-schema-subset/utils.ts
5733
5738
  var nextId = 0;
5734
5739
  function createId() {
@@ -8608,6 +8613,33 @@ var triggerScheduleSchema = array(union([object({
8608
8613
  value: number()
8609
8614
  })]));
8610
8615
  //#endregion
8616
+ //#region src/localization/common/timeZone.ts
8617
+ /** Validate a named timezone using the same runtime data used for date conversion. */
8618
+ function isTimeZone(value) {
8619
+ try {
8620
+ Intl.DateTimeFormat("en", { timeZone: value });
8621
+ return true;
8622
+ } catch {
8623
+ return false;
8624
+ }
8625
+ }
8626
+ //#endregion
8627
+ //#region src/flow/common/wait.ts
8628
+ /** Drafts retain incomplete values; semantic validation gates publication and execution. */
8629
+ var waitAutoContinueDraftSchema = discriminatedUnion("kind", [strictObject({
8630
+ kind: literal("after"),
8631
+ durationMs: number().nullable()
8632
+ }), strictObject({
8633
+ kind: literal("at"),
8634
+ at: string$1(),
8635
+ timezone: string$1().optional()
8636
+ })]);
8637
+ /** Static business configuration; the deployment owns the allowed wait lifetime. */
8638
+ var waitAutoContinueSchema = discriminatedUnion("kind", [waitAutoContinueDraftSchema.options[0].extend({ durationMs: number().int().positive().max(Number.MAX_SAFE_INTEGER) }), waitAutoContinueDraftSchema.options[1].extend({
8639
+ at: datetime({ offset: true }),
8640
+ timezone: string$1().refine(isTimeZone, "Select a valid IANA timezone.").optional()
8641
+ })]);
8642
+ //#endregion
8611
8643
  //#region src/flow/common/webhookMethod.ts
8612
8644
  var webhookMethods = [
8613
8645
  "GET",
@@ -8619,6 +8651,24 @@ var webhookMethods = [
8619
8651
  function webhookSupportsBody(method) {
8620
8652
  return method !== "GET";
8621
8653
  }
8654
+ //#endregion
8655
+ //#region src/flow/common/webhookResponse.ts
8656
+ var webhookResponseTimeout = {
8657
+ defaultMs: 3e4,
8658
+ minMs: 1e3,
8659
+ maxMs: 6e4
8660
+ };
8661
+ ({
8662
+ jsonSchema: {
8663
+ type: "object",
8664
+ additionalProperties: { type: [
8665
+ "string",
8666
+ "number",
8667
+ "boolean"
8668
+ ] }
8669
+ },
8670
+ nullable: true
8671
+ }).jsonSchema;
8622
8672
  var text = string$1();
8623
8673
  var actionConnection = text.describe("Account selection: omit while unconfigured; use an account ID to select it; use \"\" to explicitly defer configuration. Deferred Actions fail if called; deferred Agent tools are excluded from the callable tool set. Not supported by Triggers.");
8624
8674
  var json$3 = json$4();
@@ -8846,9 +8896,24 @@ var webhookOptions = object({
8846
8896
  allowedMethods: never().optional(),
8847
8897
  allowedOrigins: strings$1.optional(),
8848
8898
  noResponseBody: never().optional(),
8899
+ responseBody: discriminatedUnion("kind", [strictObject({
8900
+ kind: literal("workflow-outputs"),
8901
+ output: text.optional(),
8902
+ timeoutMs: number().int().min(webhookResponseTimeout.minMs).max(webhookResponseTimeout.maxMs).optional()
8903
+ }), strictObject({
8904
+ kind: literal("webhook-response"),
8905
+ nodeId: text.optional(),
8906
+ timeoutMs: number().int().min(webhookResponseTimeout.minMs).max(webhookResponseTimeout.maxMs).optional()
8907
+ })]).optional(),
8849
8908
  responseData: text.optional(),
8850
8909
  responseHeaders: record$3(text, text).optional(),
8851
- responseStatusCode: number().int().min(200).max(599).optional()
8910
+ responseHeadersSource: strictObject({
8911
+ kind: literal("workflow-outputs"),
8912
+ output: text.optional()
8913
+ }).optional(),
8914
+ responseHeaderOutputs: record$3(text, text).optional(),
8915
+ responseStatusCode: number().int().min(200).max(599).optional(),
8916
+ responseStatusCodeOutput: text.optional()
8852
8917
  });
8853
8918
  var webhook = {
8854
8919
  bodyFields: array(input),
@@ -8903,6 +8968,12 @@ var base = {
8903
8968
  onError: _enum(["stop", "error"]).optional()
8904
8969
  };
8905
8970
  var node = union([
8971
+ strictObject({
8972
+ ...base,
8973
+ kind: literal("webhook-response"),
8974
+ retry: never().optional(),
8975
+ onError: never().optional()
8976
+ }),
8906
8977
  strictObject({
8907
8978
  ...base,
8908
8979
  kind: literal("outputs"),
@@ -8935,7 +9006,8 @@ var node = union([
8935
9006
  strictObject({
8936
9007
  ...base,
8937
9008
  kind: literal("wait"),
8938
- ...wait
9009
+ ...wait,
9010
+ autoContinue: waitAutoContinueDraftSchema.optional()
8939
9011
  }).omit({ timeoutMs: true }),
8940
9012
  object({
8941
9013
  ...trigger,
@@ -8991,6 +9063,7 @@ var authoringDefinitionSchemas = {
8991
9063
  ports: ports$1,
8992
9064
  condition: strictObject(condition),
8993
9065
  wait: strictObject(wait),
9066
+ waitAutoContinue: waitAutoContinueSchema,
8994
9067
  webhook: strictObject(webhook),
8995
9068
  schedule: triggerScheduleSchema,
8996
9069
  capabilities: array(capability),
@@ -9037,7 +9110,8 @@ var revision = object({
9037
9110
  literal(6),
9038
9111
  literal(7),
9039
9112
  literal(8),
9040
- literal(9)
9113
+ literal(9),
9114
+ literal(10)
9041
9115
  ]),
9042
9116
  document,
9043
9117
  modules: record$3(text, module)
@@ -9170,8 +9244,14 @@ var shapes = {
9170
9244
  },
9171
9245
  "graph.node.resolution.set": {
9172
9246
  ...at,
9173
- before: object(wait),
9174
- value: object(wait)
9247
+ before: strictObject({
9248
+ ...wait,
9249
+ autoContinue: waitAutoContinueDraftSchema.optional()
9250
+ }),
9251
+ value: strictObject({
9252
+ ...wait,
9253
+ autoContinue: waitAutoContinueDraftSchema.optional()
9254
+ })
9175
9255
  },
9176
9256
  "graph.node.webhook.set": {
9177
9257
  ...at,
@@ -9232,12 +9312,14 @@ array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, sha
9232
9312
  ...shape
9233
9313
  })])).values()])).min(1);
9234
9314
  function checkModelVersion(content) {
9315
+ if (content.modelVersion < 10 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "webhook" && (candidateNode.options?.responseBody != null || candidateNode.options?.responseStatusCodeOutput != null || candidateNode.options?.responseHeadersSource != null || candidateNode.options?.responseHeaderOutputs != null))) throw new TypeError("Dynamic Webhook responses require Flow model version 10.");
9235
9316
  if (content.modelVersion < 9 && Object.values(content.document.graph.nodes).some((candidateNode) => "retry" in candidateNode && candidateNode.retry != null)) throw new TypeError("Node retries require Flow model version 9.");
9236
9317
  if (content.modelVersion < 9 && Object.values(content.document.graph.nodes).some((candidateNode) => {
9237
9318
  if (candidateNode.onError != null) return true;
9238
9319
  if ([...Object.values("inputs" in candidateNode ? candidateNode.inputs : {}), ...Object.values(candidateNode.kind == "outputs" ? candidateNode.outputMappings : {})].some((candidateMapping) => candidateMapping.kind == "sources" && candidateMapping.sources.some((candidateSource) => candidateSource.kind == "node" && candidateSource.system))) return true;
9239
9320
  return candidateNode.kind == "condition" && candidateNode.cases.some((item) => item.groups.some((candidateGroup) => candidateGroup.expressions.some((expression) => [expression.left, expression.right].some((candidateOperand) => candidateOperand?.kind == "source" && candidateOperand.source.kind == "node" && candidateOperand.source.system))));
9240
9321
  })) throw new TypeError("Node error handling requires Flow model version 9.");
9322
+ if (content.modelVersion < 10 && Object.values(content.document.graph.nodes).some((candidate) => candidate.kind === "webhook-response")) throw new TypeError("Webhook response nodes require Flow model version 10.");
9241
9323
  if (content.modelVersion < 8 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "outputs")) throw new TypeError("Workflow outputs require Flow model version 8.");
9242
9324
  if (content.modelVersion < 7 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "start")) throw new TypeError("Start Triggers require Flow model version 7.");
9243
9325
  if (content.modelVersion < 6 && Object.values(content.document.graph.nodes).some((candidateNode) => candidateNode.kind == "task" && "executor" in candidateNode.task)) throw new TypeError("Node-owned managed Tasks require Flow model version 6.");
@@ -9274,10 +9356,10 @@ function upgradeRevisionContent(content) {
9274
9356
  function upgradeDecodedRevisionContent(content) {
9275
9357
  const graph = content.document.graph;
9276
9358
  const hasManual = Object.values(graph.nodes).some((node) => node.kind == "manual");
9277
- if (!hasManual && content.modelVersion == 9) return content;
9359
+ if (!hasManual && content.modelVersion == 10) return content;
9278
9360
  return {
9279
9361
  ...content,
9280
- modelVersion: 9,
9362
+ modelVersion: 10,
9281
9363
  document: {
9282
9364
  ...content.document,
9283
9365
  graph: hasManual ? {
@@ -9366,6 +9448,7 @@ var patch = record$3(id$1, json$2);
9366
9448
  var type = _enum([
9367
9449
  "start",
9368
9450
  "outputs",
9451
+ "webhook-response",
9369
9452
  "workflow",
9370
9453
  "webhook",
9371
9454
  "cron",
@@ -9469,29 +9552,30 @@ var when = union([
9469
9552
  strictObject({ any: array(union([expression, all])) })
9470
9553
  ]);
9471
9554
  var authoringConfigurations = {
9472
- workflow: strictObject({ flowId: id$1 }),
9473
- start: strictObject({ inputDefs: flowInputFields.default({}) }),
9474
- outputs: strictObject({ outputDefs: flowOutputFields.default({}) }),
9475
- error: strictObject({ sourceFlowIds: array(id$1).optional() }),
9476
- webhook: authoringDefinitionSchemas.webhook.omit({ bodyFields: true }).extend({ body: inputFields }).strict(),
9477
- cron: strictObject({ schedule: authoringDefinitionSchemas.schedule }),
9478
- poll: strictObject({
9555
+ "webhook-response": strictObject({}),
9556
+ "workflow": strictObject({ flowId: id$1 }),
9557
+ "start": strictObject({ inputDefs: flowInputFields.default({}) }),
9558
+ "outputs": strictObject({ outputDefs: flowOutputFields.default({}) }),
9559
+ "error": strictObject({ sourceFlowIds: array(id$1).optional() }),
9560
+ "webhook": authoringDefinitionSchemas.webhook.omit({ bodyFields: true }).extend({ body: inputFields }).strict(),
9561
+ "cron": strictObject({ schedule: authoringDefinitionSchemas.schedule }),
9562
+ "poll": strictObject({
9479
9563
  key: id$1,
9480
9564
  connectionId: id$1.optional(),
9481
9565
  schedule: authoringDefinitionSchemas.schedule
9482
9566
  }),
9483
- integration: strictObject({
9567
+ "integration": strictObject({
9484
9568
  key: id$1,
9485
9569
  connectionId: id$1.optional()
9486
9570
  }),
9487
- code: strictObject({
9571
+ "code": strictObject({
9488
9572
  inputs: inputFields,
9489
9573
  outputs: outputFields,
9490
9574
  capabilities: authoringDefinitionSchemas.capabilities.optional()
9491
9575
  }),
9492
- connector: authoringDefinitionSchemas.connector.omit({ outputMode: true }).strict(),
9493
- openapi: authoringOpenApiSchema,
9494
- agent: authoringDefinitionSchemas.agent.omit({
9576
+ "connector": authoringDefinitionSchemas.connector.omit({ outputMode: true }).strict(),
9577
+ "openapi": authoringOpenApiSchema,
9578
+ "agent": authoringDefinitionSchemas.agent.omit({
9495
9579
  prompt: true,
9496
9580
  tools: true
9497
9581
  }).extend({
@@ -9500,9 +9584,9 @@ var authoringConfigurations = {
9500
9584
  tools: array(agentTool),
9501
9585
  notification: notification.optional()
9502
9586
  }).strict(),
9503
- llm: authoringLlmConfiguration.extend({ inputs: inputFields }),
9504
- decision: authoringDefinitionSchemas.decision,
9505
- condition: strictObject({
9587
+ "llm": authoringLlmConfiguration.extend({ inputs: inputFields }),
9588
+ "decision": authoringDefinitionSchemas.decision,
9589
+ "condition": strictObject({
9506
9590
  match: _enum(["first", "all"]),
9507
9591
  branches: array(strictObject({
9508
9592
  name: id$1,
@@ -9510,12 +9594,15 @@ var authoringConfigurations = {
9510
9594
  when
9511
9595
  }))
9512
9596
  }),
9513
- value: strictObject({
9597
+ "value": strictObject({
9514
9598
  values: patch,
9515
9599
  outputs: outputFields
9516
9600
  }),
9517
- wait: strictObject({ inputs: inputFields }),
9518
- approval: strictObject({ inputs: inputFields })
9601
+ "wait": strictObject({
9602
+ inputs: inputFields,
9603
+ autoContinue: authoringDefinitionSchemas.waitAutoContinue.optional().describe("Wait only. Omit to disable; clear config.autoContinue to remove. after counts from each wait registration; at requires an explicit offset and continues immediately if already past. Optional timezone preserves the editor zone; at remains the absolute instant. Server requires the deadline to precede the 7-day expiry.")
9604
+ }),
9605
+ "approval": strictObject({ inputs: inputFields })
9519
9606
  };
9520
9607
  var updates = strictObject({
9521
9608
  onError: _enum(["stop", "error"]).optional(),
@@ -11207,6 +11294,7 @@ function runWaiting(value) {
11207
11294
  if (!Array.isArray(actions) || !(actions.length == 1 && actions[0] == "continue" || actions.length == 2 && actions[0] == "approve" && actions[1] == "reject")) return invalidResponse();
11208
11295
  return {
11209
11296
  actions,
11297
+ ...source.autoContinueAt === void 0 ? {} : { autoContinueAt: string(source.autoContinueAt) },
11210
11298
  expiresAt: string(source.expiresAt),
11211
11299
  nodeId: string(source.nodeId),
11212
11300
  prompt: string(source.prompt),
@@ -11478,24 +11566,32 @@ function decodeRunEvent(value) {
11478
11566
  kind,
11479
11567
  payload: { waitIds: payload.waitIds.map((id) => string(id)) }
11480
11568
  };
11481
- case "wait.created": return {
11482
- ...base,
11483
- kind,
11484
- payload: {
11485
- expiresAt: string(payload.expiresAt),
11486
- nodeId: string(payload.nodeId),
11487
- waitId: string(payload.waitId),
11488
- waitingSince: string(payload.waitingSince)
11489
- }
11490
- };
11569
+ case "wait.created": {
11570
+ const timing = payload.autoContinueAt === void 0 ? {} : { autoContinueAt: string(payload.autoContinueAt) };
11571
+ return {
11572
+ ...base,
11573
+ kind,
11574
+ payload: {
11575
+ ...timing,
11576
+ expiresAt: string(payload.expiresAt),
11577
+ nodeId: string(payload.nodeId),
11578
+ waitId: string(payload.waitId),
11579
+ waitingSince: string(payload.waitingSince)
11580
+ }
11581
+ };
11582
+ }
11491
11583
  case "run.resolved": {
11492
11584
  const action = payload.action;
11585
+ const resolutionSource = payload.source;
11586
+ if (resolutionSource !== void 0 && resolutionSource !== "manual" && resolutionSource !== "automatic") return invalidResponse();
11587
+ const audit = resolutionSource === void 0 ? {} : { source: resolutionSource };
11493
11588
  if (action !== "approve" && action !== "continue" && action !== "reject") return invalidResponse();
11494
11589
  if (payload.comment !== null && typeof payload.comment != "string") return invalidResponse();
11495
11590
  return {
11496
11591
  ...base,
11497
11592
  kind,
11498
11593
  payload: {
11594
+ ...audit,
11499
11595
  action,
11500
11596
  comment: payload.comment,
11501
11597
  resolvedAt: string(payload.resolvedAt),
@@ -11531,7 +11627,7 @@ function decodeRunEvent(value) {
11531
11627
  switch (kind) {
11532
11628
  case "node.started": {
11533
11629
  const nodeKind = payload.nodeKind;
11534
- if (nodeKind !== void 0 && nodeKind !== "approval" && nodeKind !== "condition" && nodeKind !== "connector" && nodeKind !== "javascript" && nodeKind !== "decision" && nodeKind !== "openapi" && nodeKind !== "llm" && nodeKind !== "agent" && nodeKind !== "value" && nodeKind !== "outputs" && nodeKind !== "workflow" && nodeKind !== "wait") return invalidResponse();
11630
+ if (nodeKind !== void 0 && nodeKind !== "approval" && nodeKind !== "condition" && nodeKind !== "connector" && nodeKind !== "javascript" && nodeKind !== "decision" && nodeKind !== "openapi" && nodeKind !== "llm" && nodeKind !== "agent" && nodeKind !== "value" && nodeKind !== "outputs" && nodeKind !== "webhook-response" && nodeKind !== "workflow" && nodeKind !== "wait") return invalidResponse();
11535
11631
  return {
11536
11632
  ...base,
11537
11633
  kind,
@@ -13265,11 +13361,19 @@ var controlApiConformanceCases = [
13265
13361
  }), 202, message);
13266
13362
  const run = await create("wait-run", "Create Wait Run");
13267
13363
  const runId = requiredString(run.runId, "Wait Run runId");
13268
- let detail = run;
13269
- for (let attempt = 0; list(detail.waits, "Waits").length == 0 && attempt < 200; attempt += 1) {
13270
- await new Promise((resolve) => setTimeout(resolve, 10));
13271
- detail = await json(await request(harness, `/v1/runs/${runId}`), 200, "Read Wait Run");
13272
- }
13364
+ const awaitRun = async (initial, ready, message) => {
13365
+ const id = requiredString(initial.runId, "Run id");
13366
+ const deadline = performance.now() + 1e4;
13367
+ let current = initial;
13368
+ while (!ready(current)) {
13369
+ if (performance.now() >= deadline) fail(`${message}: timed out after 10000ms; last Run: ${JSON.stringify(current)}.`);
13370
+ await new Promise((resolve) => setTimeout(resolve, 25));
13371
+ current = await json(await request(harness, `/v1/runs/${id}`), 200, message);
13372
+ }
13373
+ return current;
13374
+ };
13375
+ const hasWait = (value) => list(value.waits, "Waits").length > 0;
13376
+ let detail = await awaitRun(run, hasWait, "Wait Run to pause");
13273
13377
  equal(detail.status, "running", "Wait Run status");
13274
13378
  const waiting = record(list(detail.waits, "Waits")[0], "Active Wait");
13275
13379
  equal(waiting.actions, ["approve", "reject"], "Wait actions");
@@ -13301,10 +13405,7 @@ var controlApiConformanceCases = [
13301
13405
  const rejected = await json(await resolveWait("reject"), 200, "Reject resolved Wait");
13302
13406
  equal(rejected.action, "approve", "Winning action");
13303
13407
  equal(rejected.resolutionAccepted, false, "Competing resolution");
13304
- for (let attempt = 0; detail.status != "completed" && attempt < 200; attempt += 1) {
13305
- await new Promise((resolve) => setTimeout(resolve, 10));
13306
- detail = await json(await request(harness, `/v1/runs/${runId}`), 200, "Read resumed Run");
13307
- }
13408
+ detail = await awaitRun(detail, (value) => value.status == "completed", "Wait Run to resume");
13308
13409
  equal(detail.status, "completed", "Resumed Run status");
13309
13410
  equal(detail.waits, [], "Completed Wait projection");
13310
13411
  const replay = await json(await resolveWait("approve"), 200, "Replay approved Wait");
@@ -13315,12 +13416,7 @@ var controlApiConformanceCases = [
13315
13416
  equal(list(completedEvents.events, "Completed events").filter((value) => record(value, "Completed event").kind == "run.resolved").length, 1, "Resolved event count");
13316
13417
  const canceled = await create("wait-run-cancel", "Create cancelable Wait Run");
13317
13418
  const canceledRunId = requiredString(canceled.runId, "Cancelable Wait Run id");
13318
- let canceledDetail = canceled;
13319
- for (let attempt = 0; list(canceledDetail.waits, "Waits").length == 0 && attempt < 200; attempt += 1) {
13320
- await new Promise((resolve) => setTimeout(resolve, 10));
13321
- canceledDetail = await json(await request(harness, `/v1/runs/${canceledRunId}`), 200, "Read cancelable Wait Run");
13322
- }
13323
- equal(canceledDetail.status, "running", "Cancelable Wait status");
13419
+ equal((await awaitRun(canceled, hasWait, "Wait cancelable Run to pause")).status, "running", "Cancelable Wait status");
13324
13420
  equal((await json(await request(harness, `/v1/runs/${canceledRunId}/cancel`, {
13325
13421
  body: JSON.stringify({ version: 1 }),
13326
13422
  method: "POST"
@@ -398,6 +398,7 @@ export interface Run {
398
398
  readonly version: 1;
399
399
  }
400
400
  export interface RunWait {
401
+ readonly autoContinueAt?: string;
401
402
  readonly actions: readonly ['continue'] | readonly ['approve', 'reject'];
402
403
  readonly expiresAt: string;
403
404
  readonly nodeId: string;
@@ -461,7 +462,15 @@ export interface RunPage {
461
462
  readonly runs: readonly Run[];
462
463
  readonly version: 1;
463
464
  }
464
- export type RunEvent = Readonly<ReturnType<typeof decodeRunEvent>>;
465
+ /** Run-level events have no node identity; callers may inspect it without narrowing the event kind. */
466
+ type EventWithNodeContext<Event> = Event extends {
467
+ readonly payload: infer Payload;
468
+ } ? Readonly<Event & {
469
+ readonly payload: Payload & {
470
+ readonly nodeId?: string;
471
+ };
472
+ }> : never;
473
+ export type RunEvent = EventWithNodeContext<ReturnType<typeof decodeRunEvent>>;
465
474
  export type RunEventKind = RunEvent['kind'];
466
475
  export declare function isRunTerminalEvent(event: RunEvent | undefined): boolean;
467
476
  export interface RunEvents {
@@ -520,17 +529,10 @@ export declare function decodeRunEvent(value: unknown): {
520
529
  readonly sequence: number;
521
530
  readonly kind: "run.queued";
522
531
  readonly payload: {
523
- nodeId?: undefined;
524
532
  readonly flowId?: undefined;
525
533
  readonly scopeId?: undefined;
526
534
  readonly progress?: undefined;
527
535
  readonly waitIds?: undefined;
528
- readonly expiresAt?: undefined;
529
- readonly waitingSince?: undefined;
530
- readonly action?: undefined;
531
- readonly comment?: undefined;
532
- readonly resolvedAt?: undefined;
533
- readonly waitId?: undefined;
534
536
  readonly result?: undefined;
535
537
  };
536
538
  } | {
@@ -538,18 +540,11 @@ export declare function decodeRunEvent(value: unknown): {
538
540
  readonly sequence: number;
539
541
  readonly kind: "run.started";
540
542
  readonly payload: {
541
- nodeId?: undefined;
542
543
  readonly flowId: string;
543
544
  readonly scopeId: string;
544
545
  readonly parentScopeId?: string | undefined;
545
546
  readonly progress?: undefined;
546
547
  readonly waitIds?: undefined;
547
- readonly expiresAt?: undefined;
548
- readonly waitingSince?: undefined;
549
- readonly action?: undefined;
550
- readonly comment?: undefined;
551
- readonly resolvedAt?: undefined;
552
- readonly waitId?: undefined;
553
548
  readonly result?: undefined;
554
549
  };
555
550
  } | {
@@ -557,17 +552,10 @@ export declare function decodeRunEvent(value: unknown): {
557
552
  readonly sequence: number;
558
553
  readonly kind: "run.progress";
559
554
  readonly payload: {
560
- nodeId?: undefined;
561
555
  readonly flowId: string;
562
556
  readonly scopeId: string;
563
557
  readonly progress: number;
564
558
  readonly waitIds?: undefined;
565
- readonly expiresAt?: undefined;
566
- readonly waitingSince?: undefined;
567
- readonly action?: undefined;
568
- readonly comment?: undefined;
569
- readonly resolvedAt?: undefined;
570
- readonly waitId?: undefined;
571
559
  readonly result?: undefined;
572
560
  };
573
561
  } | {
@@ -575,17 +563,10 @@ export declare function decodeRunEvent(value: unknown): {
575
563
  readonly sequence: number;
576
564
  readonly kind: "run.waiting";
577
565
  readonly payload: {
578
- nodeId?: undefined;
579
566
  readonly flowId?: undefined;
580
567
  readonly scopeId?: undefined;
581
568
  readonly progress?: undefined;
582
569
  readonly waitIds: string[];
583
- readonly expiresAt?: undefined;
584
- readonly waitingSince?: undefined;
585
- readonly action?: undefined;
586
- readonly comment?: undefined;
587
- readonly resolvedAt?: undefined;
588
- readonly waitId?: undefined;
589
570
  readonly result?: undefined;
590
571
  };
591
572
  } | {
@@ -597,13 +578,11 @@ export declare function decodeRunEvent(value: unknown): {
597
578
  readonly scopeId?: undefined;
598
579
  readonly progress?: undefined;
599
580
  readonly waitIds?: undefined;
581
+ readonly autoContinueAt?: string;
600
582
  readonly expiresAt: string;
601
583
  readonly nodeId: string;
602
584
  readonly waitId: string;
603
585
  readonly waitingSince: string;
604
- readonly action?: undefined;
605
- readonly comment?: undefined;
606
- readonly resolvedAt?: undefined;
607
586
  readonly result?: undefined;
608
587
  };
609
588
  } | {
@@ -611,13 +590,11 @@ export declare function decodeRunEvent(value: unknown): {
611
590
  readonly sequence: number;
612
591
  readonly kind: "run.resolved";
613
592
  readonly payload: {
614
- nodeId?: undefined;
615
593
  readonly flowId?: undefined;
616
594
  readonly scopeId?: undefined;
617
595
  readonly progress?: undefined;
618
596
  readonly waitIds?: undefined;
619
- readonly expiresAt?: undefined;
620
- readonly waitingSince?: undefined;
597
+ readonly source?: 'manual' | 'automatic';
621
598
  readonly action: "approve" | "continue" | "reject";
622
599
  readonly comment: string | null;
623
600
  readonly resolvedAt: string;
@@ -629,17 +606,10 @@ export declare function decodeRunEvent(value: unknown): {
629
606
  readonly sequence: number;
630
607
  readonly kind: "run.canceled" | "run.completed" | "run.failed" | "run.indeterminate";
631
608
  readonly payload: {
632
- nodeId?: undefined;
633
609
  readonly flowId?: undefined;
634
610
  readonly scopeId?: undefined;
635
611
  readonly progress?: undefined;
636
612
  readonly waitIds?: undefined;
637
- readonly expiresAt?: undefined;
638
- readonly waitingSince?: undefined;
639
- readonly action?: undefined;
640
- readonly comment?: undefined;
641
- readonly resolvedAt?: undefined;
642
- readonly waitId?: undefined;
643
613
  readonly result: JsonValue;
644
614
  };
645
615
  } | {
@@ -656,12 +626,6 @@ export declare function decodeRunEvent(value: unknown): {
656
626
  readonly payload: {
657
627
  readonly progress?: undefined;
658
628
  readonly waitIds?: undefined;
659
- readonly expiresAt?: undefined;
660
- readonly waitingSince?: undefined;
661
- readonly action?: undefined;
662
- readonly comment?: undefined;
663
- readonly resolvedAt?: undefined;
664
- readonly waitId?: undefined;
665
629
  readonly result?: undefined;
666
630
  readonly flowId: string;
667
631
  readonly scopeId: string;
@@ -678,12 +642,6 @@ export declare function decodeRunEvent(value: unknown): {
678
642
  readonly payload: {
679
643
  readonly progress?: undefined;
680
644
  readonly waitIds?: undefined;
681
- readonly expiresAt?: undefined;
682
- readonly waitingSince?: undefined;
683
- readonly action?: undefined;
684
- readonly comment?: undefined;
685
- readonly resolvedAt?: undefined;
686
- readonly waitId?: undefined;
687
645
  readonly result?: undefined;
688
646
  readonly flowId: string;
689
647
  readonly scopeId: string;
@@ -703,12 +661,6 @@ export declare function decodeRunEvent(value: unknown): {
703
661
  readonly payload: {
704
662
  readonly progress?: undefined;
705
663
  readonly waitIds?: undefined;
706
- readonly expiresAt?: undefined;
707
- readonly waitingSince?: undefined;
708
- readonly action?: undefined;
709
- readonly comment?: undefined;
710
- readonly resolvedAt?: undefined;
711
- readonly waitId?: undefined;
712
664
  readonly result?: undefined;
713
665
  readonly flowId: string;
714
666
  readonly scopeId: string;
@@ -730,12 +682,6 @@ export declare function decodeRunEvent(value: unknown): {
730
682
  readonly payload: {
731
683
  readonly progress?: undefined;
732
684
  readonly waitIds?: undefined;
733
- readonly expiresAt?: undefined;
734
- readonly waitingSince?: undefined;
735
- readonly action?: undefined;
736
- readonly comment?: undefined;
737
- readonly resolvedAt?: undefined;
738
- readonly waitId?: undefined;
739
685
  readonly result?: undefined;
740
686
  readonly flowId: string;
741
687
  readonly scopeId: string;
@@ -750,12 +696,6 @@ export declare function decodeRunEvent(value: unknown): {
750
696
  readonly kind: "node.progress";
751
697
  readonly payload: {
752
698
  readonly waitIds?: undefined;
753
- readonly expiresAt?: undefined;
754
- readonly waitingSince?: undefined;
755
- readonly action?: undefined;
756
- readonly comment?: undefined;
757
- readonly resolvedAt?: undefined;
758
- readonly waitId?: undefined;
759
699
  readonly result?: undefined;
760
700
  readonly flowId: string;
761
701
  readonly scopeId: string;
@@ -770,12 +710,6 @@ export declare function decodeRunEvent(value: unknown): {
770
710
  readonly payload: {
771
711
  readonly progress?: undefined;
772
712
  readonly waitIds?: undefined;
773
- readonly expiresAt?: undefined;
774
- readonly waitingSince?: undefined;
775
- readonly action?: undefined;
776
- readonly comment?: undefined;
777
- readonly resolvedAt?: undefined;
778
- readonly waitId?: undefined;
779
713
  readonly result?: undefined;
780
714
  readonly flowId: string;
781
715
  readonly scopeId: string;