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