@mastra/inngest 0.0.0-main-test-05-11-2025-2-20251106025330 → 0.0.0-main-test-2-20251127211532

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.
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { randomUUID } from 'crypto';
2
- import { ReadableStream } from 'stream/web';
2
+ import { ReadableStream, WritableStream } from 'stream/web';
3
3
  import { subscribe } from '@inngest/realtime';
4
4
  import { RequestContext } from '@mastra/core/di';
5
- import { wrapMastra, SpanType } from '@mastra/core/observability';
5
+ import { SpanType } from '@mastra/core/observability';
6
6
  import { ChunkFrom, WorkflowRunOutput } from '@mastra/core/stream';
7
7
  import { ToolStream, Tool } from '@mastra/core/tools';
8
- import { Run, Workflow, DefaultExecutionEngine, createDeprecationProxy, getStepResult, runCountDeprecationMessage, validateStepInput } from '@mastra/core/workflows';
8
+ import { Run, createTimeTravelExecutionParams, Workflow, DefaultExecutionEngine, createDeprecationProxy, getStepResult, runCountDeprecationMessage, validateStepInput, validateStepResumeData, validateStepSuspendData } from '@mastra/core/workflows';
9
9
  import { EMITTER_SYMBOL, STREAM_FORMAT_SYMBOL } from '@mastra/core/workflows/_constants';
10
10
  import { NonRetriableError, RetryAfterError } from 'inngest';
11
11
  import { serve as serve$1 } from 'inngest/hono';
@@ -99,7 +99,8 @@ var InngestRun = class extends Run {
99
99
  resourceId: this.resourceId,
100
100
  snapshot: {
101
101
  ...snapshot,
102
- status: "canceled"
102
+ status: "canceled",
103
+ value: snapshot.value
103
104
  }
104
105
  });
105
106
  }
@@ -121,14 +122,15 @@ var InngestRun = class extends Run {
121
122
  snapshot: {
122
123
  runId: this.runId,
123
124
  serializedStepGraph: this.serializedStepGraph,
125
+ status: "running",
124
126
  value: {},
125
127
  context: {},
126
128
  activePaths: [],
127
129
  suspendedPaths: {},
130
+ activeStepsPath: {},
128
131
  resumeLabels: {},
129
132
  waitingPaths: {},
130
- timestamp: Date.now(),
131
- status: "running"
133
+ timestamp: Date.now()
132
134
  }
133
135
  });
134
136
  const inputDataToUse = await this._validateInput(inputData);
@@ -172,9 +174,14 @@ var InngestRun = class extends Run {
172
174
  }
173
175
  async _resume(params) {
174
176
  const storage = this.#mastra?.getStorage();
175
- const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
176
- (step) => typeof step === "string" ? step : step?.id
177
- );
177
+ let steps = [];
178
+ if (typeof params.step === "string") {
179
+ steps = params.step.split(".");
180
+ } else {
181
+ steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
182
+ (step) => typeof step === "string" ? step : step?.id
183
+ );
184
+ }
178
185
  const snapshot = await storage?.loadWorkflowSnapshot({
179
186
  workflowName: this.workflowId,
180
187
  runId: this.runId
@@ -193,8 +200,7 @@ var InngestRun = class extends Run {
193
200
  steps,
194
201
  stepResults: snapshot?.context,
195
202
  resumePayload: resumeDataToUse,
196
- // @ts-ignore
197
- resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
203
+ resumePath: steps?.[0] ? snapshot?.suspendedPaths?.[steps?.[0]] : void 0
198
204
  }
199
205
  }
200
206
  });
@@ -209,6 +215,97 @@ var InngestRun = class extends Run {
209
215
  }
210
216
  return result;
211
217
  }
218
+ async timeTravel(params) {
219
+ const p = this._timeTravel(params).then((result) => {
220
+ if (result.status !== "suspended") {
221
+ this.closeStreamAction?.().catch(() => {
222
+ });
223
+ }
224
+ return result;
225
+ });
226
+ this.executionResults = p;
227
+ return p;
228
+ }
229
+ async _timeTravel(params) {
230
+ if (!params.step || Array.isArray(params.step) && params.step?.length === 0) {
231
+ throw new Error("Step is required and must be a valid step or array of steps");
232
+ }
233
+ let steps = [];
234
+ if (typeof params.step === "string") {
235
+ steps = params.step.split(".");
236
+ } else {
237
+ steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
238
+ (step) => typeof step === "string" ? step : step?.id
239
+ );
240
+ }
241
+ if (steps.length === 0) {
242
+ throw new Error("No steps provided to timeTravel");
243
+ }
244
+ const storage = this.#mastra?.getStorage();
245
+ const snapshot = await storage?.loadWorkflowSnapshot({
246
+ workflowName: this.workflowId,
247
+ runId: this.runId
248
+ });
249
+ if (!snapshot) {
250
+ await storage?.persistWorkflowSnapshot({
251
+ workflowName: this.workflowId,
252
+ runId: this.runId,
253
+ resourceId: this.resourceId,
254
+ snapshot: {
255
+ runId: this.runId,
256
+ serializedStepGraph: this.serializedStepGraph,
257
+ status: "pending",
258
+ value: {},
259
+ context: {},
260
+ activePaths: [],
261
+ suspendedPaths: {},
262
+ activeStepsPath: {},
263
+ resumeLabels: {},
264
+ waitingPaths: {},
265
+ timestamp: Date.now()
266
+ }
267
+ });
268
+ }
269
+ if (snapshot?.status === "running") {
270
+ throw new Error("This workflow run is still running, cannot time travel");
271
+ }
272
+ let inputDataToUse = params.inputData;
273
+ if (inputDataToUse && steps.length === 1) {
274
+ inputDataToUse = await this._validateTimetravelInputData(params.inputData, this.workflowSteps[steps[0]]);
275
+ }
276
+ const timeTravelData = createTimeTravelExecutionParams({
277
+ steps,
278
+ inputData: inputDataToUse,
279
+ resumeData: params.resumeData,
280
+ context: params.context,
281
+ nestedStepsContext: params.nestedStepsContext,
282
+ snapshot: snapshot ?? { context: {} },
283
+ graph: this.executionGraph,
284
+ initialState: params.initialState
285
+ });
286
+ const eventOutput = await this.inngest.send({
287
+ name: `workflow.${this.workflowId}`,
288
+ data: {
289
+ initialState: timeTravelData.state,
290
+ runId: this.runId,
291
+ workflowId: this.workflowId,
292
+ stepResults: timeTravelData.stepResults,
293
+ timeTravel: timeTravelData,
294
+ tracingOptions: params.tracingOptions,
295
+ outputOptions: params.outputOptions
296
+ }
297
+ });
298
+ const eventId = eventOutput.ids[0];
299
+ if (!eventId) {
300
+ throw new Error("Event ID is not set");
301
+ }
302
+ const runOutput = await this.getRunOutput(eventId);
303
+ const result = runOutput?.output?.result;
304
+ if (result.status === "failed") {
305
+ result.error = new Error(result.error);
306
+ }
307
+ return result;
308
+ }
212
309
  watch(cb) {
213
310
  let active = true;
214
311
  const streamPromise = subscribe(
@@ -235,14 +332,14 @@ var InngestRun = class extends Run {
235
332
  streamLegacy({ inputData, requestContext } = {}) {
236
333
  const { readable, writable } = new TransformStream();
237
334
  const writer = writable.getWriter();
335
+ void writer.write({
336
+ // @ts-ignore
337
+ type: "start",
338
+ // @ts-ignore
339
+ payload: { runId: this.runId }
340
+ });
238
341
  const unwatch = this.watch(async (event) => {
239
342
  try {
240
- await writer.write({
241
- // @ts-ignore
242
- type: "start",
243
- // @ts-ignore
244
- payload: { runId: this.runId }
245
- });
246
343
  const e = {
247
344
  ...event,
248
345
  type: event.type.replace("workflow-", "")
@@ -358,6 +455,75 @@ var InngestRun = class extends Run {
358
455
  streamVNext(args = {}) {
359
456
  return this.stream(args);
360
457
  }
458
+ timeTravelStream({
459
+ inputData,
460
+ resumeData,
461
+ initialState,
462
+ step,
463
+ context,
464
+ nestedStepsContext,
465
+ requestContext,
466
+ tracingOptions,
467
+ outputOptions
468
+ }) {
469
+ this.closeStreamAction = async () => {
470
+ };
471
+ const self = this;
472
+ const stream = new ReadableStream({
473
+ async start(controller) {
474
+ const unwatch = self.watch(async ({ type, from = ChunkFrom.WORKFLOW, payload }) => {
475
+ controller.enqueue({
476
+ type,
477
+ runId: self.runId,
478
+ from,
479
+ payload: {
480
+ stepName: payload?.id,
481
+ ...payload
482
+ }
483
+ });
484
+ });
485
+ self.closeStreamAction = async () => {
486
+ unwatch();
487
+ try {
488
+ await controller.close();
489
+ } catch (err) {
490
+ console.error("Error closing stream:", err);
491
+ }
492
+ };
493
+ const executionResultsPromise = self._timeTravel({
494
+ inputData,
495
+ step,
496
+ context,
497
+ nestedStepsContext,
498
+ resumeData,
499
+ initialState,
500
+ requestContext,
501
+ tracingOptions,
502
+ outputOptions
503
+ });
504
+ self.executionResults = executionResultsPromise;
505
+ let executionResults;
506
+ try {
507
+ executionResults = await executionResultsPromise;
508
+ self.closeStreamAction?.().catch(() => {
509
+ });
510
+ if (self.streamOutput) {
511
+ self.streamOutput.updateResults(executionResults);
512
+ }
513
+ } catch (err) {
514
+ self.streamOutput?.rejectResults(err);
515
+ self.closeStreamAction?.().catch(() => {
516
+ });
517
+ }
518
+ }
519
+ });
520
+ this.streamOutput = new WorkflowRunOutput({
521
+ runId: this.runId,
522
+ workflowId: this.workflowId,
523
+ stream
524
+ });
525
+ return this.streamOutput;
526
+ }
361
527
  };
362
528
  var InngestWorkflow = class _InngestWorkflow extends Workflow {
363
529
  #mastra;
@@ -367,6 +533,7 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
367
533
  constructor(params, inngest) {
368
534
  const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
369
535
  super(workflowParams);
536
+ this.engineType = "inngest";
370
537
  const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
371
538
  ([_, value]) => value !== void 0
372
539
  );
@@ -422,7 +589,9 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
422
589
  mastra: this.#mastra,
423
590
  retryConfig: this.retryConfig,
424
591
  cleanup: () => this.runs.delete(runIdToUse),
425
- workflowSteps: this.steps
592
+ workflowSteps: this.steps,
593
+ workflowEngineType: this.engineType,
594
+ validateInputs: this.options.validateInputs
426
595
  },
427
596
  this.inngest
428
597
  );
@@ -443,13 +612,13 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
443
612
  value: {},
444
613
  context: {},
445
614
  activePaths: [],
615
+ activeStepsPath: {},
446
616
  waitingPaths: {},
447
617
  serializedStepGraph: this.serializedStepGraph,
448
618
  suspendedPaths: {},
449
619
  resumeLabels: {},
450
620
  result: void 0,
451
621
  error: void 0,
452
- // @ts-ignore
453
622
  timestamp: Date.now()
454
623
  }
455
624
  });
@@ -463,15 +632,14 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
463
632
  this.function = this.inngest.createFunction(
464
633
  {
465
634
  id: `workflow.${this.id}`,
466
- // @ts-ignore
467
- retries: this.retryConfig?.attempts ?? 0,
635
+ retries: Math.min(this.retryConfig?.attempts ?? 0, 20),
468
636
  cancelOn: [{ event: `cancel.workflow.${this.id}` }],
469
637
  // Spread flow control configuration
470
638
  ...this.flowControlConfig
471
639
  },
472
640
  { event: `workflow.${this.id}` },
473
641
  async ({ event, step, attempt, publish }) => {
474
- let { inputData, initialState, runId, resourceId, resume, outputOptions, format } = event.data;
642
+ let { inputData, initialState, runId, resourceId, resume, outputOptions, format, timeTravel } = event.data;
475
643
  if (!runId) {
476
644
  runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
477
645
  return randomUUID();
@@ -513,6 +681,7 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
513
681
  requestContext: new RequestContext(),
514
682
  // TODO
515
683
  resume,
684
+ timeTravel,
516
685
  format,
517
686
  abortController: new AbortController(),
518
687
  // currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
@@ -565,13 +734,11 @@ function createStep(params, agentOptions) {
565
734
  return {
566
735
  id: params.name,
567
736
  description: params.getDescription(),
568
- // @ts-ignore
569
737
  inputSchema: z.object({
570
738
  prompt: z.string()
571
739
  // resourceId: z.string().optional(),
572
740
  // threadId: z.string().optional(),
573
741
  }),
574
- // @ts-ignore
575
742
  outputSchema: z.object({
576
743
  text: z.string()
577
744
  }),
@@ -661,20 +828,38 @@ function createStep(params, agentOptions) {
661
828
  }
662
829
  return {
663
830
  // TODO: tool probably should have strong id type
664
- // @ts-ignore
665
831
  id: params.id,
666
832
  description: params.description,
667
833
  inputSchema: params.inputSchema,
668
834
  outputSchema: params.outputSchema,
669
- execute: async ({ inputData, mastra, requestContext, tracingContext, suspend, resumeData }) => {
670
- return params.execute({
671
- context: inputData,
672
- mastra: wrapMastra(mastra, tracingContext),
835
+ suspendSchema: params.suspendSchema,
836
+ resumeSchema: params.resumeSchema,
837
+ execute: async ({
838
+ inputData,
839
+ mastra,
840
+ requestContext,
841
+ tracingContext,
842
+ suspend,
843
+ resumeData,
844
+ runId,
845
+ workflowId,
846
+ state,
847
+ setState
848
+ }) => {
849
+ const toolContext = {
850
+ mastra,
673
851
  requestContext,
674
852
  tracingContext,
675
- suspend,
676
- resumeData
677
- });
853
+ workflow: {
854
+ runId,
855
+ resumeData,
856
+ suspend,
857
+ workflowId,
858
+ state,
859
+ setState
860
+ }
861
+ };
862
+ return params.execute(inputData, toolContext);
678
863
  },
679
864
  component: "TOOL"
680
865
  };
@@ -708,6 +893,8 @@ function init(inngest) {
708
893
  suspendSchema: step.suspendSchema,
709
894
  stateSchema: step.stateSchema,
710
895
  execute: step.execute,
896
+ retries: step.retries,
897
+ scorers: step.scorers,
711
898
  component: step.component
712
899
  };
713
900
  },
@@ -717,7 +904,8 @@ function init(inngest) {
717
904
  inputSchema: workflow.inputSchema,
718
905
  outputSchema: workflow.outputSchema,
719
906
  steps: workflow.stepDefs,
720
- mastra: workflow.mastra
907
+ mastra: workflow.mastra,
908
+ options: workflow.options
721
909
  });
722
910
  wf.setStepFlow(workflow.stepGraph);
723
911
  wf.commit();
@@ -947,6 +1135,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
947
1135
  stepResults,
948
1136
  executionContext,
949
1137
  resume,
1138
+ timeTravel,
950
1139
  prevOutput,
951
1140
  emitter,
952
1141
  abortController,
@@ -967,7 +1156,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
967
1156
  const { inputData, validationError } = await validateStepInput({
968
1157
  prevOutput,
969
1158
  step,
970
- validateInputs: this.options?.validateInputs ?? false
1159
+ validateInputs: this.options?.validateInputs ?? true
971
1160
  });
972
1161
  const startedAt = await this.inngestStep.run(
973
1162
  `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
@@ -989,9 +1178,10 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
989
1178
  const isResume = !!resume?.steps?.length;
990
1179
  let result;
991
1180
  let runId;
1181
+ const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
992
1182
  try {
993
1183
  if (isResume) {
994
- runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? randomUUID();
1184
+ runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? randomUUID();
995
1185
  const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
996
1186
  workflowName: step.id,
997
1187
  runId
@@ -1007,8 +1197,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1007
1197
  steps: resume.steps.slice(1),
1008
1198
  stepResults: snapshot?.context,
1009
1199
  resumePayload: resume.resumePayload,
1010
- // @ts-ignore
1011
- resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
1200
+ resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
1012
1201
  },
1013
1202
  outputOptions: { includeState: true }
1014
1203
  }
@@ -1016,6 +1205,32 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1016
1205
  result = invokeResp.result;
1017
1206
  runId = invokeResp.runId;
1018
1207
  executionContext.state = invokeResp.result.state;
1208
+ } else if (isTimeTravel) {
1209
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
1210
+ workflowName: step.id,
1211
+ runId: executionContext.runId
1212
+ }) ?? { context: {} };
1213
+ const timeTravelParams = createTimeTravelExecutionParams({
1214
+ steps: timeTravel.steps.slice(1),
1215
+ inputData: timeTravel.inputData,
1216
+ resumeData: timeTravel.resumeData,
1217
+ context: timeTravel.nestedStepResults?.[step.id] ?? {},
1218
+ nestedStepsContext: timeTravel.nestedStepResults ?? {},
1219
+ snapshot,
1220
+ graph: step.buildExecutionGraph()
1221
+ });
1222
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1223
+ function: step.getFunction(),
1224
+ data: {
1225
+ timeTravel: timeTravelParams,
1226
+ initialState: executionContext.state ?? {},
1227
+ runId: executionContext.runId,
1228
+ outputOptions: { includeState: true }
1229
+ }
1230
+ });
1231
+ result = invokeResp.result;
1232
+ runId = invokeResp.runId;
1233
+ executionContext.state = invokeResp.result.state;
1019
1234
  } else {
1020
1235
  const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1021
1236
  function: step.getFunction(),
@@ -1128,14 +1343,32 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1128
1343
  let execResults;
1129
1344
  let suspended;
1130
1345
  let bailed;
1346
+ const { resumeData: timeTravelResumeData, validationError: timeTravelResumeValidationError } = await validateStepResumeData({
1347
+ resumeData: timeTravel?.stepResults[step.id]?.status === "suspended" ? timeTravel?.resumeData : void 0,
1348
+ step
1349
+ });
1350
+ let resumeDataToUse;
1351
+ if (timeTravelResumeData && !timeTravelResumeValidationError) {
1352
+ resumeDataToUse = timeTravelResumeData;
1353
+ } else if (timeTravelResumeData && timeTravelResumeValidationError) {
1354
+ this.logger.warn("Time travel resume data validation failed", {
1355
+ stepId: step.id,
1356
+ error: timeTravelResumeValidationError.message
1357
+ });
1358
+ } else if (resume?.steps[0] === step.id) {
1359
+ resumeDataToUse = resume?.resumePayload;
1360
+ }
1131
1361
  try {
1132
1362
  if (validationError) {
1133
1363
  throw validationError;
1134
1364
  }
1365
+ const retryCount = this.getOrGenerateRetryCount(step.id);
1135
1366
  const result = await step.execute({
1136
1367
  runId: executionContext.runId,
1368
+ workflowId: executionContext.workflowId,
1137
1369
  mastra: this.mastra,
1138
1370
  requestContext,
1371
+ retryCount,
1139
1372
  writer: new ToolStream(
1140
1373
  {
1141
1374
  prefix: "workflow-step",
@@ -1150,13 +1383,20 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1150
1383
  executionContext.state = state;
1151
1384
  },
1152
1385
  inputData,
1153
- resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1386
+ resumeData: resumeDataToUse,
1154
1387
  tracingContext: {
1155
1388
  currentSpan: stepSpan
1156
1389
  },
1157
1390
  getInitData: () => stepResults?.input,
1158
1391
  getStepResult: getStepResult.bind(this, stepResults),
1159
1392
  suspend: async (suspendPayload, suspendOptions) => {
1393
+ const { suspendData, validationError: validationError2 } = await validateStepSuspendData({
1394
+ suspendData: suspendPayload,
1395
+ step
1396
+ });
1397
+ if (validationError2) {
1398
+ throw validationError2;
1399
+ }
1160
1400
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1161
1401
  if (suspendOptions?.resumeLabel) {
1162
1402
  const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
@@ -1167,16 +1407,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1167
1407
  };
1168
1408
  }
1169
1409
  }
1170
- suspended = { payload: suspendPayload };
1410
+ suspended = { payload: suspendData };
1171
1411
  },
1172
1412
  bail: (result2) => {
1173
1413
  bailed = { payload: result2 };
1174
1414
  },
1175
- resume: {
1176
- steps: resume?.steps?.slice(1) || [],
1177
- resumePayload: resume?.resumePayload,
1178
- // @ts-ignore
1179
- runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
1415
+ abort: () => {
1416
+ abortController?.abort();
1180
1417
  },
1181
1418
  [EMITTER_SYMBOL]: emitter,
1182
1419
  [STREAM_FORMAT_SYMBOL]: executionContext.format,
@@ -1192,8 +1429,8 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1192
1429
  startedAt,
1193
1430
  endedAt,
1194
1431
  payload: inputData,
1195
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1196
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1432
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1433
+ resumePayload: resumeDataToUse
1197
1434
  };
1198
1435
  } catch (e) {
1199
1436
  const stepFailure = {
@@ -1202,8 +1439,8 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1202
1439
  error: e instanceof Error ? e.message : String(e),
1203
1440
  endedAt: Date.now(),
1204
1441
  startedAt,
1205
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1206
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1442
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1443
+ resumePayload: resumeDataToUse
1207
1444
  };
1208
1445
  execResults = stepFailure;
1209
1446
  const fallbackErrorMessage = `Step ${step.id} failed`;
@@ -1216,11 +1453,12 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1216
1453
  execResults = {
1217
1454
  status: "suspended",
1218
1455
  suspendPayload: suspended.payload,
1456
+ ...execResults.output ? { suspendOutput: execResults.output } : {},
1219
1457
  payload: inputData,
1220
1458
  suspendedAt: Date.now(),
1221
1459
  startedAt,
1222
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1223
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1460
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1461
+ resumePayload: resumeDataToUse
1224
1462
  };
1225
1463
  } else if (bailed) {
1226
1464
  execResults = {
@@ -1266,6 +1504,20 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1266
1504
  startedAt,
1267
1505
  endedAt: Date.now()
1268
1506
  };
1507
+ await emitter.emit("watch", {
1508
+ type: "workflow-step-result",
1509
+ payload: {
1510
+ id: step.id,
1511
+ ...stepFailure
1512
+ }
1513
+ });
1514
+ await emitter.emit("watch", {
1515
+ type: "workflow-step-finish",
1516
+ payload: {
1517
+ id: step.id,
1518
+ metadata: {}
1519
+ }
1520
+ });
1269
1521
  stepRes = {
1270
1522
  result: stepFailure,
1271
1523
  executionContext,
@@ -1293,7 +1545,6 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1293
1545
  });
1294
1546
  }
1295
1547
  Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
1296
- Object.assign(stepResults, stepRes.stepResults);
1297
1548
  executionContext.state = stepRes.executionContext.state;
1298
1549
  return stepRes.result;
1299
1550
  }
@@ -1321,17 +1572,17 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1321
1572
  resourceId,
1322
1573
  snapshot: {
1323
1574
  runId,
1575
+ status: workflowStatus,
1324
1576
  value: executionContext.state,
1325
1577
  context: stepResults,
1326
- activePaths: [],
1578
+ activePaths: executionContext.executionPath,
1579
+ activeStepsPath: executionContext.activeStepsPath,
1327
1580
  suspendedPaths: executionContext.suspendedPaths,
1328
1581
  resumeLabels: executionContext.resumeLabels,
1329
1582
  waitingPaths: {},
1330
1583
  serializedStepGraph,
1331
- status: workflowStatus,
1332
1584
  result,
1333
1585
  error,
1334
- // @ts-ignore
1335
1586
  timestamp: Date.now()
1336
1587
  }
1337
1588
  });
@@ -1344,6 +1595,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1344
1595
  entry,
1345
1596
  prevOutput,
1346
1597
  stepResults,
1598
+ timeTravel,
1347
1599
  resume,
1348
1600
  executionContext,
1349
1601
  emitter,
@@ -1462,10 +1714,12 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1462
1714
  prevOutput,
1463
1715
  stepResults,
1464
1716
  resume,
1717
+ timeTravel,
1465
1718
  executionContext: {
1466
1719
  workflowId,
1467
1720
  runId,
1468
1721
  executionPath: [...executionContext.executionPath, index],
1722
+ activeStepsPath: executionContext.activeStepsPath,
1469
1723
  suspendedPaths: executionContext.suspendedPaths,
1470
1724
  resumeLabels: executionContext.resumeLabels,
1471
1725
  retryConfig: executionContext.retryConfig,
@@ -1489,13 +1743,19 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1489
1743
  if (hasFailed) {
1490
1744
  execResults = { status: "failed", error: hasFailed.error };
1491
1745
  } else if (hasSuspended) {
1492
- execResults = { status: "suspended", suspendPayload: hasSuspended.suspendPayload };
1746
+ execResults = {
1747
+ status: "suspended",
1748
+ suspendPayload: hasSuspended.suspendPayload,
1749
+ ...hasSuspended.suspendOutput ? { suspendOutput: hasSuspended.suspendOutput } : {}
1750
+ };
1493
1751
  } else {
1494
1752
  execResults = {
1495
1753
  status: "success",
1496
1754
  output: results.reduce((acc, result, index) => {
1497
1755
  if (result.status === "success") {
1498
- acc[stepsToRun[index].step.id] = result.output;
1756
+ if ("step" in stepsToRun[index]) {
1757
+ acc[stepsToRun[index].step.id] = result.output;
1758
+ }
1499
1759
  }
1500
1760
  return acc;
1501
1761
  }, {})