@mastra/inngest 0.0.0-fix-backport-setserver-20251201151948 → 0.0.0-fix-request-context-as-query-key-20251209130646

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.cjs CHANGED
@@ -1,43 +1,302 @@
1
1
  'use strict';
2
2
 
3
- var crypto = require('crypto');
4
- var web = require('stream/web');
5
- var realtime = require('@inngest/realtime');
6
- var aiTracing = require('@mastra/core/ai-tracing');
7
- var di = require('@mastra/core/di');
8
- var stream = require('@mastra/core/stream');
9
3
  var tools = require('@mastra/core/tools');
10
4
  var workflows = require('@mastra/core/workflows');
11
5
  var _constants = require('@mastra/core/workflows/_constants');
6
+ var zod = require('zod');
7
+ var crypto = require('crypto');
8
+ var web = require('stream/web');
9
+ var di = require('@mastra/core/di');
12
10
  var inngest = require('inngest');
11
+ var realtime = require('@inngest/realtime');
12
+ var stream = require('@mastra/core/stream');
13
13
  var hono = require('inngest/hono');
14
- var zod = require('zod');
15
14
 
16
15
  // src/index.ts
17
- function serve({
18
- mastra,
19
- inngest,
20
- functions: userFunctions = [],
21
- registerOptions
22
- }) {
23
- const wfs = mastra.getWorkflows();
24
- const workflowFunctions = Array.from(
25
- new Set(
26
- Object.values(wfs).flatMap((wf) => {
27
- if (wf instanceof InngestWorkflow) {
28
- wf.__registerMastra(mastra);
29
- return wf.getFunctions();
16
+ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
17
+ inngestStep;
18
+ inngestAttempts;
19
+ constructor(mastra, inngestStep, inngestAttempts = 0, options) {
20
+ super({ mastra, options });
21
+ this.inngestStep = inngestStep;
22
+ this.inngestAttempts = inngestAttempts;
23
+ }
24
+ // =============================================================================
25
+ // Hook Overrides
26
+ // =============================================================================
27
+ /**
28
+ * Format errors with stack traces for better debugging in Inngest
29
+ */
30
+ formatResultError(error, lastOutput) {
31
+ if (error instanceof Error) {
32
+ return error.stack ?? error.message;
33
+ }
34
+ const outputError = lastOutput?.error;
35
+ if (outputError instanceof Error) {
36
+ return outputError.message;
37
+ }
38
+ return outputError ?? error ?? "Unknown error";
39
+ }
40
+ /**
41
+ * Detect InngestWorkflow instances for special nested workflow handling
42
+ */
43
+ isNestedWorkflowStep(step) {
44
+ return step instanceof InngestWorkflow;
45
+ }
46
+ /**
47
+ * Inngest requires requestContext serialization for memoization.
48
+ * When steps are replayed, the original function doesn't re-execute,
49
+ * so requestContext modifications must be captured and restored.
50
+ */
51
+ requiresDurableContextSerialization() {
52
+ return true;
53
+ }
54
+ /**
55
+ * Execute a step with retry logic for Inngest.
56
+ * Retries are handled via step-level retry (RetryAfterError thrown INSIDE step.run()).
57
+ * After retries exhausted, error propagates here and we return a failed result.
58
+ */
59
+ async executeStepWithRetry(stepId, runStep, params) {
60
+ try {
61
+ const result = await this.wrapDurableOperation(stepId, runStep, { delay: params.delay });
62
+ return { ok: true, result };
63
+ } catch (e) {
64
+ const cause = e?.cause;
65
+ if (cause?.status === "failed") {
66
+ params.stepSpan?.error({
67
+ error: e,
68
+ attributes: { status: "failed" }
69
+ });
70
+ return { ok: false, error: cause };
71
+ }
72
+ const errorMessage = e instanceof Error ? e.message : String(e);
73
+ params.stepSpan?.error({
74
+ error: e,
75
+ attributes: { status: "failed" }
76
+ });
77
+ return {
78
+ ok: false,
79
+ error: {
80
+ status: "failed",
81
+ error: `Error: ${errorMessage}`,
82
+ endedAt: Date.now()
30
83
  }
31
- return [];
32
- })
33
- )
34
- );
35
- return hono.serve({
36
- ...registerOptions,
37
- client: inngest,
38
- functions: [...workflowFunctions, ...userFunctions]
39
- });
40
- }
84
+ };
85
+ }
86
+ }
87
+ /**
88
+ * Use Inngest's sleep primitive for durability
89
+ */
90
+ async executeSleepDuration(duration, sleepId, workflowId) {
91
+ await this.inngestStep.sleep(`workflow.${workflowId}.sleep.${sleepId}`, duration < 0 ? 0 : duration);
92
+ }
93
+ /**
94
+ * Use Inngest's sleepUntil primitive for durability
95
+ */
96
+ async executeSleepUntilDate(date, sleepUntilId, workflowId) {
97
+ await this.inngestStep.sleepUntil(`workflow.${workflowId}.sleepUntil.${sleepUntilId}`, date);
98
+ }
99
+ /**
100
+ * Wrap durable operations in Inngest step.run() for durability.
101
+ * If retryConfig is provided, throws RetryAfterError INSIDE step.run() to trigger
102
+ * Inngest's step-level retry mechanism (not function-level retry).
103
+ */
104
+ async wrapDurableOperation(operationId, operationFn, retryConfig) {
105
+ return this.inngestStep.run(operationId, async () => {
106
+ try {
107
+ return await operationFn();
108
+ } catch (e) {
109
+ if (retryConfig) {
110
+ const errorMessage = e instanceof Error ? e.message : String(e);
111
+ throw new inngest.RetryAfterError(errorMessage, retryConfig.delay, {
112
+ cause: {
113
+ status: "failed",
114
+ error: `Error: ${errorMessage}`,
115
+ endedAt: Date.now()
116
+ }
117
+ });
118
+ }
119
+ throw e;
120
+ }
121
+ });
122
+ }
123
+ /**
124
+ * Provide Inngest step primitive in engine context
125
+ */
126
+ getEngineContext() {
127
+ return { step: this.inngestStep };
128
+ }
129
+ /**
130
+ * Execute nested InngestWorkflow using inngestStep.invoke() for durability.
131
+ * This MUST be called directly (not inside step.run()) due to Inngest constraints.
132
+ */
133
+ async executeWorkflowStep(params) {
134
+ if (!(params.step instanceof InngestWorkflow)) {
135
+ return null;
136
+ }
137
+ const { step, stepResults, executionContext, resume, timeTravel, prevOutput, inputData, emitter, startedAt } = params;
138
+ const isResume = !!resume?.steps?.length;
139
+ let result;
140
+ let runId;
141
+ const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
142
+ try {
143
+ if (isResume) {
144
+ runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
145
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
146
+ workflowName: step.id,
147
+ runId
148
+ });
149
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
150
+ function: step.getFunction(),
151
+ data: {
152
+ inputData,
153
+ initialState: executionContext.state ?? snapshot?.value ?? {},
154
+ runId,
155
+ resume: {
156
+ runId,
157
+ steps: resume.steps.slice(1),
158
+ stepResults: snapshot?.context,
159
+ resumePayload: resume.resumePayload,
160
+ resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
161
+ },
162
+ outputOptions: { includeState: true }
163
+ }
164
+ });
165
+ result = invokeResp.result;
166
+ runId = invokeResp.runId;
167
+ executionContext.state = invokeResp.result.state;
168
+ } else if (isTimeTravel) {
169
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
170
+ workflowName: step.id,
171
+ runId: executionContext.runId
172
+ }) ?? { context: {} };
173
+ const timeTravelParams = workflows.createTimeTravelExecutionParams({
174
+ steps: timeTravel.steps.slice(1),
175
+ inputData: timeTravel.inputData,
176
+ resumeData: timeTravel.resumeData,
177
+ context: timeTravel.nestedStepResults?.[step.id] ?? {},
178
+ nestedStepsContext: timeTravel.nestedStepResults ?? {},
179
+ snapshot,
180
+ graph: step.buildExecutionGraph()
181
+ });
182
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
183
+ function: step.getFunction(),
184
+ data: {
185
+ timeTravel: timeTravelParams,
186
+ initialState: executionContext.state ?? {},
187
+ runId: executionContext.runId,
188
+ outputOptions: { includeState: true }
189
+ }
190
+ });
191
+ result = invokeResp.result;
192
+ runId = invokeResp.runId;
193
+ executionContext.state = invokeResp.result.state;
194
+ } else {
195
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
196
+ function: step.getFunction(),
197
+ data: {
198
+ inputData,
199
+ initialState: executionContext.state ?? {},
200
+ outputOptions: { includeState: true }
201
+ }
202
+ });
203
+ result = invokeResp.result;
204
+ runId = invokeResp.runId;
205
+ executionContext.state = invokeResp.result.state;
206
+ }
207
+ } catch (e) {
208
+ const errorCause = e?.cause;
209
+ if (errorCause && typeof errorCause === "object") {
210
+ result = errorCause;
211
+ runId = errorCause.runId || crypto.randomUUID();
212
+ } else {
213
+ runId = crypto.randomUUID();
214
+ result = {
215
+ status: "failed",
216
+ error: e instanceof Error ? e : new Error(String(e)),
217
+ steps: {},
218
+ input: inputData
219
+ };
220
+ }
221
+ }
222
+ const res = await this.inngestStep.run(
223
+ `workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
224
+ async () => {
225
+ if (result.status === "failed") {
226
+ await emitter.emit("watch", {
227
+ type: "workflow-step-result",
228
+ payload: {
229
+ id: step.id,
230
+ status: "failed",
231
+ error: result?.error,
232
+ payload: prevOutput
233
+ }
234
+ });
235
+ return { executionContext, result: { status: "failed", error: result?.error } };
236
+ } else if (result.status === "suspended") {
237
+ const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
238
+ const stepRes = stepResult;
239
+ return stepRes?.status === "suspended";
240
+ });
241
+ for (const [stepName, stepResult] of suspendedSteps) {
242
+ const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
243
+ executionContext.suspendedPaths[step.id] = executionContext.executionPath;
244
+ await emitter.emit("watch", {
245
+ type: "workflow-step-suspended",
246
+ payload: {
247
+ id: step.id,
248
+ status: "suspended"
249
+ }
250
+ });
251
+ return {
252
+ executionContext,
253
+ result: {
254
+ status: "suspended",
255
+ payload: stepResult.payload,
256
+ suspendPayload: {
257
+ ...stepResult?.suspendPayload,
258
+ __workflow_meta: { runId, path: suspendPath }
259
+ }
260
+ }
261
+ };
262
+ }
263
+ return {
264
+ executionContext,
265
+ result: {
266
+ status: "suspended",
267
+ payload: {}
268
+ }
269
+ };
270
+ }
271
+ await emitter.emit("watch", {
272
+ type: "workflow-step-result",
273
+ payload: {
274
+ id: step.id,
275
+ status: "success",
276
+ output: result?.result
277
+ }
278
+ });
279
+ await emitter.emit("watch", {
280
+ type: "workflow-step-finish",
281
+ payload: {
282
+ id: step.id,
283
+ metadata: {}
284
+ }
285
+ });
286
+ return { executionContext, result: { status: "success", output: result?.result } };
287
+ }
288
+ );
289
+ Object.assign(executionContext, res.executionContext);
290
+ return {
291
+ ...res.result,
292
+ startedAt,
293
+ endedAt: Date.now(),
294
+ payload: inputData,
295
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
296
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
297
+ };
298
+ }
299
+ };
41
300
  var InngestRun = class extends workflows.Run {
42
301
  inngest;
43
302
  serializedStepGraph;
@@ -59,11 +318,12 @@ var InngestRun = class extends workflows.Run {
59
318
  }
60
319
  async getRunOutput(eventId) {
61
320
  let runs = await this.getRuns(eventId);
321
+ const storage = this.#mastra?.getStorage();
62
322
  while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
63
323
  await new Promise((resolve) => setTimeout(resolve, 1e3));
64
324
  runs = await this.getRuns(eventId);
65
325
  if (runs?.[0]?.status === "Failed") {
66
- const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
326
+ const snapshot = await storage?.loadWorkflowSnapshot({
67
327
  workflowName: this.workflowId,
68
328
  runId: this.runId
69
329
  });
@@ -72,7 +332,7 @@ var InngestRun = class extends workflows.Run {
72
332
  };
73
333
  }
74
334
  if (runs?.[0]?.status === "Cancelled") {
75
- const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
335
+ const snapshot = await storage?.loadWorkflowSnapshot({
76
336
  workflowName: this.workflowId,
77
337
  runId: this.runId
78
338
  });
@@ -81,38 +341,41 @@ var InngestRun = class extends workflows.Run {
81
341
  }
82
342
  return runs?.[0];
83
343
  }
84
- async sendEvent(event, data) {
85
- await this.inngest.send({
86
- name: `user-event-${event}`,
87
- data
88
- });
89
- }
90
344
  async cancel() {
345
+ const storage = this.#mastra?.getStorage();
91
346
  await this.inngest.send({
92
347
  name: `cancel.workflow.${this.workflowId}`,
93
348
  data: {
94
349
  runId: this.runId
95
350
  }
96
351
  });
97
- const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
352
+ const snapshot = await storage?.loadWorkflowSnapshot({
98
353
  workflowName: this.workflowId,
99
354
  runId: this.runId
100
355
  });
101
356
  if (snapshot) {
102
- await this.#mastra?.storage?.persistWorkflowSnapshot({
357
+ await storage?.persistWorkflowSnapshot({
103
358
  workflowName: this.workflowId,
104
359
  runId: this.runId,
105
360
  resourceId: this.resourceId,
106
361
  snapshot: {
107
362
  ...snapshot,
108
- status: "canceled"
363
+ status: "canceled",
364
+ value: snapshot.value
109
365
  }
110
366
  });
111
367
  }
112
368
  }
113
- async start({
369
+ async start(params) {
370
+ return this._start(params);
371
+ }
372
+ async _start({
114
373
  inputData,
115
- initialState
374
+ initialState,
375
+ outputOptions,
376
+ tracingOptions,
377
+ format,
378
+ requestContext
116
379
  }) {
117
380
  await this.#mastra.getStorage()?.persistWorkflowSnapshot({
118
381
  workflowName: this.workflowId,
@@ -121,14 +384,15 @@ var InngestRun = class extends workflows.Run {
121
384
  snapshot: {
122
385
  runId: this.runId,
123
386
  serializedStepGraph: this.serializedStepGraph,
387
+ status: "running",
124
388
  value: {},
125
389
  context: {},
126
390
  activePaths: [],
127
391
  suspendedPaths: {},
392
+ activeStepsPath: {},
128
393
  resumeLabels: {},
129
394
  waitingPaths: {},
130
- timestamp: Date.now(),
131
- status: "running"
395
+ timestamp: Date.now()
132
396
  }
133
397
  });
134
398
  const inputDataToUse = await this._validateInput(inputData);
@@ -139,7 +403,11 @@ var InngestRun = class extends workflows.Run {
139
403
  inputData: inputDataToUse,
140
404
  initialState: initialStateToUse,
141
405
  runId: this.runId,
142
- resourceId: this.resourceId
406
+ resourceId: this.resourceId,
407
+ outputOptions,
408
+ tracingOptions,
409
+ format,
410
+ requestContext: requestContext ? Object.fromEntries(requestContext.entries()) : {}
143
411
  }
144
412
  });
145
413
  const eventId = eventOutput.ids[0];
@@ -168,15 +436,24 @@ var InngestRun = class extends workflows.Run {
168
436
  return p;
169
437
  }
170
438
  async _resume(params) {
171
- const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
172
- (step) => typeof step === "string" ? step : step?.id
173
- );
174
- const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
439
+ const storage = this.#mastra?.getStorage();
440
+ let steps = [];
441
+ if (typeof params.step === "string") {
442
+ steps = params.step.split(".");
443
+ } else {
444
+ steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
445
+ (step) => typeof step === "string" ? step : step?.id
446
+ );
447
+ }
448
+ const snapshot = await storage?.loadWorkflowSnapshot({
175
449
  workflowName: this.workflowId,
176
450
  runId: this.runId
177
451
  });
178
452
  const suspendedStep = this.workflowSteps[steps?.[0] ?? ""];
179
453
  const resumeDataToUse = await this._validateResumeData(params.resumeData, suspendedStep);
454
+ const persistedRequestContext = snapshot?.requestContext ?? {};
455
+ const newRequestContext = params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {};
456
+ const mergedRequestContext = { ...persistedRequestContext, ...newRequestContext };
180
457
  const eventOutput = await this.inngest.send({
181
458
  name: `workflow.${this.workflowId}`,
182
459
  data: {
@@ -189,9 +466,101 @@ var InngestRun = class extends workflows.Run {
189
466
  steps,
190
467
  stepResults: snapshot?.context,
191
468
  resumePayload: resumeDataToUse,
192
- // @ts-ignore
193
- resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
469
+ resumePath: steps?.[0] ? snapshot?.suspendedPaths?.[steps?.[0]] : void 0
470
+ },
471
+ requestContext: mergedRequestContext
472
+ }
473
+ });
474
+ const eventId = eventOutput.ids[0];
475
+ if (!eventId) {
476
+ throw new Error("Event ID is not set");
477
+ }
478
+ const runOutput = await this.getRunOutput(eventId);
479
+ const result = runOutput?.output?.result;
480
+ if (result.status === "failed") {
481
+ result.error = new Error(result.error);
482
+ }
483
+ return result;
484
+ }
485
+ async timeTravel(params) {
486
+ const p = this._timeTravel(params).then((result) => {
487
+ if (result.status !== "suspended") {
488
+ this.closeStreamAction?.().catch(() => {
489
+ });
490
+ }
491
+ return result;
492
+ });
493
+ this.executionResults = p;
494
+ return p;
495
+ }
496
+ async _timeTravel(params) {
497
+ if (!params.step || Array.isArray(params.step) && params.step?.length === 0) {
498
+ throw new Error("Step is required and must be a valid step or array of steps");
499
+ }
500
+ let steps = [];
501
+ if (typeof params.step === "string") {
502
+ steps = params.step.split(".");
503
+ } else {
504
+ steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
505
+ (step) => typeof step === "string" ? step : step?.id
506
+ );
507
+ }
508
+ if (steps.length === 0) {
509
+ throw new Error("No steps provided to timeTravel");
510
+ }
511
+ const storage = this.#mastra?.getStorage();
512
+ const snapshot = await storage?.loadWorkflowSnapshot({
513
+ workflowName: this.workflowId,
514
+ runId: this.runId
515
+ });
516
+ if (!snapshot) {
517
+ await storage?.persistWorkflowSnapshot({
518
+ workflowName: this.workflowId,
519
+ runId: this.runId,
520
+ resourceId: this.resourceId,
521
+ snapshot: {
522
+ runId: this.runId,
523
+ serializedStepGraph: this.serializedStepGraph,
524
+ status: "pending",
525
+ value: {},
526
+ context: {},
527
+ activePaths: [],
528
+ suspendedPaths: {},
529
+ activeStepsPath: {},
530
+ resumeLabels: {},
531
+ waitingPaths: {},
532
+ timestamp: Date.now()
194
533
  }
534
+ });
535
+ }
536
+ if (snapshot?.status === "running") {
537
+ throw new Error("This workflow run is still running, cannot time travel");
538
+ }
539
+ let inputDataToUse = params.inputData;
540
+ if (inputDataToUse && steps.length === 1) {
541
+ inputDataToUse = await this._validateTimetravelInputData(params.inputData, this.workflowSteps[steps[0]]);
542
+ }
543
+ const timeTravelData = workflows.createTimeTravelExecutionParams({
544
+ steps,
545
+ inputData: inputDataToUse,
546
+ resumeData: params.resumeData,
547
+ context: params.context,
548
+ nestedStepsContext: params.nestedStepsContext,
549
+ snapshot: snapshot ?? { context: {} },
550
+ graph: this.executionGraph,
551
+ initialState: params.initialState
552
+ });
553
+ const eventOutput = await this.inngest.send({
554
+ name: `workflow.${this.workflowId}`,
555
+ data: {
556
+ initialState: timeTravelData.state,
557
+ runId: this.runId,
558
+ workflowId: this.workflowId,
559
+ stepResults: timeTravelData.stepResults,
560
+ timeTravel: timeTravelData,
561
+ tracingOptions: params.tracingOptions,
562
+ outputOptions: params.outputOptions,
563
+ requestContext: params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {}
195
564
  }
196
565
  });
197
566
  const eventId = eventOutput.ids[0];
@@ -205,12 +574,12 @@ var InngestRun = class extends workflows.Run {
205
574
  }
206
575
  return result;
207
576
  }
208
- watch(cb, type = "watch") {
577
+ watch(cb) {
209
578
  let active = true;
210
579
  const streamPromise = realtime.subscribe(
211
580
  {
212
581
  channel: `workflow:${this.workflowId}:${this.runId}`,
213
- topics: [type],
582
+ topics: ["watch"],
214
583
  app: this.inngest
215
584
  },
216
585
  (message) => {
@@ -228,20 +597,35 @@ var InngestRun = class extends workflows.Run {
228
597
  });
229
598
  };
230
599
  }
231
- streamLegacy({ inputData, runtimeContext } = {}) {
600
+ streamLegacy({ inputData, requestContext } = {}) {
232
601
  const { readable, writable } = new TransformStream();
233
602
  const writer = writable.getWriter();
603
+ void writer.write({
604
+ // @ts-ignore
605
+ type: "start",
606
+ // @ts-ignore
607
+ payload: { runId: this.runId }
608
+ });
234
609
  const unwatch = this.watch(async (event) => {
235
610
  try {
236
611
  const e = {
237
612
  ...event,
238
613
  type: event.type.replace("workflow-", "")
239
614
  };
615
+ if (e.type === "step-output") {
616
+ e.type = e.payload.output.type;
617
+ e.payload = e.payload.output.payload;
618
+ }
240
619
  await writer.write(e);
241
620
  } catch {
242
621
  }
243
- }, "watch-v2");
622
+ });
244
623
  this.closeStreamAction = async () => {
624
+ await writer.write({
625
+ type: "finish",
626
+ // @ts-ignore
627
+ payload: { runId: this.runId }
628
+ });
245
629
  unwatch();
246
630
  try {
247
631
  await writer.close();
@@ -251,7 +635,7 @@ var InngestRun = class extends workflows.Run {
251
635
  writer.releaseLock();
252
636
  }
253
637
  };
254
- this.executionResults = this.start({ inputData, runtimeContext }).then((result) => {
638
+ this.executionResults = this._start({ inputData, requestContext, format: "legacy" }).then((result) => {
255
639
  if (result.status !== "suspended") {
256
640
  this.closeStreamAction?.().catch(() => {
257
641
  });
@@ -265,11 +649,18 @@ var InngestRun = class extends workflows.Run {
265
649
  }
266
650
  stream({
267
651
  inputData,
268
- runtimeContext,
269
- closeOnSuspend = true
652
+ requestContext,
653
+ tracingOptions,
654
+ closeOnSuspend = true,
655
+ initialState,
656
+ outputOptions
270
657
  } = {}) {
658
+ if (this.closeStreamAction && this.streamOutput) {
659
+ return this.streamOutput;
660
+ }
661
+ this.closeStreamAction = async () => {
662
+ };
271
663
  const self = this;
272
- let streamOutput;
273
664
  const stream$1 = new web.ReadableStream({
274
665
  async start(controller) {
275
666
  const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
@@ -278,11 +669,11 @@ var InngestRun = class extends workflows.Run {
278
669
  runId: self.runId,
279
670
  from,
280
671
  payload: {
281
- stepName: payload.id,
672
+ stepName: payload?.id,
282
673
  ...payload
283
674
  }
284
675
  });
285
- }, "watch-v2");
676
+ });
286
677
  self.closeStreamAction = async () => {
287
678
  unwatch();
288
679
  try {
@@ -291,53 +682,142 @@ var InngestRun = class extends workflows.Run {
291
682
  console.error("Error closing stream:", err);
292
683
  }
293
684
  };
294
- const executionResultsPromise = self.start({
685
+ const executionResultsPromise = self._start({
295
686
  inputData,
296
- runtimeContext
687
+ requestContext,
688
+ // tracingContext, // We are not able to pass a reference to a span here, what to do?
689
+ initialState,
690
+ tracingOptions,
691
+ outputOptions,
692
+ format: "vnext"
297
693
  });
298
- const executionResults = await executionResultsPromise;
299
- if (closeOnSuspend) {
300
- self.closeStreamAction?.().catch(() => {
301
- });
302
- } else if (executionResults.status !== "suspended") {
694
+ let executionResults;
695
+ try {
696
+ executionResults = await executionResultsPromise;
697
+ if (closeOnSuspend) {
698
+ self.closeStreamAction?.().catch(() => {
699
+ });
700
+ } else if (executionResults.status !== "suspended") {
701
+ self.closeStreamAction?.().catch(() => {
702
+ });
703
+ }
704
+ if (self.streamOutput) {
705
+ self.streamOutput.updateResults(
706
+ executionResults
707
+ );
708
+ }
709
+ } catch (err) {
710
+ self.streamOutput?.rejectResults(err);
303
711
  self.closeStreamAction?.().catch(() => {
304
712
  });
305
713
  }
306
- if (streamOutput) {
307
- streamOutput.updateResults(executionResults);
308
- }
309
714
  }
310
715
  });
311
- streamOutput = new stream.WorkflowRunOutput({
716
+ this.streamOutput = new stream.WorkflowRunOutput({
312
717
  runId: this.runId,
313
718
  workflowId: this.workflowId,
314
719
  stream: stream$1
315
720
  });
316
- return streamOutput;
317
- }
318
- };
319
- var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
320
- #mastra;
321
- inngest;
322
- function;
323
- flowControlConfig;
324
- constructor(params, inngest) {
325
- const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
326
- super(workflowParams);
327
- const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
328
- ([_, value]) => value !== void 0
329
- );
330
- this.flowControlConfig = flowControlEntries.length > 0 ? Object.fromEntries(flowControlEntries) : void 0;
331
- this.#mastra = params.mastra;
332
- this.inngest = inngest;
721
+ return this.streamOutput;
333
722
  }
334
- async getWorkflowRuns(args) {
335
- const storage = this.#mastra?.getStorage();
336
- if (!storage) {
337
- this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
338
- return { runs: [], total: 0 };
339
- }
340
- return storage.getWorkflowRuns({ workflowName: this.id, ...args ?? {} });
723
+ streamVNext(args = {}) {
724
+ return this.stream(args);
725
+ }
726
+ timeTravelStream({
727
+ inputData,
728
+ resumeData,
729
+ initialState,
730
+ step,
731
+ context,
732
+ nestedStepsContext,
733
+ requestContext,
734
+ tracingOptions,
735
+ outputOptions
736
+ }) {
737
+ this.closeStreamAction = async () => {
738
+ };
739
+ const self = this;
740
+ const stream$1 = new web.ReadableStream({
741
+ async start(controller) {
742
+ const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
743
+ controller.enqueue({
744
+ type,
745
+ runId: self.runId,
746
+ from,
747
+ payload: {
748
+ stepName: payload?.id,
749
+ ...payload
750
+ }
751
+ });
752
+ });
753
+ self.closeStreamAction = async () => {
754
+ unwatch();
755
+ try {
756
+ controller.close();
757
+ } catch (err) {
758
+ console.error("Error closing stream:", err);
759
+ }
760
+ };
761
+ const executionResultsPromise = self._timeTravel({
762
+ inputData,
763
+ step,
764
+ context,
765
+ nestedStepsContext,
766
+ resumeData,
767
+ initialState,
768
+ requestContext,
769
+ tracingOptions,
770
+ outputOptions
771
+ });
772
+ self.executionResults = executionResultsPromise;
773
+ let executionResults;
774
+ try {
775
+ executionResults = await executionResultsPromise;
776
+ self.closeStreamAction?.().catch(() => {
777
+ });
778
+ if (self.streamOutput) {
779
+ self.streamOutput.updateResults(executionResults);
780
+ }
781
+ } catch (err) {
782
+ self.streamOutput?.rejectResults(err);
783
+ self.closeStreamAction?.().catch(() => {
784
+ });
785
+ }
786
+ }
787
+ });
788
+ this.streamOutput = new stream.WorkflowRunOutput({
789
+ runId: this.runId,
790
+ workflowId: this.workflowId,
791
+ stream: stream$1
792
+ });
793
+ return this.streamOutput;
794
+ }
795
+ };
796
+
797
+ // src/workflow.ts
798
+ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
799
+ #mastra;
800
+ inngest;
801
+ function;
802
+ flowControlConfig;
803
+ constructor(params, inngest) {
804
+ const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
805
+ super(workflowParams);
806
+ this.engineType = "inngest";
807
+ const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
808
+ ([_, value]) => value !== void 0
809
+ );
810
+ this.flowControlConfig = flowControlEntries.length > 0 ? Object.fromEntries(flowControlEntries) : void 0;
811
+ this.#mastra = params.mastra;
812
+ this.inngest = inngest;
813
+ }
814
+ async listWorkflowRuns(args) {
815
+ const storage = this.#mastra?.getStorage();
816
+ if (!storage) {
817
+ this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
818
+ return { runs: [], total: 0 };
819
+ }
820
+ return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
341
821
  }
342
822
  async getWorkflowRunById(runId) {
343
823
  const storage = this.#mastra?.getStorage();
@@ -366,16 +846,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
366
846
  }
367
847
  }
368
848
  }
369
- /**
370
- * @deprecated Use createRunAsync() instead.
371
- * @throws {Error} Always throws an error directing users to use createRunAsync()
372
- */
373
- createRun(_options) {
374
- throw new Error(
375
- "createRun() has been deprecated. Please use createRunAsync() instead.\n\nMigration guide:\n Before: const run = workflow.createRun();\n After: const run = await workflow.createRunAsync();\n\nNote: createRunAsync() is an async method, so make sure your calling function is async."
376
- );
377
- }
378
- async createRunAsync(options) {
849
+ async createRun(options) {
379
850
  const runIdToUse = options?.runId || crypto.randomUUID();
380
851
  const run = this.runs.get(runIdToUse) ?? new InngestRun(
381
852
  {
@@ -388,7 +859,9 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
388
859
  mastra: this.#mastra,
389
860
  retryConfig: this.retryConfig,
390
861
  cleanup: () => this.runs.delete(runIdToUse),
391
- workflowSteps: this.steps
862
+ workflowSteps: this.steps,
863
+ workflowEngineType: this.engineType,
864
+ validateInputs: this.options.validateInputs
392
865
  },
393
866
  this.inngest
394
867
  );
@@ -409,13 +882,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
409
882
  value: {},
410
883
  context: {},
411
884
  activePaths: [],
885
+ activeStepsPath: {},
412
886
  waitingPaths: {},
413
887
  serializedStepGraph: this.serializedStepGraph,
414
888
  suspendedPaths: {},
415
889
  resumeLabels: {},
416
890
  result: void 0,
417
891
  error: void 0,
418
- // @ts-ignore
419
892
  timestamp: Date.now()
420
893
  }
421
894
  });
@@ -429,15 +902,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
429
902
  this.function = this.inngest.createFunction(
430
903
  {
431
904
  id: `workflow.${this.id}`,
432
- // @ts-ignore
433
- retries: this.retryConfig?.attempts ?? 0,
905
+ retries: Math.min(this.retryConfig?.attempts ?? 0, 20),
434
906
  cancelOn: [{ event: `cancel.workflow.${this.id}` }],
435
907
  // Spread flow control configuration
436
908
  ...this.flowControlConfig
437
909
  },
438
910
  { event: `workflow.${this.id}` },
439
911
  async ({ event, step, attempt, publish }) => {
440
- let { inputData, initialState, runId, resourceId, resume, outputOptions } = event.data;
912
+ let { inputData, initialState, runId, resourceId, resume, outputOptions, format, timeTravel } = event.data;
441
913
  if (!runId) {
442
914
  runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
443
915
  return crypto.randomUUID();
@@ -476,13 +948,19 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
476
948
  initialState,
477
949
  emitter,
478
950
  retryConfig: this.retryConfig,
479
- runtimeContext: new di.RuntimeContext(),
480
- // TODO
951
+ requestContext: new di.RequestContext(Object.entries(event.data.requestContext ?? {})),
481
952
  resume,
953
+ timeTravel,
954
+ format,
482
955
  abortController: new AbortController(),
483
- currentSpan: void 0,
484
- // TODO: Pass actual parent AI span from workflow execution context
485
- outputOptions
956
+ // currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
957
+ outputOptions,
958
+ writableStream: new web.WritableStream({
959
+ write(chunk) {
960
+ void emitter.emit("watch", chunk).catch(() => {
961
+ });
962
+ }
963
+ })
486
964
  });
487
965
  await step.run(`workflow.${this.id}.finalize`, async () => {
488
966
  if (result.status === "failed") {
@@ -514,26 +992,70 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
514
992
  return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
515
993
  }
516
994
  };
995
+ function serve({
996
+ mastra,
997
+ inngest,
998
+ functions: userFunctions = [],
999
+ registerOptions
1000
+ }) {
1001
+ const wfs = mastra.listWorkflows();
1002
+ const workflowFunctions = Array.from(
1003
+ new Set(
1004
+ Object.values(wfs).flatMap((wf) => {
1005
+ if (wf instanceof InngestWorkflow) {
1006
+ wf.__registerMastra(mastra);
1007
+ return wf.getFunctions();
1008
+ }
1009
+ return [];
1010
+ })
1011
+ )
1012
+ );
1013
+ return hono.serve({
1014
+ ...registerOptions,
1015
+ client: inngest,
1016
+ functions: [...workflowFunctions, ...userFunctions]
1017
+ });
1018
+ }
1019
+
1020
+ // src/types.ts
1021
+ var _compatibilityCheck = true;
1022
+
1023
+ // src/index.ts
517
1024
  function isAgent(params) {
518
1025
  return params?.component === "AGENT";
519
1026
  }
520
1027
  function isTool(params) {
521
1028
  return params instanceof tools.Tool;
522
1029
  }
523
- function createStep(params) {
1030
+ function isInngestWorkflow(params) {
1031
+ return params instanceof InngestWorkflow;
1032
+ }
1033
+ function createStep(params, agentOptions) {
1034
+ if (isInngestWorkflow(params)) {
1035
+ return params;
1036
+ }
524
1037
  if (isAgent(params)) {
525
1038
  return {
526
1039
  id: params.name,
527
1040
  description: params.getDescription(),
528
- // @ts-ignore
529
1041
  inputSchema: zod.z.object({
530
1042
  prompt: zod.z.string()
1043
+ // resourceId: z.string().optional(),
1044
+ // threadId: z.string().optional(),
531
1045
  }),
532
- // @ts-ignore
533
1046
  outputSchema: zod.z.object({
534
1047
  text: zod.z.string()
535
1048
  }),
536
- execute: async ({ inputData, [_constants.EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort, tracingContext }) => {
1049
+ execute: async ({
1050
+ inputData,
1051
+ [_constants.EMITTER_SYMBOL]: emitter,
1052
+ [_constants.STREAM_FORMAT_SYMBOL]: streamFormat,
1053
+ requestContext,
1054
+ tracingContext,
1055
+ abortSignal,
1056
+ abort,
1057
+ writer
1058
+ }) => {
537
1059
  let streamPromise = {};
538
1060
  streamPromise.promise = new Promise((resolve, reject) => {
539
1061
  streamPromise.resolve = resolve;
@@ -543,61 +1065,60 @@ function createStep(params) {
543
1065
  name: params.name,
544
1066
  args: inputData
545
1067
  };
546
- if ((await params.getLLM()).getModel().specificationVersion === `v2`) {
547
- const { fullStream } = await params.stream(inputData.prompt, {
548
- runtimeContext,
1068
+ let stream;
1069
+ if ((await params.getModel()).specificationVersion === "v1") {
1070
+ const { fullStream } = await params.streamLegacy(inputData.prompt, {
1071
+ ...agentOptions ?? {},
1072
+ // resourceId: inputData.resourceId,
1073
+ // threadId: inputData.threadId,
1074
+ requestContext,
549
1075
  tracingContext,
550
1076
  onFinish: (result) => {
551
1077
  streamPromise.resolve(result.text);
1078
+ void agentOptions?.onFinish?.(result);
552
1079
  },
553
1080
  abortSignal
554
1081
  });
555
- if (abortSignal.aborted) {
556
- return abort();
557
- }
558
- await emitter.emit("watch-v2", {
559
- type: "tool-call-streaming-start",
560
- ...toolData ?? {}
561
- });
562
- for await (const chunk of fullStream) {
563
- if (chunk.type === "text-delta") {
564
- await emitter.emit("watch-v2", {
565
- type: "tool-call-delta",
566
- ...toolData ?? {},
567
- argsTextDelta: chunk.payload.text
568
- });
569
- }
570
- }
1082
+ stream = fullStream;
571
1083
  } else {
572
- const { fullStream } = await params.streamLegacy(inputData.prompt, {
573
- runtimeContext,
1084
+ const modelOutput = await params.stream(inputData.prompt, {
1085
+ ...agentOptions ?? {},
1086
+ requestContext,
574
1087
  tracingContext,
575
1088
  onFinish: (result) => {
576
1089
  streamPromise.resolve(result.text);
1090
+ void agentOptions?.onFinish?.(result);
577
1091
  },
578
1092
  abortSignal
579
1093
  });
580
- if (abortSignal.aborted) {
581
- return abort();
582
- }
583
- await emitter.emit("watch-v2", {
1094
+ stream = modelOutput.fullStream;
1095
+ }
1096
+ if (streamFormat === "legacy") {
1097
+ await emitter.emit("watch", {
584
1098
  type: "tool-call-streaming-start",
585
1099
  ...toolData ?? {}
586
1100
  });
587
- for await (const chunk of fullStream) {
1101
+ for await (const chunk of stream) {
588
1102
  if (chunk.type === "text-delta") {
589
- await emitter.emit("watch-v2", {
1103
+ await emitter.emit("watch", {
590
1104
  type: "tool-call-delta",
591
1105
  ...toolData ?? {},
592
1106
  argsTextDelta: chunk.textDelta
593
1107
  });
594
1108
  }
595
1109
  }
1110
+ await emitter.emit("watch", {
1111
+ type: "tool-call-streaming-finish",
1112
+ ...toolData ?? {}
1113
+ });
1114
+ } else {
1115
+ for await (const chunk of stream) {
1116
+ await writer.write(chunk);
1117
+ }
1118
+ }
1119
+ if (abortSignal.aborted) {
1120
+ return abort();
596
1121
  }
597
- await emitter.emit("watch-v2", {
598
- type: "tool-call-streaming-finish",
599
- ...toolData ?? {}
600
- });
601
1122
  return {
602
1123
  text: await streamPromise.promise
603
1124
  };
@@ -611,20 +1132,38 @@ function createStep(params) {
611
1132
  }
612
1133
  return {
613
1134
  // TODO: tool probably should have strong id type
614
- // @ts-ignore
615
1135
  id: params.id,
616
1136
  description: params.description,
617
1137
  inputSchema: params.inputSchema,
618
1138
  outputSchema: params.outputSchema,
619
- execute: async ({ inputData, mastra, runtimeContext, tracingContext, suspend, resumeData }) => {
620
- return params.execute({
621
- context: inputData,
622
- mastra: aiTracing.wrapMastra(mastra, tracingContext),
623
- runtimeContext,
1139
+ suspendSchema: params.suspendSchema,
1140
+ resumeSchema: params.resumeSchema,
1141
+ execute: async ({
1142
+ inputData,
1143
+ mastra,
1144
+ requestContext,
1145
+ tracingContext,
1146
+ suspend,
1147
+ resumeData,
1148
+ runId,
1149
+ workflowId,
1150
+ state,
1151
+ setState
1152
+ }) => {
1153
+ const toolContext = {
1154
+ mastra,
1155
+ requestContext,
624
1156
  tracingContext,
625
- suspend,
626
- resumeData
627
- });
1157
+ workflow: {
1158
+ runId,
1159
+ resumeData,
1160
+ suspend,
1161
+ workflowId,
1162
+ state,
1163
+ setState
1164
+ }
1165
+ };
1166
+ return params.execute(inputData, toolContext);
628
1167
  },
629
1168
  component: "TOOL"
630
1169
  };
@@ -658,6 +1197,8 @@ function init(inngest) {
658
1197
  suspendSchema: step.suspendSchema,
659
1198
  stateSchema: step.stateSchema,
660
1199
  execute: step.execute,
1200
+ retries: step.retries,
1201
+ scorers: step.scorers,
661
1202
  component: step.component
662
1203
  };
663
1204
  },
@@ -667,7 +1208,8 @@ function init(inngest) {
667
1208
  inputSchema: workflow.inputSchema,
668
1209
  outputSchema: workflow.outputSchema,
669
1210
  steps: workflow.stepDefs,
670
- mastra: workflow.mastra
1211
+ mastra: workflow.mastra,
1212
+ options: workflow.options
671
1213
  });
672
1214
  wf.setStepFlow(workflow.stepGraph);
673
1215
  wf.commit();
@@ -675,946 +1217,11 @@ function init(inngest) {
675
1217
  }
676
1218
  };
677
1219
  }
678
- var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
679
- inngestStep;
680
- inngestAttempts;
681
- constructor(mastra, inngestStep, inngestAttempts = 0, options) {
682
- super({ mastra, options });
683
- this.inngestStep = inngestStep;
684
- this.inngestAttempts = inngestAttempts;
685
- }
686
- async execute(params) {
687
- await params.emitter.emit("watch-v2", {
688
- type: "workflow-start",
689
- payload: { runId: params.runId }
690
- });
691
- const result = await super.execute(params);
692
- await params.emitter.emit("watch-v2", {
693
- type: "workflow-finish",
694
- payload: { runId: params.runId }
695
- });
696
- return result;
697
- }
698
- async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
699
- const base = {
700
- status: lastOutput.status,
701
- steps: stepResults
702
- };
703
- if (lastOutput.status === "success") {
704
- await emitter.emit("watch", {
705
- type: "watch",
706
- payload: {
707
- workflowState: {
708
- status: lastOutput.status,
709
- steps: stepResults,
710
- result: lastOutput.output
711
- }
712
- },
713
- eventTimestamp: Date.now()
714
- });
715
- base.result = lastOutput.output;
716
- } else if (lastOutput.status === "failed") {
717
- base.error = error instanceof Error ? error?.stack ?? error.message : lastOutput?.error instanceof Error ? lastOutput.error.message : lastOutput.error ?? error ?? "Unknown error";
718
- await emitter.emit("watch", {
719
- type: "watch",
720
- payload: {
721
- workflowState: {
722
- status: lastOutput.status,
723
- steps: stepResults,
724
- result: null,
725
- error: base.error
726
- }
727
- },
728
- eventTimestamp: Date.now()
729
- });
730
- } else if (lastOutput.status === "suspended") {
731
- await emitter.emit("watch", {
732
- type: "watch",
733
- payload: {
734
- workflowState: {
735
- status: lastOutput.status,
736
- steps: stepResults,
737
- result: null,
738
- error: null
739
- }
740
- },
741
- eventTimestamp: Date.now()
742
- });
743
- const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
744
- if (stepResult?.status === "suspended") {
745
- const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
746
- return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
747
- }
748
- return [];
749
- });
750
- base.suspended = suspendedStepIds;
751
- }
752
- executionSpan?.end();
753
- return base;
754
- }
755
- // async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
756
- // await this.inngestStep.sleep(id, duration);
757
- // }
758
- async executeSleep({
759
- workflowId,
760
- runId,
761
- entry,
762
- prevOutput,
763
- stepResults,
764
- emitter,
765
- abortController,
766
- runtimeContext,
767
- executionContext,
768
- writableStream,
769
- tracingContext
770
- }) {
771
- let { duration, fn } = entry;
772
- const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
773
- type: aiTracing.AISpanType.WORKFLOW_SLEEP,
774
- name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
775
- attributes: {
776
- durationMs: duration,
777
- sleepType: fn ? "dynamic" : "fixed"
778
- },
779
- tracingPolicy: this.options?.tracingPolicy
780
- });
781
- if (fn) {
782
- const stepCallId = crypto.randomUUID();
783
- duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
784
- return await fn({
785
- runId,
786
- workflowId,
787
- mastra: this.mastra,
788
- runtimeContext,
789
- inputData: prevOutput,
790
- state: executionContext.state,
791
- setState: (state) => {
792
- executionContext.state = state;
793
- },
794
- runCount: -1,
795
- tracingContext: {
796
- currentSpan: sleepSpan
797
- },
798
- getInitData: () => stepResults?.input,
799
- getStepResult: workflows.getStepResult.bind(this, stepResults),
800
- // TODO: this function shouldn't have suspend probably?
801
- suspend: async (_suspendPayload) => {
802
- },
803
- bail: () => {
804
- },
805
- abort: () => {
806
- abortController?.abort();
807
- },
808
- [_constants.EMITTER_SYMBOL]: emitter,
809
- // TODO: add streamVNext support
810
- [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
811
- engine: { step: this.inngestStep },
812
- abortSignal: abortController?.signal,
813
- writer: new tools.ToolStream(
814
- {
815
- prefix: "workflow-step",
816
- callId: stepCallId,
817
- name: "sleep",
818
- runId
819
- },
820
- writableStream
821
- )
822
- });
823
- });
824
- sleepSpan?.update({
825
- attributes: {
826
- durationMs: duration
827
- }
828
- });
829
- }
830
- try {
831
- await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
832
- sleepSpan?.end();
833
- } catch (e) {
834
- sleepSpan?.error({ error: e });
835
- throw e;
836
- }
837
- }
838
- async executeSleepUntil({
839
- workflowId,
840
- runId,
841
- entry,
842
- prevOutput,
843
- stepResults,
844
- emitter,
845
- abortController,
846
- runtimeContext,
847
- executionContext,
848
- writableStream,
849
- tracingContext
850
- }) {
851
- let { date, fn } = entry;
852
- const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
853
- type: aiTracing.AISpanType.WORKFLOW_SLEEP,
854
- name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
855
- attributes: {
856
- untilDate: date,
857
- durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
858
- sleepType: fn ? "dynamic" : "fixed"
859
- },
860
- tracingPolicy: this.options?.tracingPolicy
861
- });
862
- if (fn) {
863
- date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
864
- const stepCallId = crypto.randomUUID();
865
- return await fn({
866
- runId,
867
- workflowId,
868
- mastra: this.mastra,
869
- runtimeContext,
870
- inputData: prevOutput,
871
- state: executionContext.state,
872
- setState: (state) => {
873
- executionContext.state = state;
874
- },
875
- runCount: -1,
876
- tracingContext: {
877
- currentSpan: sleepUntilSpan
878
- },
879
- getInitData: () => stepResults?.input,
880
- getStepResult: workflows.getStepResult.bind(this, stepResults),
881
- // TODO: this function shouldn't have suspend probably?
882
- suspend: async (_suspendPayload) => {
883
- },
884
- bail: () => {
885
- },
886
- abort: () => {
887
- abortController?.abort();
888
- },
889
- [_constants.EMITTER_SYMBOL]: emitter,
890
- [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
891
- // TODO: add streamVNext support
892
- engine: { step: this.inngestStep },
893
- abortSignal: abortController?.signal,
894
- writer: new tools.ToolStream(
895
- {
896
- prefix: "workflow-step",
897
- callId: stepCallId,
898
- name: "sleep",
899
- runId
900
- },
901
- writableStream
902
- )
903
- });
904
- });
905
- if (date && !(date instanceof Date)) {
906
- date = new Date(date);
907
- }
908
- const time = !date ? 0 : date.getTime() - Date.now();
909
- sleepUntilSpan?.update({
910
- attributes: {
911
- durationMs: Math.max(0, time)
912
- }
913
- });
914
- }
915
- if (!(date instanceof Date)) {
916
- sleepUntilSpan?.end();
917
- return;
918
- }
919
- try {
920
- await this.inngestStep.sleepUntil(entry.id, date);
921
- sleepUntilSpan?.end();
922
- } catch (e) {
923
- sleepUntilSpan?.error({ error: e });
924
- throw e;
925
- }
926
- }
927
- async executeWaitForEvent({ event, timeout }) {
928
- const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
929
- event: `user-event-${event}`,
930
- timeout: timeout ?? 5e3
931
- });
932
- if (eventData === null) {
933
- throw "Timeout waiting for event";
934
- }
935
- return eventData?.data;
936
- }
937
- async executeStep({
938
- step,
939
- stepResults,
940
- executionContext,
941
- resume,
942
- prevOutput,
943
- emitter,
944
- abortController,
945
- runtimeContext,
946
- tracingContext,
947
- writableStream,
948
- disableScorers
949
- }) {
950
- const stepAISpan = tracingContext?.currentSpan?.createChildSpan({
951
- name: `workflow step: '${step.id}'`,
952
- type: aiTracing.AISpanType.WORKFLOW_STEP,
953
- input: prevOutput,
954
- attributes: {
955
- stepId: step.id
956
- },
957
- tracingPolicy: this.options?.tracingPolicy
958
- });
959
- const { inputData, validationError } = await workflows.validateStepInput({
960
- prevOutput,
961
- step,
962
- validateInputs: this.options?.validateInputs ?? false
963
- });
964
- const startedAt = await this.inngestStep.run(
965
- `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
966
- async () => {
967
- const startedAt2 = Date.now();
968
- await emitter.emit("watch", {
969
- type: "watch",
970
- payload: {
971
- currentStep: {
972
- id: step.id,
973
- status: "running"
974
- },
975
- workflowState: {
976
- status: "running",
977
- steps: {
978
- ...stepResults,
979
- [step.id]: {
980
- status: "running"
981
- }
982
- },
983
- result: null,
984
- error: null
985
- }
986
- },
987
- eventTimestamp: Date.now()
988
- });
989
- await emitter.emit("watch-v2", {
990
- type: "workflow-step-start",
991
- payload: {
992
- id: step.id,
993
- status: "running",
994
- payload: inputData,
995
- startedAt: startedAt2
996
- }
997
- });
998
- return startedAt2;
999
- }
1000
- );
1001
- if (step instanceof InngestWorkflow) {
1002
- const isResume = !!resume?.steps?.length;
1003
- let result;
1004
- let runId;
1005
- try {
1006
- if (isResume) {
1007
- runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
1008
- const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
1009
- workflowName: step.id,
1010
- runId
1011
- });
1012
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1013
- function: step.getFunction(),
1014
- data: {
1015
- inputData,
1016
- initialState: executionContext.state ?? snapshot?.value ?? {},
1017
- runId,
1018
- resume: {
1019
- runId,
1020
- steps: resume.steps.slice(1),
1021
- stepResults: snapshot?.context,
1022
- resumePayload: resume.resumePayload,
1023
- // @ts-ignore
1024
- resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
1025
- },
1026
- outputOptions: { includeState: true }
1027
- }
1028
- });
1029
- result = invokeResp.result;
1030
- runId = invokeResp.runId;
1031
- executionContext.state = invokeResp.result.state;
1032
- } else {
1033
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1034
- function: step.getFunction(),
1035
- data: {
1036
- inputData,
1037
- initialState: executionContext.state ?? {},
1038
- outputOptions: { includeState: true }
1039
- }
1040
- });
1041
- result = invokeResp.result;
1042
- runId = invokeResp.runId;
1043
- executionContext.state = invokeResp.result.state;
1044
- }
1045
- } catch (e) {
1046
- const errorCause = e?.cause;
1047
- if (errorCause && typeof errorCause === "object") {
1048
- result = errorCause;
1049
- runId = errorCause.runId || crypto.randomUUID();
1050
- } else {
1051
- runId = crypto.randomUUID();
1052
- result = {
1053
- status: "failed",
1054
- error: e instanceof Error ? e : new Error(String(e)),
1055
- steps: {},
1056
- input: inputData
1057
- };
1058
- }
1059
- }
1060
- const res = await this.inngestStep.run(
1061
- `workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
1062
- async () => {
1063
- if (result.status === "failed") {
1064
- await emitter.emit("watch", {
1065
- type: "watch",
1066
- payload: {
1067
- currentStep: {
1068
- id: step.id,
1069
- status: "failed",
1070
- error: result?.error
1071
- },
1072
- workflowState: {
1073
- status: "running",
1074
- steps: stepResults,
1075
- result: null,
1076
- error: null
1077
- }
1078
- },
1079
- eventTimestamp: Date.now()
1080
- });
1081
- await emitter.emit("watch-v2", {
1082
- type: "workflow-step-result",
1083
- payload: {
1084
- id: step.id,
1085
- status: "failed",
1086
- error: result?.error,
1087
- payload: prevOutput
1088
- }
1089
- });
1090
- return { executionContext, result: { status: "failed", error: result?.error } };
1091
- } else if (result.status === "suspended") {
1092
- const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
1093
- const stepRes2 = stepResult;
1094
- return stepRes2?.status === "suspended";
1095
- });
1096
- for (const [stepName, stepResult] of suspendedSteps) {
1097
- const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
1098
- executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1099
- await emitter.emit("watch", {
1100
- type: "watch",
1101
- payload: {
1102
- currentStep: {
1103
- id: step.id,
1104
- status: "suspended",
1105
- payload: stepResult.payload,
1106
- suspendPayload: {
1107
- ...stepResult?.suspendPayload,
1108
- __workflow_meta: { runId, path: suspendPath }
1109
- }
1110
- },
1111
- workflowState: {
1112
- status: "running",
1113
- steps: stepResults,
1114
- result: null,
1115
- error: null
1116
- }
1117
- },
1118
- eventTimestamp: Date.now()
1119
- });
1120
- await emitter.emit("watch-v2", {
1121
- type: "workflow-step-suspended",
1122
- payload: {
1123
- id: step.id,
1124
- status: "suspended"
1125
- }
1126
- });
1127
- return {
1128
- executionContext,
1129
- result: {
1130
- status: "suspended",
1131
- payload: stepResult.payload,
1132
- suspendPayload: {
1133
- ...stepResult?.suspendPayload,
1134
- __workflow_meta: { runId, path: suspendPath }
1135
- }
1136
- }
1137
- };
1138
- }
1139
- await emitter.emit("watch", {
1140
- type: "watch",
1141
- payload: {
1142
- currentStep: {
1143
- id: step.id,
1144
- status: "suspended",
1145
- payload: {}
1146
- },
1147
- workflowState: {
1148
- status: "running",
1149
- steps: stepResults,
1150
- result: null,
1151
- error: null
1152
- }
1153
- },
1154
- eventTimestamp: Date.now()
1155
- });
1156
- return {
1157
- executionContext,
1158
- result: {
1159
- status: "suspended",
1160
- payload: {}
1161
- }
1162
- };
1163
- }
1164
- await emitter.emit("watch", {
1165
- type: "watch",
1166
- payload: {
1167
- currentStep: {
1168
- id: step.id,
1169
- status: "success",
1170
- output: result?.result
1171
- },
1172
- workflowState: {
1173
- status: "running",
1174
- steps: stepResults,
1175
- result: null,
1176
- error: null
1177
- }
1178
- },
1179
- eventTimestamp: Date.now()
1180
- });
1181
- await emitter.emit("watch-v2", {
1182
- type: "workflow-step-result",
1183
- payload: {
1184
- id: step.id,
1185
- status: "success",
1186
- output: result?.result
1187
- }
1188
- });
1189
- await emitter.emit("watch-v2", {
1190
- type: "workflow-step-finish",
1191
- payload: {
1192
- id: step.id,
1193
- metadata: {}
1194
- }
1195
- });
1196
- return { executionContext, result: { status: "success", output: result?.result } };
1197
- }
1198
- );
1199
- Object.assign(executionContext, res.executionContext);
1200
- return {
1201
- ...res.result,
1202
- startedAt,
1203
- endedAt: Date.now(),
1204
- payload: inputData,
1205
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1206
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1207
- };
1208
- }
1209
- let stepRes;
1210
- try {
1211
- stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1212
- let execResults;
1213
- let suspended;
1214
- let bailed;
1215
- try {
1216
- if (validationError) {
1217
- throw validationError;
1218
- }
1219
- const result = await step.execute({
1220
- runId: executionContext.runId,
1221
- mastra: this.mastra,
1222
- runtimeContext,
1223
- writableStream,
1224
- state: executionContext?.state ?? {},
1225
- setState: (state) => {
1226
- executionContext.state = state;
1227
- },
1228
- inputData,
1229
- resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1230
- tracingContext: {
1231
- currentSpan: stepAISpan
1232
- },
1233
- getInitData: () => stepResults?.input,
1234
- getStepResult: workflows.getStepResult.bind(this, stepResults),
1235
- suspend: async (suspendPayload, suspendOptions) => {
1236
- executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1237
- if (suspendOptions?.resumeLabel) {
1238
- const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
1239
- for (const label of resumeLabel) {
1240
- executionContext.resumeLabels[label] = {
1241
- stepId: step.id,
1242
- foreachIndex: executionContext.foreachIndex
1243
- };
1244
- }
1245
- }
1246
- suspended = { payload: suspendPayload };
1247
- },
1248
- bail: (result2) => {
1249
- bailed = { payload: result2 };
1250
- },
1251
- resume: {
1252
- steps: resume?.steps?.slice(1) || [],
1253
- resumePayload: resume?.resumePayload,
1254
- // @ts-ignore
1255
- runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
1256
- },
1257
- [_constants.EMITTER_SYMBOL]: emitter,
1258
- engine: {
1259
- step: this.inngestStep
1260
- },
1261
- abortSignal: abortController.signal
1262
- });
1263
- const endedAt = Date.now();
1264
- execResults = {
1265
- status: "success",
1266
- output: result,
1267
- startedAt,
1268
- endedAt,
1269
- payload: inputData,
1270
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1271
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1272
- };
1273
- } catch (e) {
1274
- const stepFailure = {
1275
- status: "failed",
1276
- payload: inputData,
1277
- error: e instanceof Error ? e.stack ?? e.message : String(e),
1278
- endedAt: Date.now(),
1279
- startedAt,
1280
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1281
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1282
- };
1283
- execResults = stepFailure;
1284
- const fallbackErrorMessage = `Step ${step.id} failed`;
1285
- stepAISpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1286
- throw new inngest.RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
1287
- cause: execResults
1288
- });
1289
- }
1290
- if (suspended) {
1291
- execResults = {
1292
- status: "suspended",
1293
- suspendPayload: suspended.payload,
1294
- payload: inputData,
1295
- suspendedAt: Date.now(),
1296
- startedAt,
1297
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1298
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1299
- };
1300
- } else if (bailed) {
1301
- execResults = {
1302
- status: "bailed",
1303
- output: bailed.payload,
1304
- payload: inputData,
1305
- endedAt: Date.now(),
1306
- startedAt
1307
- };
1308
- }
1309
- await emitter.emit("watch", {
1310
- type: "watch",
1311
- payload: {
1312
- currentStep: {
1313
- id: step.id,
1314
- ...execResults
1315
- },
1316
- workflowState: {
1317
- status: "running",
1318
- steps: { ...stepResults, [step.id]: execResults },
1319
- result: null,
1320
- error: null
1321
- }
1322
- },
1323
- eventTimestamp: Date.now()
1324
- });
1325
- if (execResults.status === "suspended") {
1326
- await emitter.emit("watch-v2", {
1327
- type: "workflow-step-suspended",
1328
- payload: {
1329
- id: step.id,
1330
- ...execResults
1331
- }
1332
- });
1333
- } else {
1334
- await emitter.emit("watch-v2", {
1335
- type: "workflow-step-result",
1336
- payload: {
1337
- id: step.id,
1338
- ...execResults
1339
- }
1340
- });
1341
- await emitter.emit("watch-v2", {
1342
- type: "workflow-step-finish",
1343
- payload: {
1344
- id: step.id,
1345
- metadata: {}
1346
- }
1347
- });
1348
- }
1349
- stepAISpan?.end({ output: execResults });
1350
- return { result: execResults, executionContext, stepResults };
1351
- });
1352
- } catch (e) {
1353
- const stepFailure = e instanceof Error ? e?.cause : {
1354
- status: "failed",
1355
- error: e instanceof Error ? e.stack ?? e.message : String(e),
1356
- payload: inputData,
1357
- startedAt,
1358
- endedAt: Date.now()
1359
- };
1360
- await emitter.emit("watch-v2", {
1361
- type: "workflow-step-result",
1362
- payload: {
1363
- id: step.id,
1364
- ...stepFailure
1365
- }
1366
- });
1367
- await emitter.emit("watch-v2", {
1368
- type: "workflow-step-finish",
1369
- payload: {
1370
- id: step.id,
1371
- metadata: {}
1372
- }
1373
- });
1374
- stepRes = {
1375
- result: stepFailure,
1376
- executionContext,
1377
- stepResults: {
1378
- ...stepResults,
1379
- [step.id]: stepFailure
1380
- }
1381
- };
1382
- }
1383
- if (disableScorers !== false && stepRes.result.status === "success") {
1384
- await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
1385
- if (step.scorers) {
1386
- await this.runScorers({
1387
- scorers: step.scorers,
1388
- runId: executionContext.runId,
1389
- input: inputData,
1390
- output: stepRes.result,
1391
- workflowId: executionContext.workflowId,
1392
- stepId: step.id,
1393
- runtimeContext,
1394
- disableScorers,
1395
- tracingContext: { currentSpan: stepAISpan }
1396
- });
1397
- }
1398
- });
1399
- }
1400
- Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
1401
- Object.assign(stepResults, stepRes.stepResults);
1402
- executionContext.state = stepRes.executionContext.state;
1403
- return stepRes.result;
1404
- }
1405
- async persistStepUpdate({
1406
- workflowId,
1407
- runId,
1408
- stepResults,
1409
- resourceId,
1410
- executionContext,
1411
- serializedStepGraph,
1412
- workflowStatus,
1413
- result,
1414
- error
1415
- }) {
1416
- await this.inngestStep.run(
1417
- `workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
1418
- async () => {
1419
- const shouldPersistSnapshot = this.options.shouldPersistSnapshot({ stepResults, workflowStatus });
1420
- if (!shouldPersistSnapshot) {
1421
- return;
1422
- }
1423
- await this.mastra?.getStorage()?.persistWorkflowSnapshot({
1424
- workflowName: workflowId,
1425
- runId,
1426
- resourceId,
1427
- snapshot: {
1428
- runId,
1429
- value: executionContext.state,
1430
- context: stepResults,
1431
- activePaths: [],
1432
- suspendedPaths: executionContext.suspendedPaths,
1433
- resumeLabels: executionContext.resumeLabels,
1434
- waitingPaths: {},
1435
- serializedStepGraph,
1436
- status: workflowStatus,
1437
- result,
1438
- error,
1439
- // @ts-ignore
1440
- timestamp: Date.now()
1441
- }
1442
- });
1443
- }
1444
- );
1445
- }
1446
- async executeConditional({
1447
- workflowId,
1448
- runId,
1449
- entry,
1450
- prevOutput,
1451
- stepResults,
1452
- resume,
1453
- executionContext,
1454
- emitter,
1455
- abortController,
1456
- runtimeContext,
1457
- writableStream,
1458
- disableScorers,
1459
- tracingContext
1460
- }) {
1461
- const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
1462
- type: aiTracing.AISpanType.WORKFLOW_CONDITIONAL,
1463
- name: `conditional: '${entry.conditions.length} conditions'`,
1464
- input: prevOutput,
1465
- attributes: {
1466
- conditionCount: entry.conditions.length
1467
- },
1468
- tracingPolicy: this.options?.tracingPolicy
1469
- });
1470
- let execResults;
1471
- const truthyIndexes = (await Promise.all(
1472
- entry.conditions.map(
1473
- (cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
1474
- const evalSpan = conditionalSpan?.createChildSpan({
1475
- type: aiTracing.AISpanType.WORKFLOW_CONDITIONAL_EVAL,
1476
- name: `condition: '${index}'`,
1477
- input: prevOutput,
1478
- attributes: {
1479
- conditionIndex: index
1480
- },
1481
- tracingPolicy: this.options?.tracingPolicy
1482
- });
1483
- try {
1484
- const result = await cond({
1485
- runId,
1486
- workflowId,
1487
- mastra: this.mastra,
1488
- runtimeContext,
1489
- runCount: -1,
1490
- inputData: prevOutput,
1491
- state: executionContext.state,
1492
- setState: (state) => {
1493
- executionContext.state = state;
1494
- },
1495
- tracingContext: {
1496
- currentSpan: evalSpan
1497
- },
1498
- getInitData: () => stepResults?.input,
1499
- getStepResult: workflows.getStepResult.bind(this, stepResults),
1500
- // TODO: this function shouldn't have suspend probably?
1501
- suspend: async (_suspendPayload) => {
1502
- },
1503
- bail: () => {
1504
- },
1505
- abort: () => {
1506
- abortController.abort();
1507
- },
1508
- [_constants.EMITTER_SYMBOL]: emitter,
1509
- [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1510
- // TODO: add streamVNext support
1511
- engine: {
1512
- step: this.inngestStep
1513
- },
1514
- abortSignal: abortController.signal,
1515
- writer: new tools.ToolStream(
1516
- {
1517
- prefix: "workflow-step",
1518
- callId: crypto.randomUUID(),
1519
- name: "conditional",
1520
- runId
1521
- },
1522
- writableStream
1523
- )
1524
- });
1525
- evalSpan?.end({
1526
- output: result,
1527
- attributes: {
1528
- result: !!result
1529
- }
1530
- });
1531
- return result ? index : null;
1532
- } catch (e) {
1533
- evalSpan?.error({
1534
- error: e instanceof Error ? e : new Error(String(e)),
1535
- attributes: {
1536
- result: false
1537
- }
1538
- });
1539
- return null;
1540
- }
1541
- })
1542
- )
1543
- )).filter((index) => index !== null);
1544
- const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
1545
- conditionalSpan?.update({
1546
- attributes: {
1547
- truthyIndexes,
1548
- selectedSteps: stepsToRun.map((s) => s.type === "step" ? s.step.id : `control-${s.type}`)
1549
- }
1550
- });
1551
- const results = await Promise.all(
1552
- stepsToRun.map(async (step, index) => {
1553
- const currStepResult = stepResults[step.step.id];
1554
- if (currStepResult && currStepResult.status === "success") {
1555
- return currStepResult;
1556
- }
1557
- const result = await this.executeStep({
1558
- step: step.step,
1559
- prevOutput,
1560
- stepResults,
1561
- resume,
1562
- executionContext: {
1563
- workflowId,
1564
- runId,
1565
- executionPath: [...executionContext.executionPath, index],
1566
- suspendedPaths: executionContext.suspendedPaths,
1567
- resumeLabels: executionContext.resumeLabels,
1568
- retryConfig: executionContext.retryConfig,
1569
- executionSpan: executionContext.executionSpan,
1570
- state: executionContext.state
1571
- },
1572
- emitter,
1573
- abortController,
1574
- runtimeContext,
1575
- writableStream,
1576
- disableScorers,
1577
- tracingContext: {
1578
- currentSpan: conditionalSpan
1579
- }
1580
- });
1581
- stepResults[step.step.id] = result;
1582
- return result;
1583
- })
1584
- );
1585
- const hasFailed = results.find((result) => result.status === "failed");
1586
- const hasSuspended = results.find((result) => result.status === "suspended");
1587
- if (hasFailed) {
1588
- execResults = { status: "failed", error: hasFailed.error };
1589
- } else if (hasSuspended) {
1590
- execResults = { status: "suspended", suspendPayload: hasSuspended.suspendPayload };
1591
- } else {
1592
- execResults = {
1593
- status: "success",
1594
- output: results.reduce((acc, result, index) => {
1595
- if (result.status === "success") {
1596
- acc[stepsToRun[index].step.id] = result.output;
1597
- }
1598
- return acc;
1599
- }, {})
1600
- };
1601
- }
1602
- if (execResults.status === "failed") {
1603
- conditionalSpan?.error({
1604
- error: new Error(execResults.error)
1605
- });
1606
- } else {
1607
- conditionalSpan?.end({
1608
- output: execResults.output || execResults
1609
- });
1610
- }
1611
- return execResults;
1612
- }
1613
- };
1614
1220
 
1615
1221
  exports.InngestExecutionEngine = InngestExecutionEngine;
1616
1222
  exports.InngestRun = InngestRun;
1617
1223
  exports.InngestWorkflow = InngestWorkflow;
1224
+ exports._compatibilityCheck = _compatibilityCheck;
1618
1225
  exports.createStep = createStep;
1619
1226
  exports.init = init;
1620
1227
  exports.serve = serve;