@mastra/inngest 0.0.0-cloud-604-map-nested-flow-details-to-side-panel-20251212192149 → 0.0.0-cloudflare-file-url-lazy-20260130204903

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,11 +1,14 @@
1
+ import { MessageList, Agent, TripWire } from '@mastra/core/agent';
2
+ import { getErrorFromUnknown, MastraError, ErrorDomain, ErrorCategory } from '@mastra/core/error';
3
+ import { EntityType, SpanType } from '@mastra/core/observability';
4
+ import { ProcessorStepOutputSchema, ProcessorStepSchema, ProcessorRunner } from '@mastra/core/processors';
1
5
  import { Tool } from '@mastra/core/tools';
2
6
  import { DefaultExecutionEngine, createTimeTravelExecutionParams, Run, hydrateSerializedStepErrors, Workflow } from '@mastra/core/workflows';
3
7
  import { PUBSUB_SYMBOL, STREAM_FORMAT_SYMBOL } from '@mastra/core/workflows/_constants';
4
8
  import { z } from 'zod';
5
9
  import { randomUUID } from 'crypto';
6
10
  import { RequestContext } from '@mastra/core/di';
7
- import { RetryAfterError, NonRetriableError } from 'inngest';
8
- import { getErrorFromUnknown } from '@mastra/core/error';
11
+ import { NonRetriableError } from 'inngest';
9
12
  import { subscribe } from '@inngest/realtime';
10
13
  import { PubSub } from '@mastra/core/events';
11
14
  import { ReadableStream } from 'stream/web';
@@ -58,38 +61,46 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
58
61
  * After retries exhausted, error propagates here and we return a failed result.
59
62
  */
60
63
  async executeStepWithRetry(stepId, runStep, params) {
61
- try {
62
- const result = await this.wrapDurableOperation(stepId, runStep, { delay: params.delay });
63
- return { ok: true, result };
64
- } catch (e) {
65
- const cause = e?.cause;
66
- if (cause?.status === "failed") {
67
- params.stepSpan?.error({
68
- error: e,
69
- attributes: { status: "failed" }
70
- });
71
- if (cause.error && !(cause.error instanceof Error)) {
72
- cause.error = getErrorFromUnknown(cause.error, { serializeStack: false });
73
- }
74
- return { ok: false, error: cause };
64
+ for (let i = 0; i < params.retries + 1; i++) {
65
+ if (i > 0 && params.delay) {
66
+ await new Promise((resolve) => setTimeout(resolve, params.delay));
75
67
  }
76
- const errorInstance = getErrorFromUnknown(e, {
77
- serializeStack: false,
78
- fallbackMessage: "Unknown step execution error"
79
- });
80
- params.stepSpan?.error({
81
- error: errorInstance,
82
- attributes: { status: "failed" }
83
- });
84
- return {
85
- ok: false,
86
- error: {
87
- status: "failed",
88
- error: errorInstance,
89
- endedAt: Date.now()
68
+ try {
69
+ const result = await this.wrapDurableOperation(stepId, runStep);
70
+ return { ok: true, result };
71
+ } catch (e) {
72
+ if (i === params.retries) {
73
+ const cause = e?.cause;
74
+ if (cause?.status === "failed") {
75
+ params.stepSpan?.error({
76
+ error: e,
77
+ attributes: { status: "failed" }
78
+ });
79
+ if (cause.error && !(cause.error instanceof Error)) {
80
+ cause.error = getErrorFromUnknown(cause.error, { serializeStack: false });
81
+ }
82
+ return { ok: false, error: cause };
83
+ }
84
+ const errorInstance = getErrorFromUnknown(e, {
85
+ serializeStack: false,
86
+ fallbackMessage: "Unknown step execution error"
87
+ });
88
+ params.stepSpan?.error({
89
+ error: errorInstance,
90
+ attributes: { status: "failed" }
91
+ });
92
+ return {
93
+ ok: false,
94
+ error: {
95
+ status: "failed",
96
+ error: errorInstance,
97
+ endedAt: Date.now()
98
+ }
99
+ };
90
100
  }
91
- };
101
+ }
92
102
  }
103
+ return { ok: false, error: { status: "failed", error: new Error("Unknown error"), endedAt: Date.now() } };
93
104
  }
94
105
  /**
95
106
  * Use Inngest's sleep primitive for durability
@@ -105,28 +116,32 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
105
116
  }
106
117
  /**
107
118
  * Wrap durable operations in Inngest step.run() for durability.
108
- * If retryConfig is provided, throws RetryAfterError INSIDE step.run() to trigger
109
- * Inngest's step-level retry mechanism (not function-level retry).
119
+ *
120
+ * IMPORTANT: Errors are wrapped with a cause structure before throwing.
121
+ * This is necessary because Inngest's error serialization (serialize-error-cjs)
122
+ * only captures standard Error properties (message, name, stack, code, cause).
123
+ * Custom properties like statusCode, responseHeaders from AI SDK errors would
124
+ * be lost. By putting our serialized error (via getErrorFromUnknown with toJSON())
125
+ * in the cause property, we ensure custom properties survive serialization.
126
+ * The cause property is in serialize-error-cjs's allowlist, and when the cause
127
+ * object is finally JSON.stringify'd, our error's toJSON() is called.
110
128
  */
111
- async wrapDurableOperation(operationId, operationFn, retryConfig) {
129
+ async wrapDurableOperation(operationId, operationFn) {
112
130
  return this.inngestStep.run(operationId, async () => {
113
131
  try {
114
132
  return await operationFn();
115
133
  } catch (e) {
116
- if (retryConfig) {
117
- const errorInstance = getErrorFromUnknown(e, {
118
- serializeStack: false,
119
- fallbackMessage: "Unknown step execution error"
120
- });
121
- throw new RetryAfterError(errorInstance.message, retryConfig.delay, {
122
- cause: {
123
- status: "failed",
124
- error: errorInstance,
125
- endedAt: Date.now()
126
- }
127
- });
128
- }
129
- throw e;
134
+ const errorInstance = getErrorFromUnknown(e, {
135
+ serializeStack: false,
136
+ fallbackMessage: "Unknown step execution error"
137
+ });
138
+ throw new Error(errorInstance.message, {
139
+ cause: {
140
+ status: "failed",
141
+ error: errorInstance,
142
+ endedAt: Date.now()
143
+ }
144
+ });
130
145
  }
131
146
  });
132
147
  }
@@ -136,6 +151,108 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
136
151
  getEngineContext() {
137
152
  return { step: this.inngestStep };
138
153
  }
154
+ /**
155
+ * For Inngest, lifecycle callbacks are invoked in the workflow's finalize step
156
+ * (wrapped in step.run for durability), not in execute(). Override to skip.
157
+ */
158
+ async invokeLifecycleCallbacks(_result) {
159
+ }
160
+ /**
161
+ * Actually invoke the lifecycle callbacks. Called from workflow.ts finalize step.
162
+ */
163
+ async invokeLifecycleCallbacksInternal(result) {
164
+ return super.invokeLifecycleCallbacks(result);
165
+ }
166
+ // =============================================================================
167
+ // Durable Span Lifecycle Hooks
168
+ // =============================================================================
169
+ /**
170
+ * Create a step span durably - on first execution, creates and exports span.
171
+ * On replay, returns cached span data without re-creating.
172
+ */
173
+ async createStepSpan(params) {
174
+ const { executionContext, operationId, options, parentSpan } = params;
175
+ const parentSpanId = parentSpan?.id ?? executionContext.tracingIds?.workflowSpanId;
176
+ const exportedSpan = await this.wrapDurableOperation(operationId, async () => {
177
+ const observability = this.mastra?.observability?.getSelectedInstance({});
178
+ if (!observability) return void 0;
179
+ const span = observability.startSpan({
180
+ ...options,
181
+ entityType: options.entityType,
182
+ traceId: executionContext.tracingIds?.traceId,
183
+ parentSpanId
184
+ });
185
+ return span?.exportSpan();
186
+ });
187
+ if (exportedSpan) {
188
+ const observability = this.mastra?.observability?.getSelectedInstance({});
189
+ return observability?.rebuildSpan(exportedSpan);
190
+ }
191
+ return void 0;
192
+ }
193
+ /**
194
+ * End a step span durably.
195
+ */
196
+ async endStepSpan(params) {
197
+ const { span, operationId, endOptions } = params;
198
+ if (!span) return;
199
+ await this.wrapDurableOperation(operationId, async () => {
200
+ span.end(endOptions);
201
+ });
202
+ }
203
+ /**
204
+ * Record error on step span durably.
205
+ */
206
+ async errorStepSpan(params) {
207
+ const { span, operationId, errorOptions } = params;
208
+ if (!span) return;
209
+ await this.wrapDurableOperation(operationId, async () => {
210
+ span.error(errorOptions);
211
+ });
212
+ }
213
+ /**
214
+ * Create a generic child span durably (for control-flow operations).
215
+ * On first execution, creates and exports span. On replay, returns cached span data.
216
+ */
217
+ async createChildSpan(params) {
218
+ const { executionContext, operationId, options, parentSpan } = params;
219
+ const parentSpanId = parentSpan?.id ?? executionContext.tracingIds?.workflowSpanId;
220
+ const exportedSpan = await this.wrapDurableOperation(operationId, async () => {
221
+ const observability = this.mastra?.observability?.getSelectedInstance({});
222
+ if (!observability) return void 0;
223
+ const span = observability.startSpan({
224
+ ...options,
225
+ traceId: executionContext.tracingIds?.traceId,
226
+ parentSpanId
227
+ });
228
+ return span?.exportSpan();
229
+ });
230
+ if (exportedSpan) {
231
+ const observability = this.mastra?.observability?.getSelectedInstance({});
232
+ return observability?.rebuildSpan(exportedSpan);
233
+ }
234
+ return void 0;
235
+ }
236
+ /**
237
+ * End a generic child span durably (for control-flow operations).
238
+ */
239
+ async endChildSpan(params) {
240
+ const { span, operationId, endOptions } = params;
241
+ if (!span) return;
242
+ await this.wrapDurableOperation(operationId, async () => {
243
+ span.end(endOptions);
244
+ });
245
+ }
246
+ /**
247
+ * Record error on a generic child span durably (for control-flow operations).
248
+ */
249
+ async errorChildSpan(params) {
250
+ const { span, operationId, errorOptions } = params;
251
+ if (!span) return;
252
+ await this.wrapDurableOperation(operationId, async () => {
253
+ span.error(errorOptions);
254
+ });
255
+ }
139
256
  /**
140
257
  * Execute nested InngestWorkflow using inngestStep.invoke() for durability.
141
258
  * This MUST be called directly (not inside step.run()) due to Inngest constraints.
@@ -144,7 +261,23 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
144
261
  if (!(params.step instanceof InngestWorkflow)) {
145
262
  return null;
146
263
  }
147
- const { step, stepResults, executionContext, resume, timeTravel, prevOutput, inputData, pubsub, startedAt } = params;
264
+ const {
265
+ step,
266
+ stepResults,
267
+ executionContext,
268
+ resume,
269
+ timeTravel,
270
+ prevOutput,
271
+ inputData,
272
+ pubsub,
273
+ startedAt,
274
+ perStep,
275
+ stepSpan
276
+ } = params;
277
+ const nestedTracingContext = executionContext.tracingIds?.traceId ? {
278
+ traceId: executionContext.tracingIds.traceId,
279
+ parentSpanId: stepSpan?.id
280
+ } : void 0;
148
281
  const isResume = !!resume?.steps?.length;
149
282
  let result;
150
283
  let runId;
@@ -152,7 +285,8 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
152
285
  try {
153
286
  if (isResume) {
154
287
  runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? randomUUID();
155
- const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
288
+ const workflowsStore = await this.mastra?.getStorage()?.getStore("workflows");
289
+ const snapshot = await workflowsStore?.loadWorkflowSnapshot({
156
290
  workflowName: step.id,
157
291
  runId
158
292
  });
@@ -169,14 +303,17 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
169
303
  resumePayload: resume.resumePayload,
170
304
  resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
171
305
  },
172
- outputOptions: { includeState: true }
306
+ outputOptions: { includeState: true },
307
+ perStep,
308
+ tracingOptions: nestedTracingContext
173
309
  }
174
310
  });
175
311
  result = invokeResp.result;
176
312
  runId = invokeResp.runId;
177
313
  executionContext.state = invokeResp.result.state;
178
314
  } else if (isTimeTravel) {
179
- const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
315
+ const workflowsStoreForTimeTravel = await this.mastra?.getStorage()?.getStore("workflows");
316
+ const snapshot = await workflowsStoreForTimeTravel?.loadWorkflowSnapshot({
180
317
  workflowName: step.id,
181
318
  runId: executionContext.runId
182
319
  }) ?? { context: {} };
@@ -195,7 +332,9 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
195
332
  timeTravel: timeTravelParams,
196
333
  initialState: executionContext.state ?? {},
197
334
  runId: executionContext.runId,
198
- outputOptions: { includeState: true }
335
+ outputOptions: { includeState: true },
336
+ perStep,
337
+ tracingOptions: nestedTracingContext
199
338
  }
200
339
  });
201
340
  result = invokeResp.result;
@@ -207,7 +346,9 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
207
346
  data: {
208
347
  inputData,
209
348
  initialState: executionContext.state ?? {},
210
- outputOptions: { includeState: true }
349
+ outputOptions: { includeState: true },
350
+ perStep,
351
+ tracingOptions: nestedTracingContext
211
352
  }
212
353
  });
213
354
  result = invokeResp.result;
@@ -246,7 +387,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
246
387
  }
247
388
  }
248
389
  });
249
- return { executionContext, result: { status: "failed", error: result?.error } };
390
+ return { executionContext, result: { status: "failed", error: result?.error, endedAt: Date.now() } };
250
391
  } else if (result.status === "suspended") {
251
392
  const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
252
393
  const stepRes = stepResult;
@@ -270,6 +411,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
270
411
  executionContext,
271
412
  result: {
272
413
  status: "suspended",
414
+ suspendedAt: Date.now(),
273
415
  payload: stepResult.payload,
274
416
  suspendPayload: {
275
417
  ...stepResult?.suspendPayload,
@@ -282,6 +424,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
282
424
  executionContext,
283
425
  result: {
284
426
  status: "suspended",
427
+ suspendedAt: Date.now(),
285
428
  payload: {}
286
429
  }
287
430
  };
@@ -303,9 +446,34 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
303
446
  executionContext,
304
447
  result: {
305
448
  status: "tripwire",
306
- tripwire: result?.tripwire
449
+ tripwire: result?.tripwire,
450
+ endedAt: Date.now()
307
451
  }
308
452
  };
453
+ } else if (perStep || result.status === "paused") {
454
+ await pubsub.publish(`workflow.events.v2.${executionContext.runId}`, {
455
+ type: "watch",
456
+ runId: executionContext.runId,
457
+ data: {
458
+ type: "workflow-step-result",
459
+ payload: {
460
+ id: step.id,
461
+ status: "paused"
462
+ }
463
+ }
464
+ });
465
+ await pubsub.publish(`workflow.events.v2.${executionContext.runId}`, {
466
+ type: "watch",
467
+ runId: executionContext.runId,
468
+ data: {
469
+ type: "workflow-step-finish",
470
+ payload: {
471
+ id: step.id,
472
+ metadata: {}
473
+ }
474
+ }
475
+ });
476
+ return { executionContext, result: { status: "paused" } };
309
477
  }
310
478
  await pubsub.publish(`workflow.events.v2.${executionContext.runId}`, {
311
479
  type: "watch",
@@ -330,14 +498,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
330
498
  }
331
499
  }
332
500
  });
333
- return { executionContext, result: { status: "success", output: result?.result } };
501
+ return { executionContext, result: { status: "success", output: result?.result, endedAt: Date.now() } };
334
502
  }
335
503
  );
336
504
  Object.assign(executionContext, res.executionContext);
337
505
  return {
338
506
  ...res.result,
339
507
  startedAt,
340
- endedAt: Date.now(),
341
508
  payload: inputData,
342
509
  resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
343
510
  resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
@@ -506,6 +673,7 @@ var InngestRun = class extends Run {
506
673
  async getRunOutput(eventId, maxWaitMs = 3e5) {
507
674
  const startTime = Date.now();
508
675
  const storage = this.#mastra?.getStorage();
676
+ const workflowsStore = await storage?.getStore("workflows");
509
677
  while (Date.now() - startTime < maxWaitMs) {
510
678
  let runs;
511
679
  try {
@@ -522,7 +690,7 @@ var InngestRun = class extends Run {
522
690
  return runs[0];
523
691
  }
524
692
  if (runs?.[0]?.status === "Failed") {
525
- const snapshot = await storage?.loadWorkflowSnapshot({
693
+ const snapshot = await workflowsStore?.loadWorkflowSnapshot({
526
694
  workflowName: this.workflowId,
527
695
  runId: this.runId
528
696
  });
@@ -541,7 +709,7 @@ var InngestRun = class extends Run {
541
709
  };
542
710
  }
543
711
  if (runs?.[0]?.status === "Cancelled") {
544
- const snapshot = await storage?.loadWorkflowSnapshot({
712
+ const snapshot = await workflowsStore?.loadWorkflowSnapshot({
545
713
  workflowName: this.workflowId,
546
714
  runId: this.runId
547
715
  });
@@ -559,12 +727,13 @@ var InngestRun = class extends Run {
559
727
  runId: this.runId
560
728
  }
561
729
  });
562
- const snapshot = await storage?.loadWorkflowSnapshot({
730
+ const workflowsStore = await storage?.getStore("workflows");
731
+ const snapshot = await workflowsStore?.loadWorkflowSnapshot({
563
732
  workflowName: this.workflowId,
564
733
  runId: this.runId
565
734
  });
566
735
  if (snapshot) {
567
- await storage?.persistWorkflowSnapshot({
736
+ await workflowsStore?.persistWorkflowSnapshot({
568
737
  workflowName: this.workflowId,
569
738
  runId: this.runId,
570
739
  resourceId: this.resourceId,
@@ -576,8 +745,8 @@ var InngestRun = class extends Run {
576
745
  });
577
746
  }
578
747
  }
579
- async start(params) {
580
- return this._start(params);
748
+ async start(args) {
749
+ return this._start(args);
581
750
  }
582
751
  /**
583
752
  * Starts the workflow execution without waiting for completion (fire-and-forget).
@@ -585,8 +754,9 @@ var InngestRun = class extends Run {
585
754
  * The workflow executes independently in Inngest.
586
755
  * Use this when you don't need to wait for the result or want to avoid polling failures.
587
756
  */
588
- async startAsync(params) {
589
- await this.#mastra.getStorage()?.persistWorkflowSnapshot({
757
+ async startAsync(args) {
758
+ const workflowsStore = await this.#mastra.getStorage()?.getStore("workflows");
759
+ await workflowsStore?.persistWorkflowSnapshot({
590
760
  workflowName: this.workflowId,
591
761
  runId: this.runId,
592
762
  resourceId: this.resourceId,
@@ -604,8 +774,8 @@ var InngestRun = class extends Run {
604
774
  timestamp: Date.now()
605
775
  }
606
776
  });
607
- const inputDataToUse = await this._validateInput(params.inputData);
608
- const initialStateToUse = await this._validateInitialState(params.initialState ?? {});
777
+ const inputDataToUse = await this._validateInput(args.inputData);
778
+ const initialStateToUse = await this._validateInitialState(args.initialState ?? {});
609
779
  const eventOutput = await this.inngest.send({
610
780
  name: `workflow.${this.workflowId}`,
611
781
  data: {
@@ -613,9 +783,10 @@ var InngestRun = class extends Run {
613
783
  initialState: initialStateToUse,
614
784
  runId: this.runId,
615
785
  resourceId: this.resourceId,
616
- outputOptions: params.outputOptions,
617
- tracingOptions: params.tracingOptions,
618
- requestContext: params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {}
786
+ outputOptions: args.outputOptions,
787
+ tracingOptions: args.tracingOptions,
788
+ requestContext: args.requestContext ? Object.fromEntries(args.requestContext.entries()) : {},
789
+ perStep: args.perStep
619
790
  }
620
791
  });
621
792
  const eventId = eventOutput.ids[0];
@@ -630,9 +801,11 @@ var InngestRun = class extends Run {
630
801
  outputOptions,
631
802
  tracingOptions,
632
803
  format,
633
- requestContext
804
+ requestContext,
805
+ perStep
634
806
  }) {
635
- await this.#mastra.getStorage()?.persistWorkflowSnapshot({
807
+ const workflowsStore = await this.#mastra.getStorage()?.getStore("workflows");
808
+ await workflowsStore?.persistWorkflowSnapshot({
636
809
  workflowName: this.workflowId,
637
810
  runId: this.runId,
638
811
  resourceId: this.resourceId,
@@ -662,7 +835,8 @@ var InngestRun = class extends Run {
662
835
  outputOptions,
663
836
  tracingOptions,
664
837
  format,
665
- requestContext: requestContext ? Object.fromEntries(requestContext.entries()) : {}
838
+ requestContext: requestContext ? Object.fromEntries(requestContext.entries()) : {},
839
+ perStep
666
840
  }
667
841
  });
668
842
  const eventId = eventOutput.ids[0];
@@ -698,7 +872,8 @@ var InngestRun = class extends Run {
698
872
  (step) => typeof step === "string" ? step : step?.id
699
873
  );
700
874
  }
701
- const snapshot = await storage?.loadWorkflowSnapshot({
875
+ const workflowsStore = await storage?.getStore("workflows");
876
+ const snapshot = await workflowsStore?.loadWorkflowSnapshot({
702
877
  workflowName: this.workflowId,
703
878
  runId: this.runId
704
879
  });
@@ -721,7 +896,8 @@ var InngestRun = class extends Run {
721
896
  resumePayload: resumeDataToUse,
722
897
  resumePath: steps?.[0] ? snapshot?.suspendedPaths?.[steps?.[0]] : void 0
723
898
  },
724
- requestContext: mergedRequestContext
899
+ requestContext: mergedRequestContext,
900
+ perStep: params.perStep
725
901
  }
726
902
  });
727
903
  const eventId = eventOutput.ids[0];
@@ -760,12 +936,13 @@ var InngestRun = class extends Run {
760
936
  throw new Error("No steps provided to timeTravel");
761
937
  }
762
938
  const storage = this.#mastra?.getStorage();
763
- const snapshot = await storage?.loadWorkflowSnapshot({
939
+ const workflowsStore = await storage?.getStore("workflows");
940
+ const snapshot = await workflowsStore?.loadWorkflowSnapshot({
764
941
  workflowName: this.workflowId,
765
942
  runId: this.runId
766
943
  });
767
944
  if (!snapshot) {
768
- await storage?.persistWorkflowSnapshot({
945
+ await workflowsStore?.persistWorkflowSnapshot({
769
946
  workflowName: this.workflowId,
770
947
  runId: this.runId,
771
948
  resourceId: this.resourceId,
@@ -799,7 +976,8 @@ var InngestRun = class extends Run {
799
976
  nestedStepsContext: params.nestedStepsContext,
800
977
  snapshot: snapshot ?? { context: {} },
801
978
  graph: this.executionGraph,
802
- initialState: params.initialState
979
+ initialState: params.initialState,
980
+ perStep: params.perStep
803
981
  });
804
982
  const eventOutput = await this.inngest.send({
805
983
  name: `workflow.${this.workflowId}`,
@@ -811,7 +989,8 @@ var InngestRun = class extends Run {
811
989
  timeTravel: timeTravelData,
812
990
  tracingOptions: params.tracingOptions,
813
991
  outputOptions: params.outputOptions,
814
- requestContext: params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {}
992
+ requestContext: params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {},
993
+ perStep: params.perStep
815
994
  }
816
995
  });
817
996
  const eventId = eventOutput.ids[0];
@@ -850,9 +1029,8 @@ var InngestRun = class extends Run {
850
1029
  const { readable, writable } = new TransformStream();
851
1030
  const writer = writable.getWriter();
852
1031
  void writer.write({
853
- // @ts-ignore
1032
+ // @ts-expect-error - stream event type mismatch
854
1033
  type: "start",
855
- // @ts-ignore
856
1034
  payload: { runId: this.runId }
857
1035
  });
858
1036
  const unwatch = this.watch(async (event) => {
@@ -872,7 +1050,7 @@ var InngestRun = class extends Run {
872
1050
  this.closeStreamAction = async () => {
873
1051
  await writer.write({
874
1052
  type: "finish",
875
- // @ts-ignore
1053
+ // @ts-expect-error - stream event type mismatch
876
1054
  payload: { runId: this.runId }
877
1055
  });
878
1056
  unwatch();
@@ -902,7 +1080,8 @@ var InngestRun = class extends Run {
902
1080
  tracingOptions,
903
1081
  closeOnSuspend = true,
904
1082
  initialState,
905
- outputOptions
1083
+ outputOptions,
1084
+ perStep
906
1085
  } = {}) {
907
1086
  if (this.closeStreamAction && this.streamOutput) {
908
1087
  return this.streamOutput;
@@ -938,7 +1117,8 @@ var InngestRun = class extends Run {
938
1117
  initialState,
939
1118
  tracingOptions,
940
1119
  outputOptions,
941
- format: "vnext"
1120
+ format: "vnext",
1121
+ perStep
942
1122
  });
943
1123
  let executionResults;
944
1124
  try {
@@ -969,9 +1149,6 @@ var InngestRun = class extends Run {
969
1149
  });
970
1150
  return this.streamOutput;
971
1151
  }
972
- streamVNext(args = {}) {
973
- return this.stream(args);
974
- }
975
1152
  timeTravelStream({
976
1153
  inputData,
977
1154
  resumeData,
@@ -980,8 +1157,10 @@ var InngestRun = class extends Run {
980
1157
  context,
981
1158
  nestedStepsContext,
982
1159
  requestContext,
1160
+ // tracingContext,
983
1161
  tracingOptions,
984
- outputOptions
1162
+ outputOptions,
1163
+ perStep
985
1164
  }) {
986
1165
  this.closeStreamAction = async () => {
987
1166
  };
@@ -1016,7 +1195,8 @@ var InngestRun = class extends Run {
1016
1195
  initialState,
1017
1196
  requestContext,
1018
1197
  tracingOptions,
1019
- outputOptions
1198
+ outputOptions,
1199
+ perStep
1020
1200
  });
1021
1201
  self.executionResults = executionResultsPromise;
1022
1202
  let executionResults;
@@ -1060,9 +1240,11 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
1060
1240
  #mastra;
1061
1241
  inngest;
1062
1242
  function;
1243
+ cronFunction;
1063
1244
  flowControlConfig;
1245
+ cronConfig;
1064
1246
  constructor(params, inngest) {
1065
- const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
1247
+ const { concurrency, rateLimit, throttle, debounce, priority, cron, inputData, initialState, ...workflowParams } = params;
1066
1248
  super(workflowParams);
1067
1249
  this.engineType = "inngest";
1068
1250
  const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
@@ -1071,6 +1253,9 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
1071
1253
  this.flowControlConfig = flowControlEntries.length > 0 ? Object.fromEntries(flowControlEntries) : void 0;
1072
1254
  this.#mastra = params.mastra;
1073
1255
  this.inngest = inngest;
1256
+ if (cron) {
1257
+ this.cronConfig = { cron, inputData, initialState };
1258
+ }
1074
1259
  }
1075
1260
  async listWorkflowRuns(args) {
1076
1261
  const storage = this.#mastra?.getStorage();
@@ -1078,16 +1263,11 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
1078
1263
  this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
1079
1264
  return { runs: [], total: 0 };
1080
1265
  }
1081
- return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
1082
- }
1083
- async getWorkflowRunById(runId) {
1084
- const storage = this.#mastra?.getStorage();
1085
- if (!storage) {
1086
- this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
1087
- return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
1266
+ const workflowsStore = await storage.getStore("workflows");
1267
+ if (!workflowsStore) {
1268
+ return { runs: [], total: 0 };
1088
1269
  }
1089
- const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
1090
- return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
1270
+ return workflowsStore.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
1091
1271
  }
1092
1272
  __registerMastra(mastra) {
1093
1273
  super.__registerMastra(mastra);
@@ -1110,7 +1290,8 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
1110
1290
  }
1111
1291
  async createRun(options) {
1112
1292
  const runIdToUse = options?.runId || randomUUID();
1113
- const run = this.runs.get(runIdToUse) ?? new InngestRun(
1293
+ const existingInMemoryRun = this.runs.get(runIdToUse);
1294
+ const newRun = new InngestRun(
1114
1295
  {
1115
1296
  workflowId: this.id,
1116
1297
  runId: runIdToUse,
@@ -1127,14 +1308,19 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
1127
1308
  },
1128
1309
  this.inngest
1129
1310
  );
1311
+ const run = existingInMemoryRun ?? newRun;
1130
1312
  this.runs.set(runIdToUse, run);
1131
1313
  const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
1132
1314
  workflowStatus: run.workflowRunStatus,
1133
1315
  stepResults: {}
1134
1316
  });
1135
- const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
1136
- if (!workflowSnapshotInStorage && shouldPersistSnapshot) {
1137
- await this.mastra?.getStorage()?.persistWorkflowSnapshot({
1317
+ const existingStoredRun = await this.getWorkflowRunById(runIdToUse, {
1318
+ withNestedWorkflows: false
1319
+ });
1320
+ const existsInStorage = existingStoredRun && !existingStoredRun.isFromInMemory;
1321
+ if (!existsInStorage && shouldPersistSnapshot) {
1322
+ const workflowsStore = await this.mastra?.getStorage()?.getStore("workflows");
1323
+ await workflowsStore?.persistWorkflowSnapshot({
1138
1324
  workflowName: this.id,
1139
1325
  runId: runIdToUse,
1140
1326
  resourceId: options?.resourceId,
@@ -1157,6 +1343,30 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
1157
1343
  }
1158
1344
  return run;
1159
1345
  }
1346
+ //createCronFunction is only called if cronConfig.cron is defined.
1347
+ createCronFunction() {
1348
+ if (this.cronFunction) {
1349
+ return this.cronFunction;
1350
+ }
1351
+ this.cronFunction = this.inngest.createFunction(
1352
+ {
1353
+ id: `workflow.${this.id}.cron`,
1354
+ retries: 0,
1355
+ cancelOn: [{ event: `cancel.workflow.${this.id}` }],
1356
+ ...this.flowControlConfig
1357
+ },
1358
+ { cron: this.cronConfig?.cron ?? "" },
1359
+ async () => {
1360
+ const run = await this.createRun();
1361
+ const result = await run.start({
1362
+ inputData: this.cronConfig?.inputData,
1363
+ initialState: this.cronConfig?.initialState
1364
+ });
1365
+ return { result, runId: run.runId };
1366
+ }
1367
+ );
1368
+ return this.cronFunction;
1369
+ }
1160
1370
  getFunction() {
1161
1371
  if (this.function) {
1162
1372
  return this.function;
@@ -1164,51 +1374,128 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
1164
1374
  this.function = this.inngest.createFunction(
1165
1375
  {
1166
1376
  id: `workflow.${this.id}`,
1167
- retries: Math.min(this.retryConfig?.attempts ?? 0, 20),
1377
+ retries: 0,
1168
1378
  cancelOn: [{ event: `cancel.workflow.${this.id}` }],
1169
1379
  // Spread flow control configuration
1170
1380
  ...this.flowControlConfig
1171
1381
  },
1172
1382
  { event: `workflow.${this.id}` },
1173
1383
  async ({ event, step, attempt, publish }) => {
1174
- let { inputData, initialState, runId, resourceId, resume, outputOptions, format, timeTravel } = event.data;
1384
+ let {
1385
+ inputData,
1386
+ initialState,
1387
+ runId,
1388
+ resourceId,
1389
+ resume,
1390
+ outputOptions,
1391
+ format,
1392
+ timeTravel,
1393
+ perStep,
1394
+ tracingOptions
1395
+ } = event.data;
1175
1396
  if (!runId) {
1176
1397
  runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
1177
1398
  return randomUUID();
1178
1399
  });
1179
1400
  }
1180
1401
  const pubsub = new InngestPubSub(this.inngest, this.id, publish);
1402
+ const requestContext = new RequestContext(Object.entries(event.data.requestContext ?? {}));
1403
+ const mastra = this.#mastra;
1404
+ const tracingPolicy = this.options.tracingPolicy;
1405
+ const workflowSpanData = await step.run(`workflow.${this.id}.span.start`, async () => {
1406
+ const observability = mastra?.observability?.getSelectedInstance({ requestContext });
1407
+ if (!observability) return void 0;
1408
+ const span = observability.startSpan({
1409
+ type: SpanType.WORKFLOW_RUN,
1410
+ name: `workflow run: '${this.id}'`,
1411
+ entityType: EntityType.WORKFLOW_RUN,
1412
+ entityId: this.id,
1413
+ input: inputData,
1414
+ metadata: {
1415
+ resourceId,
1416
+ runId
1417
+ },
1418
+ tracingPolicy,
1419
+ tracingOptions,
1420
+ requestContext
1421
+ });
1422
+ return span?.exportSpan();
1423
+ });
1181
1424
  const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
1182
- const result = await engine.execute({
1183
- workflowId: this.id,
1184
- runId,
1185
- resourceId,
1186
- graph: this.executionGraph,
1187
- serializedStepGraph: this.serializedStepGraph,
1188
- input: inputData,
1189
- initialState,
1190
- pubsub,
1191
- retryConfig: this.retryConfig,
1192
- requestContext: new RequestContext(Object.entries(event.data.requestContext ?? {})),
1193
- resume,
1194
- timeTravel,
1195
- format,
1196
- abortController: new AbortController(),
1197
- // currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
1198
- outputOptions,
1199
- outputWriter: async (chunk) => {
1200
- try {
1201
- await pubsub.publish(`workflow.events.v2.${runId}`, {
1202
- type: "watch",
1203
- runId,
1204
- data: chunk
1205
- });
1206
- } catch (err) {
1207
- this.logger.debug?.("Failed to publish watch event:", err);
1425
+ let result;
1426
+ try {
1427
+ result = await engine.execute({
1428
+ workflowId: this.id,
1429
+ runId,
1430
+ resourceId,
1431
+ graph: this.executionGraph,
1432
+ serializedStepGraph: this.serializedStepGraph,
1433
+ input: inputData,
1434
+ initialState,
1435
+ pubsub,
1436
+ retryConfig: this.retryConfig,
1437
+ requestContext,
1438
+ resume,
1439
+ timeTravel,
1440
+ perStep,
1441
+ format,
1442
+ abortController: new AbortController(),
1443
+ // For Inngest, we don't pass workflowSpan - step spans use tracingIds instead
1444
+ workflowSpan: void 0,
1445
+ // Pass tracing IDs for durable span operations
1446
+ tracingIds: workflowSpanData ? {
1447
+ traceId: workflowSpanData.traceId,
1448
+ workflowSpanId: workflowSpanData.id
1449
+ } : void 0,
1450
+ outputOptions,
1451
+ outputWriter: async (chunk) => {
1452
+ try {
1453
+ await pubsub.publish(`workflow.events.v2.${runId}`, {
1454
+ type: "watch",
1455
+ runId,
1456
+ data: chunk
1457
+ });
1458
+ } catch (err) {
1459
+ this.logger.debug?.("Failed to publish watch event:", err);
1460
+ }
1208
1461
  }
1209
- }
1210
- });
1462
+ });
1463
+ } catch (error) {
1464
+ throw error;
1465
+ }
1211
1466
  await step.run(`workflow.${this.id}.finalize`, async () => {
1467
+ if (result.status !== "paused") {
1468
+ await engine.invokeLifecycleCallbacksInternal({
1469
+ status: result.status,
1470
+ result: "result" in result ? result.result : void 0,
1471
+ error: "error" in result ? result.error : void 0,
1472
+ steps: result.steps,
1473
+ tripwire: "tripwire" in result ? result.tripwire : void 0,
1474
+ runId,
1475
+ workflowId: this.id,
1476
+ resourceId,
1477
+ input: inputData,
1478
+ requestContext,
1479
+ state: result.state ?? initialState ?? {}
1480
+ });
1481
+ }
1482
+ if (workflowSpanData) {
1483
+ const observability = mastra?.observability?.getSelectedInstance({ requestContext });
1484
+ if (observability) {
1485
+ const workflowSpan = observability.rebuildSpan(workflowSpanData);
1486
+ if (result.status === "failed") {
1487
+ workflowSpan.error({
1488
+ error: result.error instanceof Error ? result.error : new Error(String(result.error)),
1489
+ attributes: { status: "failed" }
1490
+ });
1491
+ } else {
1492
+ workflowSpan.end({
1493
+ output: result.status === "success" ? result.result : void 0,
1494
+ attributes: { status: result.status }
1495
+ });
1496
+ }
1497
+ }
1498
+ }
1212
1499
  if (result.status === "failed") {
1213
1500
  throw new NonRetriableError(`Workflow failed`, {
1214
1501
  cause: result
@@ -1235,15 +1522,14 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
1235
1522
  });
1236
1523
  }
1237
1524
  getFunctions() {
1238
- return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
1525
+ return [
1526
+ this.getFunction(),
1527
+ ...this.cronConfig?.cron ? [this.createCronFunction()] : [],
1528
+ ...this.getNestedFunctions(this.executionGraph.steps)
1529
+ ];
1239
1530
  }
1240
1531
  };
1241
- function serve({
1242
- mastra,
1243
- inngest,
1244
- functions: userFunctions = [],
1245
- registerOptions
1246
- }) {
1532
+ function prepareServeOptions({ mastra, inngest, functions: userFunctions = [], registerOptions }) {
1247
1533
  const wfs = mastra.listWorkflows();
1248
1534
  const workflowFunctions = Array.from(
1249
1535
  new Set(
@@ -1256,177 +1542,181 @@ function serve({
1256
1542
  })
1257
1543
  )
1258
1544
  );
1259
- return serve$1({
1545
+ return {
1260
1546
  ...registerOptions,
1261
1547
  client: inngest,
1262
1548
  functions: [...workflowFunctions, ...userFunctions]
1263
- });
1549
+ };
1550
+ }
1551
+ function createServe(adapter) {
1552
+ return (options) => {
1553
+ const serveOptions = prepareServeOptions(options);
1554
+ return adapter(serveOptions);
1555
+ };
1264
1556
  }
1557
+ var serve = createServe(serve$1);
1265
1558
 
1266
1559
  // src/types.ts
1267
1560
  var _compatibilityCheck = true;
1268
1561
 
1269
1562
  // src/index.ts
1270
- function isAgent(params) {
1271
- return params?.component === "AGENT";
1563
+ function isInngestWorkflow(input) {
1564
+ return input instanceof InngestWorkflow;
1565
+ }
1566
+ function isAgent(input) {
1567
+ return input instanceof Agent;
1568
+ }
1569
+ function isToolStep(input) {
1570
+ return input instanceof Tool;
1272
1571
  }
1273
- function isTool(params) {
1274
- return params instanceof Tool;
1572
+ function isStepParams(input) {
1573
+ return input !== null && typeof input === "object" && "id" in input && "execute" in input && !(input instanceof Agent) && !(input instanceof Tool) && !(input instanceof InngestWorkflow);
1275
1574
  }
1276
- function isInngestWorkflow(params) {
1277
- return params instanceof InngestWorkflow;
1575
+ function isProcessor(obj) {
1576
+ return obj !== null && typeof obj === "object" && "id" in obj && typeof obj.id === "string" && !(obj instanceof Agent) && !(obj instanceof Tool) && !(obj instanceof InngestWorkflow) && (typeof obj.processInput === "function" || typeof obj.processInputStep === "function" || typeof obj.processOutputStream === "function" || typeof obj.processOutputResult === "function" || typeof obj.processOutputStep === "function");
1278
1577
  }
1279
- function createStep(params, agentOptions) {
1578
+ function createStep(params, agentOrToolOptions) {
1280
1579
  if (isInngestWorkflow(params)) {
1281
1580
  return params;
1282
1581
  }
1283
1582
  if (isAgent(params)) {
1284
- const outputSchema = agentOptions?.structuredOutput?.schema ?? z.object({ text: z.string() });
1285
- return {
1286
- id: params.name,
1287
- description: params.getDescription(),
1288
- inputSchema: z.object({
1289
- prompt: z.string()
1290
- // resourceId: z.string().optional(),
1291
- // threadId: z.string().optional(),
1292
- }),
1293
- outputSchema,
1294
- execute: async ({
1295
- inputData,
1296
- runId,
1297
- [PUBSUB_SYMBOL]: pubsub,
1298
- [STREAM_FORMAT_SYMBOL]: streamFormat,
1299
- requestContext,
1300
- tracingContext,
1301
- abortSignal,
1302
- abort,
1303
- writer
1304
- }) => {
1305
- let streamPromise = {};
1306
- streamPromise.promise = new Promise((resolve, reject) => {
1307
- streamPromise.resolve = resolve;
1308
- streamPromise.reject = reject;
1583
+ return createStepFromAgent(params, agentOrToolOptions);
1584
+ }
1585
+ if (isToolStep(params)) {
1586
+ return createStepFromTool(params, agentOrToolOptions);
1587
+ }
1588
+ if (isStepParams(params)) {
1589
+ return createStepFromParams(params);
1590
+ }
1591
+ if (isProcessor(params)) {
1592
+ return createStepFromProcessor(params);
1593
+ }
1594
+ throw new Error("Invalid input: expected StepParams, Agent, ToolStep, Processor, or InngestWorkflow");
1595
+ }
1596
+ function createStepFromParams(params) {
1597
+ return {
1598
+ id: params.id,
1599
+ description: params.description,
1600
+ inputSchema: params.inputSchema,
1601
+ stateSchema: params.stateSchema,
1602
+ outputSchema: params.outputSchema,
1603
+ resumeSchema: params.resumeSchema,
1604
+ suspendSchema: params.suspendSchema,
1605
+ scorers: params.scorers,
1606
+ retries: params.retries,
1607
+ execute: params.execute.bind(params)
1608
+ };
1609
+ }
1610
+ function createStepFromAgent(params, agentOrToolOptions) {
1611
+ const options = agentOrToolOptions ?? {};
1612
+ const outputSchema = options?.structuredOutput?.schema ?? z.object({ text: z.string() });
1613
+ const { retries, scorers, ...agentOptions } = options ?? {};
1614
+ return {
1615
+ id: params.name,
1616
+ description: params.getDescription(),
1617
+ inputSchema: z.object({
1618
+ prompt: z.string()
1619
+ }),
1620
+ outputSchema,
1621
+ retries,
1622
+ scorers,
1623
+ execute: async ({
1624
+ inputData,
1625
+ runId,
1626
+ [PUBSUB_SYMBOL]: pubsub,
1627
+ [STREAM_FORMAT_SYMBOL]: streamFormat,
1628
+ requestContext,
1629
+ tracingContext,
1630
+ abortSignal,
1631
+ abort,
1632
+ writer
1633
+ }) => {
1634
+ let streamPromise = {};
1635
+ streamPromise.promise = new Promise((resolve, reject) => {
1636
+ streamPromise.resolve = resolve;
1637
+ streamPromise.reject = reject;
1638
+ });
1639
+ let structuredResult = null;
1640
+ const toolData = {
1641
+ name: params.name,
1642
+ args: inputData
1643
+ };
1644
+ let stream;
1645
+ if ((await params.getModel()).specificationVersion === "v1") {
1646
+ const { fullStream } = await params.streamLegacy(inputData.prompt, {
1647
+ ...agentOptions ?? {},
1648
+ requestContext,
1649
+ tracingContext,
1650
+ onFinish: (result) => {
1651
+ const resultWithObject = result;
1652
+ if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
1653
+ structuredResult = resultWithObject.object;
1654
+ }
1655
+ streamPromise.resolve(result.text);
1656
+ void agentOptions?.onFinish?.(result);
1657
+ },
1658
+ abortSignal
1309
1659
  });
1310
- let structuredResult = null;
1311
- const toolData = {
1312
- name: params.name,
1313
- args: inputData
1314
- };
1315
- let stream;
1316
- if ((await params.getModel()).specificationVersion === "v1") {
1317
- const { fullStream } = await params.streamLegacy(inputData.prompt, {
1318
- ...agentOptions ?? {},
1319
- // resourceId: inputData.resourceId,
1320
- // threadId: inputData.threadId,
1321
- requestContext,
1322
- tracingContext,
1323
- onFinish: (result) => {
1324
- const resultWithObject = result;
1325
- if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
1326
- structuredResult = resultWithObject.object;
1327
- }
1328
- streamPromise.resolve(result.text);
1329
- void agentOptions?.onFinish?.(result);
1330
- },
1331
- abortSignal
1332
- });
1333
- stream = fullStream;
1334
- } else {
1335
- const modelOutput = await params.stream(inputData.prompt, {
1336
- ...agentOptions ?? {},
1337
- requestContext,
1338
- tracingContext,
1339
- onFinish: (result) => {
1340
- const resultWithObject = result;
1341
- if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
1342
- structuredResult = resultWithObject.object;
1343
- }
1344
- streamPromise.resolve(result.text);
1345
- void agentOptions?.onFinish?.(result);
1346
- },
1347
- abortSignal
1348
- });
1349
- stream = modelOutput.fullStream;
1350
- }
1351
- if (streamFormat === "legacy") {
1352
- await pubsub.publish(`workflow.events.v2.${runId}`, {
1353
- type: "watch",
1354
- runId,
1355
- data: { type: "tool-call-streaming-start", ...toolData ?? {} }
1356
- });
1357
- for await (const chunk of stream) {
1358
- if (chunk.type === "text-delta") {
1359
- await pubsub.publish(`workflow.events.v2.${runId}`, {
1360
- type: "watch",
1361
- runId,
1362
- data: { type: "tool-call-delta", ...toolData ?? {}, argsTextDelta: chunk.textDelta }
1363
- });
1660
+ stream = fullStream;
1661
+ } else {
1662
+ const modelOutput = await params.stream(inputData.prompt, {
1663
+ ...agentOptions ?? {},
1664
+ requestContext,
1665
+ tracingContext,
1666
+ onFinish: (result) => {
1667
+ const resultWithObject = result;
1668
+ if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
1669
+ structuredResult = resultWithObject.object;
1364
1670
  }
1671
+ streamPromise.resolve(result.text);
1672
+ void agentOptions?.onFinish?.(result);
1673
+ },
1674
+ abortSignal
1675
+ });
1676
+ stream = modelOutput.fullStream;
1677
+ }
1678
+ if (streamFormat === "legacy") {
1679
+ await pubsub.publish(`workflow.events.v2.${runId}`, {
1680
+ type: "watch",
1681
+ runId,
1682
+ data: { type: "tool-call-streaming-start", ...toolData ?? {} }
1683
+ });
1684
+ for await (const chunk of stream) {
1685
+ if (chunk.type === "text-delta") {
1686
+ await pubsub.publish(`workflow.events.v2.${runId}`, {
1687
+ type: "watch",
1688
+ runId,
1689
+ data: { type: "tool-call-delta", ...toolData ?? {}, argsTextDelta: chunk.textDelta }
1690
+ });
1365
1691
  }
1366
- await pubsub.publish(`workflow.events.v2.${runId}`, {
1367
- type: "watch",
1368
- runId,
1369
- data: { type: "tool-call-streaming-finish", ...toolData ?? {} }
1370
- });
1371
- } else {
1372
- for await (const chunk of stream) {
1373
- await writer.write(chunk);
1374
- }
1375
- }
1376
- if (abortSignal.aborted) {
1377
- return abort();
1378
1692
  }
1379
- if (structuredResult !== null) {
1380
- return structuredResult;
1693
+ await pubsub.publish(`workflow.events.v2.${runId}`, {
1694
+ type: "watch",
1695
+ runId,
1696
+ data: { type: "tool-call-streaming-finish", ...toolData ?? {} }
1697
+ });
1698
+ } else {
1699
+ for await (const chunk of stream) {
1700
+ await writer.write(chunk);
1381
1701
  }
1382
- return {
1383
- text: await streamPromise.promise
1384
- };
1385
- },
1386
- component: params.component
1387
- };
1388
- }
1389
- if (isTool(params)) {
1390
- if (!params.inputSchema || !params.outputSchema) {
1391
- throw new Error("Tool must have input and output schemas defined");
1392
- }
1393
- return {
1394
- // TODO: tool probably should have strong id type
1395
- id: params.id,
1396
- description: params.description,
1397
- inputSchema: params.inputSchema,
1398
- outputSchema: params.outputSchema,
1399
- suspendSchema: params.suspendSchema,
1400
- resumeSchema: params.resumeSchema,
1401
- execute: async ({
1402
- inputData,
1403
- mastra,
1404
- requestContext,
1405
- tracingContext,
1406
- suspend,
1407
- resumeData,
1408
- runId,
1409
- workflowId,
1410
- state,
1411
- setState
1412
- }) => {
1413
- const toolContext = {
1414
- mastra,
1415
- requestContext,
1416
- tracingContext,
1417
- workflow: {
1418
- runId,
1419
- resumeData,
1420
- suspend,
1421
- workflowId,
1422
- state,
1423
- setState
1424
- }
1425
- };
1426
- return params.execute(inputData, toolContext);
1427
- },
1428
- component: "TOOL"
1429
- };
1702
+ }
1703
+ if (abortSignal.aborted) {
1704
+ return abort();
1705
+ }
1706
+ if (structuredResult !== null) {
1707
+ return structuredResult;
1708
+ }
1709
+ return {
1710
+ text: await streamPromise.promise
1711
+ };
1712
+ },
1713
+ component: params.component
1714
+ };
1715
+ }
1716
+ function createStepFromTool(params, agentOrToolOptions) {
1717
+ const toolOpts = agentOrToolOptions;
1718
+ if (!params.inputSchema || !params.outputSchema) {
1719
+ throw new Error("Tool must have input and output schemas defined");
1430
1720
  }
1431
1721
  return {
1432
1722
  id: params.id,
@@ -1435,7 +1725,480 @@ function createStep(params, agentOptions) {
1435
1725
  outputSchema: params.outputSchema,
1436
1726
  resumeSchema: params.resumeSchema,
1437
1727
  suspendSchema: params.suspendSchema,
1438
- execute: params.execute
1728
+ retries: toolOpts?.retries,
1729
+ scorers: toolOpts?.scorers,
1730
+ execute: async ({
1731
+ inputData,
1732
+ mastra,
1733
+ requestContext,
1734
+ tracingContext,
1735
+ suspend,
1736
+ resumeData,
1737
+ runId,
1738
+ workflowId,
1739
+ state,
1740
+ setState
1741
+ }) => {
1742
+ const toolContext = {
1743
+ mastra,
1744
+ requestContext,
1745
+ tracingContext,
1746
+ workflow: {
1747
+ runId,
1748
+ resumeData,
1749
+ suspend,
1750
+ workflowId,
1751
+ state,
1752
+ setState
1753
+ }
1754
+ };
1755
+ return params.execute(inputData, toolContext);
1756
+ },
1757
+ component: "TOOL"
1758
+ };
1759
+ }
1760
+ function createStepFromProcessor(processor) {
1761
+ const getProcessorEntityType = (phase) => {
1762
+ switch (phase) {
1763
+ case "input":
1764
+ return EntityType.INPUT_PROCESSOR;
1765
+ case "inputStep":
1766
+ return EntityType.INPUT_STEP_PROCESSOR;
1767
+ case "outputStream":
1768
+ case "outputResult":
1769
+ return EntityType.OUTPUT_PROCESSOR;
1770
+ case "outputStep":
1771
+ return EntityType.OUTPUT_STEP_PROCESSOR;
1772
+ default:
1773
+ return EntityType.OUTPUT_PROCESSOR;
1774
+ }
1775
+ };
1776
+ const getSpanNamePrefix = (phase) => {
1777
+ switch (phase) {
1778
+ case "input":
1779
+ return "input processor";
1780
+ case "inputStep":
1781
+ return "input step processor";
1782
+ case "outputStream":
1783
+ return "output stream processor";
1784
+ case "outputResult":
1785
+ return "output processor";
1786
+ case "outputStep":
1787
+ return "output step processor";
1788
+ default:
1789
+ return "processor";
1790
+ }
1791
+ };
1792
+ const hasPhaseMethod = (phase) => {
1793
+ switch (phase) {
1794
+ case "input":
1795
+ return !!processor.processInput;
1796
+ case "inputStep":
1797
+ return !!processor.processInputStep;
1798
+ case "outputStream":
1799
+ return !!processor.processOutputStream;
1800
+ case "outputResult":
1801
+ return !!processor.processOutputResult;
1802
+ case "outputStep":
1803
+ return !!processor.processOutputStep;
1804
+ default:
1805
+ return false;
1806
+ }
1807
+ };
1808
+ return {
1809
+ id: `processor:${processor.id}`,
1810
+ description: processor.name ?? `Processor ${processor.id}`,
1811
+ inputSchema: ProcessorStepSchema,
1812
+ outputSchema: ProcessorStepOutputSchema,
1813
+ execute: async ({ inputData, requestContext, tracingContext }) => {
1814
+ const input = inputData;
1815
+ const {
1816
+ phase,
1817
+ messages,
1818
+ messageList,
1819
+ stepNumber,
1820
+ systemMessages,
1821
+ part,
1822
+ streamParts,
1823
+ state,
1824
+ finishReason,
1825
+ toolCalls,
1826
+ text,
1827
+ retryCount,
1828
+ // inputStep phase fields for model/tools configuration
1829
+ model,
1830
+ tools,
1831
+ toolChoice,
1832
+ activeTools,
1833
+ providerOptions,
1834
+ modelSettings,
1835
+ structuredOutput,
1836
+ steps
1837
+ } = input;
1838
+ const abort = (reason, options) => {
1839
+ throw new TripWire(reason || `Tripwire triggered by ${processor.id}`, options, processor.id);
1840
+ };
1841
+ if (!hasPhaseMethod(phase)) {
1842
+ return input;
1843
+ }
1844
+ const currentSpan = tracingContext?.currentSpan;
1845
+ const parentSpan = phase === "inputStep" || phase === "outputStep" ? currentSpan?.findParent(SpanType.MODEL_STEP) || currentSpan : currentSpan?.findParent(SpanType.AGENT_RUN) || currentSpan;
1846
+ const processorSpan = phase !== "outputStream" ? parentSpan?.createChildSpan({
1847
+ type: SpanType.PROCESSOR_RUN,
1848
+ name: `${getSpanNamePrefix(phase)}: ${processor.id}`,
1849
+ entityType: getProcessorEntityType(phase),
1850
+ entityId: processor.id,
1851
+ entityName: processor.name ?? processor.id,
1852
+ input: { phase, messageCount: messages?.length },
1853
+ attributes: {
1854
+ processorExecutor: "workflow",
1855
+ // Read processorIndex from processor (set in combineProcessorsIntoWorkflow)
1856
+ processorIndex: processor.processorIndex
1857
+ }
1858
+ }) : void 0;
1859
+ const processorTracingContext = processorSpan ? { currentSpan: processorSpan } : tracingContext;
1860
+ const baseContext = {
1861
+ abort,
1862
+ retryCount: retryCount ?? 0,
1863
+ requestContext,
1864
+ tracingContext: processorTracingContext
1865
+ };
1866
+ const passThrough = {
1867
+ phase,
1868
+ // Auto-create MessageList from messages if not provided
1869
+ // This enables running processor workflows from the UI where messageList can't be serialized
1870
+ messageList: messageList ?? (Array.isArray(messages) ? new MessageList().add(messages, "input").addSystem(systemMessages ?? []) : void 0),
1871
+ stepNumber,
1872
+ systemMessages,
1873
+ streamParts,
1874
+ state,
1875
+ finishReason,
1876
+ toolCalls,
1877
+ text,
1878
+ retryCount,
1879
+ // inputStep phase fields for model/tools configuration
1880
+ model,
1881
+ tools,
1882
+ toolChoice,
1883
+ activeTools,
1884
+ providerOptions,
1885
+ modelSettings,
1886
+ structuredOutput,
1887
+ steps
1888
+ };
1889
+ const executePhaseWithSpan = async (fn) => {
1890
+ try {
1891
+ const result = await fn();
1892
+ processorSpan?.end({ output: result });
1893
+ return result;
1894
+ } catch (error) {
1895
+ if (error instanceof TripWire) {
1896
+ processorSpan?.end({ output: { tripwire: error.message } });
1897
+ } else {
1898
+ processorSpan?.error({ error, endSpan: true });
1899
+ }
1900
+ throw error;
1901
+ }
1902
+ };
1903
+ return executePhaseWithSpan(async () => {
1904
+ switch (phase) {
1905
+ case "input": {
1906
+ if (processor.processInput) {
1907
+ if (!passThrough.messageList) {
1908
+ throw new MastraError({
1909
+ category: ErrorCategory.USER,
1910
+ domain: ErrorDomain.MASTRA_WORKFLOW,
1911
+ id: "PROCESSOR_MISSING_MESSAGE_LIST",
1912
+ text: `Processor ${processor.id} requires messageList or messages for processInput phase`
1913
+ });
1914
+ }
1915
+ const idsBeforeProcessing = messages.map((m) => m.id);
1916
+ const check = passThrough.messageList.makeMessageSourceChecker();
1917
+ const result = await processor.processInput({
1918
+ ...baseContext,
1919
+ messages,
1920
+ messageList: passThrough.messageList,
1921
+ systemMessages: systemMessages ?? []
1922
+ });
1923
+ if (result instanceof MessageList) {
1924
+ if (result !== passThrough.messageList) {
1925
+ throw new MastraError({
1926
+ category: ErrorCategory.USER,
1927
+ domain: ErrorDomain.MASTRA_WORKFLOW,
1928
+ id: "PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST",
1929
+ text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`
1930
+ });
1931
+ }
1932
+ return {
1933
+ ...passThrough,
1934
+ messages: result.get.all.db(),
1935
+ systemMessages: result.getAllSystemMessages()
1936
+ };
1937
+ } else if (Array.isArray(result)) {
1938
+ ProcessorRunner.applyMessagesToMessageList(
1939
+ result,
1940
+ passThrough.messageList,
1941
+ idsBeforeProcessing,
1942
+ check,
1943
+ "input"
1944
+ );
1945
+ return { ...passThrough, messages: result };
1946
+ } else if (result && "messages" in result && "systemMessages" in result) {
1947
+ const typedResult = result;
1948
+ ProcessorRunner.applyMessagesToMessageList(
1949
+ typedResult.messages,
1950
+ passThrough.messageList,
1951
+ idsBeforeProcessing,
1952
+ check,
1953
+ "input"
1954
+ );
1955
+ passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);
1956
+ return {
1957
+ ...passThrough,
1958
+ messages: typedResult.messages,
1959
+ systemMessages: typedResult.systemMessages
1960
+ };
1961
+ }
1962
+ return { ...passThrough, messages };
1963
+ }
1964
+ return { ...passThrough, messages };
1965
+ }
1966
+ case "inputStep": {
1967
+ if (processor.processInputStep) {
1968
+ if (!passThrough.messageList) {
1969
+ throw new MastraError({
1970
+ category: ErrorCategory.USER,
1971
+ domain: ErrorDomain.MASTRA_WORKFLOW,
1972
+ id: "PROCESSOR_MISSING_MESSAGE_LIST",
1973
+ text: `Processor ${processor.id} requires messageList or messages for processInputStep phase`
1974
+ });
1975
+ }
1976
+ const idsBeforeProcessing = messages.map((m) => m.id);
1977
+ const check = passThrough.messageList.makeMessageSourceChecker();
1978
+ const result = await processor.processInputStep({
1979
+ ...baseContext,
1980
+ messages,
1981
+ messageList: passThrough.messageList,
1982
+ stepNumber: stepNumber ?? 0,
1983
+ systemMessages: systemMessages ?? [],
1984
+ // Pass model/tools configuration fields - types match ProcessInputStepArgs
1985
+ model,
1986
+ tools,
1987
+ toolChoice,
1988
+ activeTools,
1989
+ providerOptions,
1990
+ modelSettings,
1991
+ structuredOutput,
1992
+ steps: steps ?? []
1993
+ });
1994
+ const validatedResult = await ProcessorRunner.validateAndFormatProcessInputStepResult(result, {
1995
+ messageList: passThrough.messageList,
1996
+ processor,
1997
+ stepNumber: stepNumber ?? 0
1998
+ });
1999
+ if (validatedResult.messages) {
2000
+ ProcessorRunner.applyMessagesToMessageList(
2001
+ validatedResult.messages,
2002
+ passThrough.messageList,
2003
+ idsBeforeProcessing,
2004
+ check
2005
+ );
2006
+ }
2007
+ if (validatedResult.systemMessages) {
2008
+ passThrough.messageList.replaceAllSystemMessages(validatedResult.systemMessages);
2009
+ }
2010
+ return { ...passThrough, messages, ...validatedResult };
2011
+ }
2012
+ return { ...passThrough, messages };
2013
+ }
2014
+ case "outputStream": {
2015
+ if (processor.processOutputStream) {
2016
+ const spanKey = `__outputStreamSpan_${processor.id}`;
2017
+ const mutableState = state ?? {};
2018
+ let processorSpan2 = mutableState[spanKey];
2019
+ if (!processorSpan2 && parentSpan) {
2020
+ processorSpan2 = parentSpan.createChildSpan({
2021
+ type: SpanType.PROCESSOR_RUN,
2022
+ name: `output stream processor: ${processor.id}`,
2023
+ entityType: EntityType.OUTPUT_PROCESSOR,
2024
+ entityId: processor.id,
2025
+ entityName: processor.name ?? processor.id,
2026
+ input: { phase, streamParts: [] },
2027
+ attributes: {
2028
+ processorExecutor: "workflow",
2029
+ processorIndex: processor.processorIndex
2030
+ }
2031
+ });
2032
+ mutableState[spanKey] = processorSpan2;
2033
+ }
2034
+ if (processorSpan2) {
2035
+ processorSpan2.input = {
2036
+ phase,
2037
+ streamParts: streamParts ?? [],
2038
+ totalChunks: (streamParts ?? []).length
2039
+ };
2040
+ }
2041
+ const processorTracingContext2 = processorSpan2 ? { currentSpan: processorSpan2 } : baseContext.tracingContext;
2042
+ let result;
2043
+ try {
2044
+ result = await processor.processOutputStream({
2045
+ ...baseContext,
2046
+ tracingContext: processorTracingContext2,
2047
+ part,
2048
+ streamParts: streamParts ?? [],
2049
+ state: mutableState,
2050
+ messageList: passThrough.messageList
2051
+ // Optional for stream processing
2052
+ });
2053
+ if (part && part.type === "finish") {
2054
+ processorSpan2?.end({ output: result });
2055
+ delete mutableState[spanKey];
2056
+ }
2057
+ } catch (error) {
2058
+ if (error instanceof TripWire) {
2059
+ processorSpan2?.end({ output: { tripwire: error.message } });
2060
+ } else {
2061
+ processorSpan2?.error({ error, endSpan: true });
2062
+ }
2063
+ delete mutableState[spanKey];
2064
+ throw error;
2065
+ }
2066
+ return { ...passThrough, state: mutableState, part: result };
2067
+ }
2068
+ return { ...passThrough, part };
2069
+ }
2070
+ case "outputResult": {
2071
+ if (processor.processOutputResult) {
2072
+ if (!passThrough.messageList) {
2073
+ throw new MastraError({
2074
+ category: ErrorCategory.USER,
2075
+ domain: ErrorDomain.MASTRA_WORKFLOW,
2076
+ id: "PROCESSOR_MISSING_MESSAGE_LIST",
2077
+ text: `Processor ${processor.id} requires messageList or messages for processOutputResult phase`
2078
+ });
2079
+ }
2080
+ const idsBeforeProcessing = messages.map((m) => m.id);
2081
+ const check = passThrough.messageList.makeMessageSourceChecker();
2082
+ const result = await processor.processOutputResult({
2083
+ ...baseContext,
2084
+ messages,
2085
+ messageList: passThrough.messageList
2086
+ });
2087
+ if (result instanceof MessageList) {
2088
+ if (result !== passThrough.messageList) {
2089
+ throw new MastraError({
2090
+ category: ErrorCategory.USER,
2091
+ domain: ErrorDomain.MASTRA_WORKFLOW,
2092
+ id: "PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST",
2093
+ text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`
2094
+ });
2095
+ }
2096
+ return {
2097
+ ...passThrough,
2098
+ messages: result.get.all.db(),
2099
+ systemMessages: result.getAllSystemMessages()
2100
+ };
2101
+ } else if (Array.isArray(result)) {
2102
+ ProcessorRunner.applyMessagesToMessageList(
2103
+ result,
2104
+ passThrough.messageList,
2105
+ idsBeforeProcessing,
2106
+ check,
2107
+ "response"
2108
+ );
2109
+ return { ...passThrough, messages: result };
2110
+ } else if (result && "messages" in result && "systemMessages" in result) {
2111
+ const typedResult = result;
2112
+ ProcessorRunner.applyMessagesToMessageList(
2113
+ typedResult.messages,
2114
+ passThrough.messageList,
2115
+ idsBeforeProcessing,
2116
+ check,
2117
+ "response"
2118
+ );
2119
+ passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);
2120
+ return {
2121
+ ...passThrough,
2122
+ messages: typedResult.messages,
2123
+ systemMessages: typedResult.systemMessages
2124
+ };
2125
+ }
2126
+ return { ...passThrough, messages };
2127
+ }
2128
+ return { ...passThrough, messages };
2129
+ }
2130
+ case "outputStep": {
2131
+ if (processor.processOutputStep) {
2132
+ if (!passThrough.messageList) {
2133
+ throw new MastraError({
2134
+ category: ErrorCategory.USER,
2135
+ domain: ErrorDomain.MASTRA_WORKFLOW,
2136
+ id: "PROCESSOR_MISSING_MESSAGE_LIST",
2137
+ text: `Processor ${processor.id} requires messageList or messages for processOutputStep phase`
2138
+ });
2139
+ }
2140
+ const idsBeforeProcessing = messages.map((m) => m.id);
2141
+ const check = passThrough.messageList.makeMessageSourceChecker();
2142
+ const result = await processor.processOutputStep({
2143
+ ...baseContext,
2144
+ messages,
2145
+ messageList: passThrough.messageList,
2146
+ stepNumber: stepNumber ?? 0,
2147
+ finishReason,
2148
+ toolCalls,
2149
+ text,
2150
+ systemMessages: systemMessages ?? [],
2151
+ steps: steps ?? []
2152
+ });
2153
+ if (result instanceof MessageList) {
2154
+ if (result !== passThrough.messageList) {
2155
+ throw new MastraError({
2156
+ category: ErrorCategory.USER,
2157
+ domain: ErrorDomain.MASTRA_WORKFLOW,
2158
+ id: "PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST",
2159
+ text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`
2160
+ });
2161
+ }
2162
+ return {
2163
+ ...passThrough,
2164
+ messages: result.get.all.db(),
2165
+ systemMessages: result.getAllSystemMessages()
2166
+ };
2167
+ } else if (Array.isArray(result)) {
2168
+ ProcessorRunner.applyMessagesToMessageList(
2169
+ result,
2170
+ passThrough.messageList,
2171
+ idsBeforeProcessing,
2172
+ check,
2173
+ "response"
2174
+ );
2175
+ return { ...passThrough, messages: result };
2176
+ } else if (result && "messages" in result && "systemMessages" in result) {
2177
+ const typedResult = result;
2178
+ ProcessorRunner.applyMessagesToMessageList(
2179
+ typedResult.messages,
2180
+ passThrough.messageList,
2181
+ idsBeforeProcessing,
2182
+ check,
2183
+ "response"
2184
+ );
2185
+ passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);
2186
+ return {
2187
+ ...passThrough,
2188
+ messages: typedResult.messages,
2189
+ systemMessages: typedResult.systemMessages
2190
+ };
2191
+ }
2192
+ return { ...passThrough, messages };
2193
+ }
2194
+ return { ...passThrough, messages };
2195
+ }
2196
+ default:
2197
+ return { ...passThrough, messages };
2198
+ }
2199
+ });
2200
+ },
2201
+ component: "PROCESSOR"
1439
2202
  };
1440
2203
  }
1441
2204
  function init(inngest) {
@@ -1478,6 +2241,6 @@ function init(inngest) {
1478
2241
  };
1479
2242
  }
1480
2243
 
1481
- export { InngestExecutionEngine, InngestPubSub, InngestRun, InngestWorkflow, _compatibilityCheck, createStep, init, serve };
2244
+ export { InngestExecutionEngine, InngestPubSub, InngestRun, InngestWorkflow, _compatibilityCheck, createServe, createStep, init, serve };
1482
2245
  //# sourceMappingURL=index.js.map
1483
2246
  //# sourceMappingURL=index.js.map