@oomol-lab/open-flow 0.1.0-beta.50 → 0.1.0-beta.51

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 (33) hide show
  1. package/dist/browser/{createResourceDialog-CSltk-qY.js → createResourceDialog-BDtXpRSt.js} +1 -1
  2. package/dist/browser/flow-authoring-node.d.ts +3 -1
  3. package/dist/browser/flow-authoring.js +39 -3
  4. package/dist/browser/flow-change-schema.d.ts +1 -1
  5. package/dist/browser/flow-change.d.ts +9 -1
  6. package/dist/browser/flow-change.js +38 -3
  7. package/dist/browser/{flowChanges-DbYrpHnS.js → flowChanges-BWSXSnMX.js} +431 -27
  8. package/dist/browser/{flowWorkspace-CjwpbVBR.js → flowWorkspace-DBaq2Eks.js} +459 -190
  9. package/dist/browser/preview.css +20 -0
  10. package/dist/browser/preview.js +556 -21
  11. package/dist/browser/ui.css +20 -0
  12. package/dist/browser/ui.js +4 -3
  13. package/dist/browser/workbench-contract.d.ts +1 -0
  14. package/dist/browser/workbench.css +20 -0
  15. package/dist/browser/workbench.js +133 -22
  16. package/dist/browser/{workbenchSelect-oVujN2z6.js → workbenchSelect-C9kwcUmN.js} +47 -6
  17. package/dist/common/authoringExamples.d.ts +3 -2
  18. package/dist/common/control-api-conformance.js +82 -10
  19. package/dist/common/control-api.d.ts +34 -5
  20. package/dist/common/control-api.js +147 -10
  21. package/dist/common/control-requests.js +23 -1
  22. package/dist/common/flow-encoding.js +30 -5
  23. package/dist/common/flow-semantics.js +87 -2
  24. package/dist/common/integration-trigger.js +16 -1
  25. package/dist/common/mcp.js +82 -10
  26. package/dist/common/poll-trigger.js +16 -1
  27. package/dist/common/provider-triggers.js +16 -1
  28. package/dist/common/run-events.js +25 -1
  29. package/dist/common/scheduler.d.ts +3 -0
  30. package/dist/common/scheduler.js +91 -5
  31. package/dist/common/trigger-contract.d.ts +2 -0
  32. package/dist/common/webhook-trigger.js +16 -1
  33. package/package.json +1 -1
@@ -9817,6 +9817,7 @@ var endpoint = object({
9817
9817
  ])),
9818
9818
  successStatus: number()
9819
9819
  });
9820
+ var sourceFlowIds = array(text.min(1)).refine((ids) => new Set(ids).size === ids.length, "Duplicate source Flow ID.");
9820
9821
  var trigger = {
9821
9822
  name: text,
9822
9823
  description: text.optional(),
@@ -9874,6 +9875,11 @@ var node = union([
9874
9875
  ...trigger,
9875
9876
  kind: literal("manual")
9876
9877
  }),
9878
+ strictObject({
9879
+ ...trigger,
9880
+ kind: literal("error"),
9881
+ sourceFlowIds: sourceFlowIds.optional()
9882
+ }),
9877
9883
  object({
9878
9884
  ...trigger,
9879
9885
  kind: literal("webhook"),
@@ -9945,7 +9951,11 @@ var document = object({
9945
9951
  tasks: record(text, managed)
9946
9952
  });
9947
9953
  object({
9948
- modelVersion: union([literal(2), literal(4)]),
9954
+ modelVersion: union([
9955
+ literal(2),
9956
+ literal(4),
9957
+ literal(5)
9958
+ ]),
9949
9959
  document,
9950
9960
  modules: record(text, module)
9951
9961
  }).extend({
@@ -9953,6 +9963,11 @@ object({
9953
9963
  version: literal(1)
9954
9964
  });
9955
9965
  var shapes = {
9966
+ "graph.trigger.sources.set": {
9967
+ nodeId: text,
9968
+ before: sourceFlowIds.optional(),
9969
+ value: sourceFlowIds.optional()
9970
+ },
9956
9971
  "binding.create": {
9957
9972
  bindingId: text,
9958
9973
  binding
@@ -10537,6 +10552,67 @@ function hasRetiredRef(value) {
10537
10552
  }
10538
10553
  //#endregion
10539
10554
  //#region src/trigger/common/contract.ts
10555
+ var errorOutputs = [
10556
+ {
10557
+ handle: "workflow",
10558
+ nullable: false,
10559
+ jsonSchema: {
10560
+ type: "object",
10561
+ additionalProperties: false,
10562
+ required: [
10563
+ "flowId",
10564
+ "name",
10565
+ "revisionId",
10566
+ "publicationId"
10567
+ ],
10568
+ properties: {
10569
+ flowId: { type: "string" },
10570
+ name: { type: "string" },
10571
+ revisionId: { type: "string" },
10572
+ publicationId: { type: ["string", "null"] }
10573
+ }
10574
+ }
10575
+ },
10576
+ {
10577
+ handle: "execution",
10578
+ nullable: false,
10579
+ jsonSchema: {
10580
+ type: "object",
10581
+ additionalProperties: false,
10582
+ required: [
10583
+ "runId",
10584
+ "status",
10585
+ "startedAt",
10586
+ "finishedAt"
10587
+ ],
10588
+ properties: {
10589
+ runId: { type: "string" },
10590
+ status: { enum: ["failed", "indeterminate"] },
10591
+ startedAt: { type: ["string", "null"] },
10592
+ finishedAt: { type: "string" }
10593
+ }
10594
+ }
10595
+ },
10596
+ {
10597
+ handle: "error",
10598
+ nullable: false,
10599
+ jsonSchema: {
10600
+ type: "object",
10601
+ additionalProperties: false,
10602
+ required: ["code", "message"],
10603
+ properties: {
10604
+ code: { type: "string" },
10605
+ message: { type: "string" },
10606
+ nodeId: { type: "string" },
10607
+ jobId: { type: "string" },
10608
+ path: {
10609
+ type: "array",
10610
+ items: { type: "string" }
10611
+ }
10612
+ }
10613
+ }
10614
+ }
10615
+ ];
10540
10616
  var webhookOutputs = [
10541
10617
  {
10542
10618
  handle: "headers",
@@ -10581,6 +10657,7 @@ var cronOutputs = [{
10581
10657
  }];
10582
10658
  function triggerOutputDefinitions(trigger) {
10583
10659
  switch (trigger.kind) {
10660
+ case "error": return errorOutputs;
10584
10661
  case "manual": return [];
10585
10662
  case "cron": return cronOutputs;
10586
10663
  case "poll":
@@ -11179,6 +11256,10 @@ function canonicalTriggerNode(trigger) {
11179
11256
  name: trigger.name
11180
11257
  });
11181
11258
  switch (trigger.kind) {
11259
+ case "error": return {
11260
+ ...common(trigger.kind),
11261
+ ...trigger.sourceFlowIds == null ? {} : { sourceFlowIds: [...trigger.sourceFlowIds] }
11262
+ };
11182
11263
  case "manual": return common(trigger.kind);
11183
11264
  case "webhook": return {
11184
11265
  ...common(trigger.kind),
@@ -11296,7 +11377,7 @@ function validateTrigger(triggerId, trigger, path, diagnostics) {
11296
11377
  }
11297
11378
  return;
11298
11379
  }
11299
- if (trigger.kind == "cron" || trigger.kind == "manual") return;
11380
+ if (trigger.kind == "error" || trigger.kind == "cron" || trigger.kind == "manual") return;
11300
11381
  if (trigger.connectionId == null) diagnostics.push(graphDiagnostic("trigger.connection-missing", "Select a connection account for this Trigger.", `${path}/connectionId`));
11301
11382
  const missingConfig = missingTriggerConfig(trigger.definition.configInputs, trigger.config);
11302
11383
  if (missingConfig.length > 0) diagnostics.push({
@@ -11320,6 +11401,7 @@ function nodeInputPorts(document, node) {
11320
11401
  case "cron":
11321
11402
  case "integration":
11322
11403
  case "poll":
11404
+ case "error":
11323
11405
  case "manual":
11324
11406
  case "webhook": return {};
11325
11407
  }
@@ -11370,6 +11452,7 @@ function nodeOutputPorts(document, node) {
11370
11452
  case "cron":
11371
11453
  case "integration":
11372
11454
  case "poll":
11455
+ case "error":
11373
11456
  case "manual":
11374
11457
  case "webhook": return triggerOutputPorts(node);
11375
11458
  }
@@ -11587,6 +11670,8 @@ function validateResolution(nodeId, node, allowed, path, diagnostics) {
11587
11670
  }
11588
11671
  function validateGraph(graph, document, flowInputs, allowTriggers, path, diagnostics) {
11589
11672
  const analysis = graphPaths(graph);
11673
+ const errorTriggers = Object.entries(graph.nodes).filter(([, node]) => node.kind == "error");
11674
+ if (errorTriggers.length > 1) for (const [nodeId] of errorTriggers) diagnostics.push(graphDiagnostic("graph.error-trigger-duplicate", "A graph can contain only one Error Trigger.", `${path}/nodes/${nodeId}`));
11590
11675
  const manualTriggers = Object.entries(graph.nodes).filter(([, node]) => node.kind == "manual");
11591
11676
  if (manualTriggers.length > 1) for (const [nodeId] of manualTriggers) diagnostics.push(graphDiagnostic("graph.manual-trigger-duplicate", "A graph can contain only one manual Trigger.", `${path}/nodes/${nodeId}`));
11592
11677
  const seen = /* @__PURE__ */ new Set();
@@ -9485,6 +9485,7 @@ var endpoint = object({
9485
9485
  ])),
9486
9486
  successStatus: number()
9487
9487
  });
9488
+ var sourceFlowIds = array(text.min(1)).refine((ids) => new Set(ids).size === ids.length, "Duplicate source Flow ID.");
9488
9489
  var trigger = {
9489
9490
  name: text,
9490
9491
  description: text.optional(),
@@ -9542,6 +9543,11 @@ var node = union([
9542
9543
  ...trigger,
9543
9544
  kind: literal("manual")
9544
9545
  }),
9546
+ strictObject({
9547
+ ...trigger,
9548
+ kind: literal("error"),
9549
+ sourceFlowIds: sourceFlowIds.optional()
9550
+ }),
9545
9551
  object({
9546
9552
  ...trigger,
9547
9553
  kind: literal("webhook"),
@@ -9613,7 +9619,11 @@ var document = object({
9613
9619
  tasks: record$1(text, managed)
9614
9620
  });
9615
9621
  object({
9616
- modelVersion: union([literal(2), literal(4)]),
9622
+ modelVersion: union([
9623
+ literal(2),
9624
+ literal(4),
9625
+ literal(5)
9626
+ ]),
9617
9627
  document,
9618
9628
  modules: record$1(text, module)
9619
9629
  }).extend({
@@ -9621,6 +9631,11 @@ object({
9621
9631
  version: literal(1)
9622
9632
  });
9623
9633
  var shapes = {
9634
+ "graph.trigger.sources.set": {
9635
+ nodeId: text,
9636
+ before: sourceFlowIds.optional(),
9637
+ value: sourceFlowIds.optional()
9638
+ },
9624
9639
  "binding.create": {
9625
9640
  bindingId: text,
9626
9641
  binding
@@ -6123,6 +6123,7 @@ var endpoint = object({
6123
6123
  ])),
6124
6124
  successStatus: number()
6125
6125
  });
6126
+ var sourceFlowIds = array(text.min(1)).refine((ids) => new Set(ids).size === ids.length, "Duplicate source Flow ID.");
6126
6127
  var trigger = {
6127
6128
  name: text,
6128
6129
  description: text.optional(),
@@ -6180,6 +6181,11 @@ var node = union([
6180
6181
  ...trigger,
6181
6182
  kind: literal("manual")
6182
6183
  }),
6184
+ strictObject({
6185
+ ...trigger,
6186
+ kind: literal("error"),
6187
+ sourceFlowIds: sourceFlowIds.optional()
6188
+ }),
6183
6189
  object({
6184
6190
  ...trigger,
6185
6191
  kind: literal("webhook"),
@@ -6251,7 +6257,11 @@ var document = object({
6251
6257
  tasks: record$1(text, managed)
6252
6258
  });
6253
6259
  var revision = object({
6254
- modelVersion: union([literal(2), literal(4)]),
6260
+ modelVersion: union([
6261
+ literal(2),
6262
+ literal(4),
6263
+ literal(5)
6264
+ ]),
6255
6265
  document,
6256
6266
  modules: record$1(text, module)
6257
6267
  });
@@ -6261,9 +6271,16 @@ revision.extend({
6261
6271
  });
6262
6272
  function decodeRevisionContent(value) {
6263
6273
  checkJsonDepth(value);
6264
- return revision.parse(value);
6274
+ const content = revision.parse(value);
6275
+ checkErrorModelVersion(content);
6276
+ return content;
6265
6277
  }
6266
6278
  var shapes = {
6279
+ "graph.trigger.sources.set": {
6280
+ nodeId: text,
6281
+ before: sourceFlowIds.optional(),
6282
+ value: sourceFlowIds.optional()
6283
+ },
6267
6284
  "binding.create": {
6268
6285
  bindingId: text,
6269
6286
  binding
@@ -6437,6 +6454,9 @@ array(union([...new Map(Object.entries(shapes).map(([kind, shape]) => [kind, sha
6437
6454
  kind: literal(kind),
6438
6455
  ...shape
6439
6456
  })])).values()])).min(1);
6457
+ function checkErrorModelVersion(content) {
6458
+ if (content.modelVersion < 5 && [content.document.graph, ...Object.values(content.document.subflows).map((item) => item.graph)].some((item) => Object.values(item.nodes).some((itemNode) => itemNode.kind == "error"))) throw new TypeError("Error workflows require Flow model version 5.");
6459
+ }
6440
6460
  //#endregion
6441
6461
  //#region src/flow/common/change.ts
6442
6462
  var schemaKeywords = /* @__PURE__ */ new Set([
@@ -9840,6 +9860,7 @@ function triggerKey(value) {
9840
9860
  };
9841
9861
  }
9842
9862
  var triggerKinds = /* @__PURE__ */ new Set([
9863
+ "error",
9843
9864
  "cron",
9844
9865
  "integration",
9845
9866
  "poll",
@@ -10216,6 +10237,17 @@ function variable(value) {
10216
10237
  version: 1
10217
10238
  };
10218
10239
  }
10240
+ function errorListener(value) {
10241
+ const source = record(value);
10242
+ if (typeof source.enabled != "boolean") return invalidResponse();
10243
+ return {
10244
+ flowId: string(source.flowId),
10245
+ flowName: string(source.flowName),
10246
+ nodeId: string(source.nodeId),
10247
+ nodeName: string(source.nodeName),
10248
+ enabled: source.enabled
10249
+ };
10250
+ }
10219
10251
  //#endregion
10220
10252
  //#region src/control/common/publicationDecoders.ts
10221
10253
  function publication(value) {
@@ -10474,6 +10506,7 @@ function runDetails(value) {
10474
10506
  };
10475
10507
  const details = {
10476
10508
  ...summary,
10509
+ ...errorHandling(source),
10477
10510
  closureDigest: string(source.closureDigest),
10478
10511
  engineContract: string(source.engineContract),
10479
10512
  engineDigest: string(source.engineDigest),
@@ -10573,10 +10606,7 @@ function runResult(value) {
10573
10606
  const error = record(source.error);
10574
10607
  return {
10575
10608
  ...base,
10576
- error: {
10577
- code: string(error.code),
10578
- message: string(error.message)
10579
- },
10609
+ error: runFailure(error),
10580
10610
  status: "failed"
10581
10611
  };
10582
10612
  }
@@ -10584,15 +10614,52 @@ function runResult(value) {
10584
10614
  const error = record(source.error);
10585
10615
  return {
10586
10616
  ...base,
10587
- error: {
10588
- code: string(error.code),
10589
- message: string(error.message)
10590
- },
10617
+ error: runFailure(error),
10591
10618
  status: "indeterminate"
10592
10619
  };
10593
10620
  }
10594
10621
  return invalidResponse();
10595
10622
  }
10623
+ function errorHandling(source) {
10624
+ const errorSource = source.errorSource == null ? void 0 : record(source.errorSource);
10625
+ if (source.errorDispatches != null && !Array.isArray(source.errorDispatches)) return invalidResponse();
10626
+ return {
10627
+ ...errorSource == null ? {} : { errorSource: {
10628
+ flowId: string(errorSource.flowId),
10629
+ runId: string(errorSource.runId)
10630
+ } },
10631
+ ...source.errorDispatches == null ? {} : { errorDispatches: source.errorDispatches.map((value) => {
10632
+ const dispatch = record(value);
10633
+ const flowId = string(dispatch.flowId);
10634
+ switch (dispatch.status) {
10635
+ case "pending": return {
10636
+ status: "pending",
10637
+ flowId
10638
+ };
10639
+ case "dispatched": return {
10640
+ status: "dispatched",
10641
+ flowId,
10642
+ runId: string(dispatch.runId)
10643
+ };
10644
+ case "failed": return {
10645
+ status: "failed",
10646
+ flowId,
10647
+ message: string(dispatch.message)
10648
+ };
10649
+ default: return invalidResponse();
10650
+ }
10651
+ }) }
10652
+ };
10653
+ }
10654
+ function runFailure(error) {
10655
+ return {
10656
+ code: string(error.code),
10657
+ message: string(error.message),
10658
+ ...error.nodeId === void 0 ? {} : { nodeId: string(error.nodeId) },
10659
+ ...error.jobId === void 0 ? {} : { jobId: string(error.jobId) },
10660
+ ...error.path === void 0 ? {} : { path: (Array.isArray(error.path) ? error.path : invalidResponse()).map(string) }
10661
+ };
10662
+ }
10596
10663
  //#endregion
10597
10664
  //#region src/control/common/random.ts
10598
10665
  function randomId() {
@@ -10891,6 +10958,11 @@ var ControlClient = class {
10891
10958
  async getFlow(flowId) {
10892
10959
  return flow$1(await this.request(`/v1/flows/${segment(flowId)}`));
10893
10960
  }
10961
+ async getErrorListeners(flowId, signal) {
10962
+ const source = record(await this.request(`/v1/flows/${segment(flowId)}/error-listeners`, { signal }));
10963
+ if (source.version != 1 || !Array.isArray(source.listeners)) return invalidResponse();
10964
+ return source.listeners.map(errorListener);
10965
+ }
10894
10966
  async renameFlow(flowId, name) {
10895
10967
  return flow$1(await this.request(`/v1/flows/${segment(flowId)}`, {
10896
10968
  body: JSON.stringify({
@@ -9461,6 +9461,7 @@ var endpoint = object({
9461
9461
  ])),
9462
9462
  successStatus: number()
9463
9463
  });
9464
+ var sourceFlowIds = array(text.min(1)).refine((ids) => new Set(ids).size === ids.length, "Duplicate source Flow ID.");
9464
9465
  var trigger = {
9465
9466
  name: text,
9466
9467
  description: text.optional(),
@@ -9518,6 +9519,11 @@ var node = union([
9518
9519
  ...trigger,
9519
9520
  kind: literal("manual")
9520
9521
  }),
9522
+ strictObject({
9523
+ ...trigger,
9524
+ kind: literal("error"),
9525
+ sourceFlowIds: sourceFlowIds.optional()
9526
+ }),
9521
9527
  object({
9522
9528
  ...trigger,
9523
9529
  kind: literal("webhook"),
@@ -9589,7 +9595,11 @@ var document = object({
9589
9595
  tasks: record(text, managed)
9590
9596
  });
9591
9597
  object({
9592
- modelVersion: union([literal(2), literal(4)]),
9598
+ modelVersion: union([
9599
+ literal(2),
9600
+ literal(4),
9601
+ literal(5)
9602
+ ]),
9593
9603
  document,
9594
9604
  modules: record(text, module)
9595
9605
  }).extend({
@@ -9597,6 +9607,11 @@ object({
9597
9607
  version: literal(1)
9598
9608
  });
9599
9609
  var shapes = {
9610
+ "graph.trigger.sources.set": {
9611
+ nodeId: text,
9612
+ before: sourceFlowIds.optional(),
9613
+ value: sourceFlowIds.optional()
9614
+ },
9600
9615
  "binding.create": {
9601
9616
  bindingId: text,
9602
9617
  binding
@@ -6935,6 +6935,7 @@ var endpoint$3 = object({
6935
6935
  ])),
6936
6936
  successStatus: number()
6937
6937
  });
6938
+ var sourceFlowIds = array(text.min(1)).refine((ids) => new Set(ids).size === ids.length, "Duplicate source Flow ID.");
6938
6939
  var trigger = {
6939
6940
  name: text,
6940
6941
  description: text.optional(),
@@ -6992,6 +6993,11 @@ var node = union([
6992
6993
  ...trigger,
6993
6994
  kind: literal("manual")
6994
6995
  }),
6996
+ strictObject({
6997
+ ...trigger,
6998
+ kind: literal("error"),
6999
+ sourceFlowIds: sourceFlowIds.optional()
7000
+ }),
6995
7001
  object({
6996
7002
  ...trigger,
6997
7003
  kind: literal("webhook"),
@@ -7063,7 +7069,11 @@ var document = object({
7063
7069
  tasks: record$12(text, managed)
7064
7070
  });
7065
7071
  object({
7066
- modelVersion: union([literal(2), literal(4)]),
7072
+ modelVersion: union([
7073
+ literal(2),
7074
+ literal(4),
7075
+ literal(5)
7076
+ ]),
7067
7077
  document,
7068
7078
  modules: record$12(text, module)
7069
7079
  }).extend({
@@ -7071,6 +7081,11 @@ object({
7071
7081
  version: literal(1)
7072
7082
  });
7073
7083
  var shapes = {
7084
+ "graph.trigger.sources.set": {
7085
+ nodeId: text,
7086
+ before: sourceFlowIds.optional(),
7087
+ value: sourceFlowIds.optional()
7088
+ },
7074
7089
  "binding.create": {
7075
7090
  bindingId: text,
7076
7091
  binding
@@ -80,6 +80,8 @@ function artifact(value) {
80
80
  }
81
81
  function createEventProjector(platformRunId, nodeFailureCodes) {
82
82
  const flows = /* @__PURE__ */ new Map();
83
+ const paths = /* @__PURE__ */ new Map();
84
+ const jobs = /* @__PURE__ */ new Map();
83
85
  const nodeProgressBuckets = /* @__PURE__ */ new Map();
84
86
  const runProgressBuckets = /* @__PURE__ */ new Map();
85
87
  return async (value) => {
@@ -93,6 +95,9 @@ function createEventProjector(platformRunId, nodeFailureCodes) {
93
95
  flows.set(rawRunId, flowId);
94
96
  const parentRunId = event.parentRunId;
95
97
  if (parentRunId !== void 0 && (typeof parentRunId != "string" || parentRunId.length == 0)) throw new TypeError("Runtime run.started parentRunId must be a non-empty string when present.");
98
+ const parentJobId = optionalString(event.parentJobId, "Runtime run.started parentJobId");
99
+ const parentNode = parentRunId == null || parentJobId == null ? void 0 : jobs.get(JSON.stringify([parentRunId, parentJobId]));
100
+ paths.set(rawRunId, parentRunId == null ? [] : [...paths.get(parentRunId) ?? [], parentNode ?? flowId]);
96
101
  return {
97
102
  kind: "run.started",
98
103
  payload: {
@@ -120,7 +125,24 @@ function createEventProjector(platformRunId, nodeFailureCodes) {
120
125
  };
121
126
  }
122
127
  if (type == "run.completed" || type == "run.failed") {
123
- runId(event);
128
+ const rawRunId = runId(event);
129
+ if (type == "run.failed" && rawRunId == platformRunId && event.failure != null) {
130
+ const failure = object(event.failure, "Runtime terminal failure");
131
+ const context = nodeContext(failure, flows, platformRunId);
132
+ return {
133
+ kind: "node.failed",
134
+ payload: {
135
+ terminal: true,
136
+ nodeId: context.nodeId,
137
+ executionId: await context.executionId,
138
+ path: paths.get(context.rawRunId) ?? [],
139
+ error: {
140
+ code: nodeFailureCode(failure.code, nodeFailureCodes),
141
+ message: message(failure.message)
142
+ }
143
+ }
144
+ };
145
+ }
124
146
  return;
125
147
  }
126
148
  if (type == "node.started" || type == "node.progress" || type == "node.artifact" || type == "node.log" || type == "node.completed" || type == "node.failed") {
@@ -139,6 +161,7 @@ function createEventProjector(platformRunId, nodeFailureCodes) {
139
161
  value: object(event.outputs, "Runtime node.completed outputs")
140
162
  };
141
163
  case "node.started": {
164
+ jobs.set(JSON.stringify([context.rawRunId, event.jobId]), context.nodeId);
142
165
  const kind = nodeKind(event.nodeKind);
143
166
  const nodeTitle = optionalString(event.nodeTitle, "Runtime node.started nodeTitle");
144
167
  const operation = optionalString(event.operation, "Runtime node.started operation");
@@ -190,6 +213,7 @@ function createEventProjector(platformRunId, nodeFailureCodes) {
190
213
  kind: type,
191
214
  payload: {
192
215
  ...payload,
216
+ ...(paths.get(context.rawRunId)?.length ?? 0) == 0 ? {} : { path: paths.get(context.rawRunId) },
193
217
  error: {
194
218
  code: nodeFailureCode(event.code, nodeFailureCodes),
195
219
  message: message(event.message)
@@ -57,6 +57,9 @@ export type SchedulerEvent = {
57
57
  readonly message: string;
58
58
  readonly runId: string;
59
59
  readonly type: 'run.failed';
60
+ readonly failure?: Extract<SchedulerEvent, {
61
+ readonly type: 'node.failed';
62
+ }>;
60
63
  };
61
64
  export interface FlowRunResult {
62
65
  readonly kind: 'node-results';