@mastra/inngest 0.0.0-fix-local-pkg-cwd-20251226155239 → 0.0.0-fix-agent-network-schema-20260119184437

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,5 +1,9 @@
1
1
  'use strict';
2
2
 
3
+ var agent = require('@mastra/core/agent');
4
+ var error = require('@mastra/core/error');
5
+ var observability = require('@mastra/core/observability');
6
+ var processors = require('@mastra/core/processors');
3
7
  var tools = require('@mastra/core/tools');
4
8
  var workflows = require('@mastra/core/workflows');
5
9
  var _constants = require('@mastra/core/workflows/_constants');
@@ -7,7 +11,6 @@ var zod = require('zod');
7
11
  var crypto$1 = require('crypto');
8
12
  var di = require('@mastra/core/di');
9
13
  var inngest = require('inngest');
10
- var error = require('@mastra/core/error');
11
14
  var realtime = require('@inngest/realtime');
12
15
  var events = require('@mastra/core/events');
13
16
  var web = require('stream/web');
@@ -60,38 +63,46 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
60
63
  * After retries exhausted, error propagates here and we return a failed result.
61
64
  */
62
65
  async executeStepWithRetry(stepId, runStep, params) {
63
- try {
64
- const result = await this.wrapDurableOperation(stepId, runStep, { delay: params.delay });
65
- return { ok: true, result };
66
- } catch (e) {
67
- const cause = e?.cause;
68
- if (cause?.status === "failed") {
69
- params.stepSpan?.error({
70
- error: e,
71
- attributes: { status: "failed" }
72
- });
73
- if (cause.error && !(cause.error instanceof Error)) {
74
- cause.error = error.getErrorFromUnknown(cause.error, { serializeStack: false });
75
- }
76
- return { ok: false, error: cause };
66
+ for (let i = 0; i < params.retries + 1; i++) {
67
+ if (i > 0 && params.delay) {
68
+ await new Promise((resolve) => setTimeout(resolve, params.delay));
77
69
  }
78
- const errorInstance = error.getErrorFromUnknown(e, {
79
- serializeStack: false,
80
- fallbackMessage: "Unknown step execution error"
81
- });
82
- params.stepSpan?.error({
83
- error: errorInstance,
84
- attributes: { status: "failed" }
85
- });
86
- return {
87
- ok: false,
88
- error: {
89
- status: "failed",
90
- error: errorInstance,
91
- endedAt: Date.now()
70
+ try {
71
+ const result = await this.wrapDurableOperation(stepId, runStep);
72
+ return { ok: true, result };
73
+ } catch (e) {
74
+ if (i === params.retries) {
75
+ const cause = e?.cause;
76
+ if (cause?.status === "failed") {
77
+ params.stepSpan?.error({
78
+ error: e,
79
+ attributes: { status: "failed" }
80
+ });
81
+ if (cause.error && !(cause.error instanceof Error)) {
82
+ cause.error = error.getErrorFromUnknown(cause.error, { serializeStack: false });
83
+ }
84
+ return { ok: false, error: cause };
85
+ }
86
+ const errorInstance = error.getErrorFromUnknown(e, {
87
+ serializeStack: false,
88
+ fallbackMessage: "Unknown step execution error"
89
+ });
90
+ params.stepSpan?.error({
91
+ error: errorInstance,
92
+ attributes: { status: "failed" }
93
+ });
94
+ return {
95
+ ok: false,
96
+ error: {
97
+ status: "failed",
98
+ error: errorInstance,
99
+ endedAt: Date.now()
100
+ }
101
+ };
92
102
  }
93
- };
103
+ }
94
104
  }
105
+ return { ok: false, error: { status: "failed", error: new Error("Unknown error"), endedAt: Date.now() } };
95
106
  }
96
107
  /**
97
108
  * Use Inngest's sleep primitive for durability
@@ -107,28 +118,32 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
107
118
  }
108
119
  /**
109
120
  * Wrap durable operations in Inngest step.run() for durability.
110
- * If retryConfig is provided, throws RetryAfterError INSIDE step.run() to trigger
111
- * Inngest's step-level retry mechanism (not function-level retry).
121
+ *
122
+ * IMPORTANT: Errors are wrapped with a cause structure before throwing.
123
+ * This is necessary because Inngest's error serialization (serialize-error-cjs)
124
+ * only captures standard Error properties (message, name, stack, code, cause).
125
+ * Custom properties like statusCode, responseHeaders from AI SDK errors would
126
+ * be lost. By putting our serialized error (via getErrorFromUnknown with toJSON())
127
+ * in the cause property, we ensure custom properties survive serialization.
128
+ * The cause property is in serialize-error-cjs's allowlist, and when the cause
129
+ * object is finally JSON.stringify'd, our error's toJSON() is called.
112
130
  */
113
- async wrapDurableOperation(operationId, operationFn, retryConfig) {
131
+ async wrapDurableOperation(operationId, operationFn) {
114
132
  return this.inngestStep.run(operationId, async () => {
115
133
  try {
116
134
  return await operationFn();
117
135
  } catch (e) {
118
- if (retryConfig) {
119
- const errorInstance = error.getErrorFromUnknown(e, {
120
- serializeStack: false,
121
- fallbackMessage: "Unknown step execution error"
122
- });
123
- throw new inngest.RetryAfterError(errorInstance.message, retryConfig.delay, {
124
- cause: {
125
- status: "failed",
126
- error: errorInstance,
127
- endedAt: Date.now()
128
- }
129
- });
130
- }
131
- throw e;
136
+ const errorInstance = error.getErrorFromUnknown(e, {
137
+ serializeStack: false,
138
+ fallbackMessage: "Unknown step execution error"
139
+ });
140
+ throw new Error(errorInstance.message, {
141
+ cause: {
142
+ status: "failed",
143
+ error: errorInstance,
144
+ endedAt: Date.now()
145
+ }
146
+ });
132
147
  }
133
148
  });
134
149
  }
@@ -150,6 +165,96 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
150
165
  async invokeLifecycleCallbacksInternal(result) {
151
166
  return super.invokeLifecycleCallbacks(result);
152
167
  }
168
+ // =============================================================================
169
+ // Durable Span Lifecycle Hooks
170
+ // =============================================================================
171
+ /**
172
+ * Create a step span durably - on first execution, creates and exports span.
173
+ * On replay, returns cached span data without re-creating.
174
+ */
175
+ async createStepSpan(params) {
176
+ const { executionContext, operationId, options, parentSpan } = params;
177
+ const parentSpanId = parentSpan?.id ?? executionContext.tracingIds?.workflowSpanId;
178
+ const exportedSpan = await this.wrapDurableOperation(operationId, async () => {
179
+ const observability = this.mastra?.observability?.getSelectedInstance({});
180
+ if (!observability) return void 0;
181
+ const span = observability.startSpan({
182
+ ...options,
183
+ entityType: options.entityType,
184
+ traceId: executionContext.tracingIds?.traceId,
185
+ parentSpanId
186
+ });
187
+ return span?.exportSpan();
188
+ });
189
+ if (exportedSpan) {
190
+ const observability = this.mastra?.observability?.getSelectedInstance({});
191
+ return observability?.rebuildSpan(exportedSpan);
192
+ }
193
+ return void 0;
194
+ }
195
+ /**
196
+ * End a step span durably.
197
+ */
198
+ async endStepSpan(params) {
199
+ const { span, operationId, endOptions } = params;
200
+ if (!span) return;
201
+ await this.wrapDurableOperation(operationId, async () => {
202
+ span.end(endOptions);
203
+ });
204
+ }
205
+ /**
206
+ * Record error on step span durably.
207
+ */
208
+ async errorStepSpan(params) {
209
+ const { span, operationId, errorOptions } = params;
210
+ if (!span) return;
211
+ await this.wrapDurableOperation(operationId, async () => {
212
+ span.error(errorOptions);
213
+ });
214
+ }
215
+ /**
216
+ * Create a generic child span durably (for control-flow operations).
217
+ * On first execution, creates and exports span. On replay, returns cached span data.
218
+ */
219
+ async createChildSpan(params) {
220
+ const { executionContext, operationId, options, parentSpan } = params;
221
+ const parentSpanId = parentSpan?.id ?? executionContext.tracingIds?.workflowSpanId;
222
+ const exportedSpan = await this.wrapDurableOperation(operationId, async () => {
223
+ const observability = this.mastra?.observability?.getSelectedInstance({});
224
+ if (!observability) return void 0;
225
+ const span = observability.startSpan({
226
+ ...options,
227
+ traceId: executionContext.tracingIds?.traceId,
228
+ parentSpanId
229
+ });
230
+ return span?.exportSpan();
231
+ });
232
+ if (exportedSpan) {
233
+ const observability = this.mastra?.observability?.getSelectedInstance({});
234
+ return observability?.rebuildSpan(exportedSpan);
235
+ }
236
+ return void 0;
237
+ }
238
+ /**
239
+ * End a generic child span durably (for control-flow operations).
240
+ */
241
+ async endChildSpan(params) {
242
+ const { span, operationId, endOptions } = params;
243
+ if (!span) return;
244
+ await this.wrapDurableOperation(operationId, async () => {
245
+ span.end(endOptions);
246
+ });
247
+ }
248
+ /**
249
+ * Record error on a generic child span durably (for control-flow operations).
250
+ */
251
+ async errorChildSpan(params) {
252
+ const { span, operationId, errorOptions } = params;
253
+ if (!span) return;
254
+ await this.wrapDurableOperation(operationId, async () => {
255
+ span.error(errorOptions);
256
+ });
257
+ }
153
258
  /**
154
259
  * Execute nested InngestWorkflow using inngestStep.invoke() for durability.
155
260
  * This MUST be called directly (not inside step.run()) due to Inngest constraints.
@@ -168,8 +273,13 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
168
273
  inputData,
169
274
  pubsub,
170
275
  startedAt,
171
- perStep
276
+ perStep,
277
+ stepSpan
172
278
  } = params;
279
+ const nestedTracingContext = executionContext.tracingIds?.traceId ? {
280
+ traceId: executionContext.tracingIds.traceId,
281
+ parentSpanId: stepSpan?.id
282
+ } : void 0;
173
283
  const isResume = !!resume?.steps?.length;
174
284
  let result;
175
285
  let runId;
@@ -196,7 +306,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
196
306
  resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
197
307
  },
198
308
  outputOptions: { includeState: true },
199
- perStep
309
+ perStep,
310
+ tracingOptions: nestedTracingContext
200
311
  }
201
312
  });
202
313
  result = invokeResp.result;
@@ -224,7 +335,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
224
335
  initialState: executionContext.state ?? {},
225
336
  runId: executionContext.runId,
226
337
  outputOptions: { includeState: true },
227
- perStep
338
+ perStep,
339
+ tracingOptions: nestedTracingContext
228
340
  }
229
341
  });
230
342
  result = invokeResp.result;
@@ -237,7 +349,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
237
349
  inputData,
238
350
  initialState: executionContext.state ?? {},
239
351
  outputOptions: { includeState: true },
240
- perStep
352
+ perStep,
353
+ tracingOptions: nestedTracingContext
241
354
  }
242
355
  });
243
356
  result = invokeResp.result;
@@ -634,8 +747,8 @@ var InngestRun = class extends workflows.Run {
634
747
  });
635
748
  }
636
749
  }
637
- async start(params) {
638
- return this._start(params);
750
+ async start(args) {
751
+ return this._start(args);
639
752
  }
640
753
  /**
641
754
  * Starts the workflow execution without waiting for completion (fire-and-forget).
@@ -643,7 +756,7 @@ var InngestRun = class extends workflows.Run {
643
756
  * The workflow executes independently in Inngest.
644
757
  * Use this when you don't need to wait for the result or want to avoid polling failures.
645
758
  */
646
- async startAsync(params) {
759
+ async startAsync(args) {
647
760
  const workflowsStore = await this.#mastra.getStorage()?.getStore("workflows");
648
761
  await workflowsStore?.persistWorkflowSnapshot({
649
762
  workflowName: this.workflowId,
@@ -663,8 +776,8 @@ var InngestRun = class extends workflows.Run {
663
776
  timestamp: Date.now()
664
777
  }
665
778
  });
666
- const inputDataToUse = await this._validateInput(params.inputData);
667
- const initialStateToUse = await this._validateInitialState(params.initialState ?? {});
779
+ const inputDataToUse = await this._validateInput(args.inputData);
780
+ const initialStateToUse = await this._validateInitialState(args.initialState ?? {});
668
781
  const eventOutput = await this.inngest.send({
669
782
  name: `workflow.${this.workflowId}`,
670
783
  data: {
@@ -672,10 +785,10 @@ var InngestRun = class extends workflows.Run {
672
785
  initialState: initialStateToUse,
673
786
  runId: this.runId,
674
787
  resourceId: this.resourceId,
675
- outputOptions: params.outputOptions,
676
- tracingOptions: params.tracingOptions,
677
- requestContext: params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {},
678
- perStep: params.perStep
788
+ outputOptions: args.outputOptions,
789
+ tracingOptions: args.tracingOptions,
790
+ requestContext: args.requestContext ? Object.fromEntries(args.requestContext.entries()) : {},
791
+ perStep: args.perStep
679
792
  }
680
793
  });
681
794
  const eventId = eventOutput.ids[0];
@@ -1039,9 +1152,6 @@ var InngestRun = class extends workflows.Run {
1039
1152
  });
1040
1153
  return this.streamOutput;
1041
1154
  }
1042
- streamVNext(args = {}) {
1043
- return this.stream(args);
1044
- }
1045
1155
  timeTravelStream({
1046
1156
  inputData,
1047
1157
  resumeData,
@@ -1050,6 +1160,7 @@ var InngestRun = class extends workflows.Run {
1050
1160
  context,
1051
1161
  nestedStepsContext,
1052
1162
  requestContext,
1163
+ // tracingContext,
1053
1164
  tracingOptions,
1054
1165
  outputOptions,
1055
1166
  perStep
@@ -1132,9 +1243,11 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
1132
1243
  #mastra;
1133
1244
  inngest;
1134
1245
  function;
1246
+ cronFunction;
1135
1247
  flowControlConfig;
1248
+ cronConfig;
1136
1249
  constructor(params, inngest) {
1137
- const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
1250
+ const { concurrency, rateLimit, throttle, debounce, priority, cron, inputData, initialState, ...workflowParams } = params;
1138
1251
  super(workflowParams);
1139
1252
  this.engineType = "inngest";
1140
1253
  const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
@@ -1143,6 +1256,9 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
1143
1256
  this.flowControlConfig = flowControlEntries.length > 0 ? Object.fromEntries(flowControlEntries) : void 0;
1144
1257
  this.#mastra = params.mastra;
1145
1258
  this.inngest = inngest;
1259
+ if (cron) {
1260
+ this.cronConfig = { cron, inputData, initialState };
1261
+ }
1146
1262
  }
1147
1263
  async listWorkflowRuns(args) {
1148
1264
  const storage = this.#mastra?.getStorage();
@@ -1156,19 +1272,6 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
1156
1272
  }
1157
1273
  return workflowsStore.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
1158
1274
  }
1159
- async getWorkflowRunById(runId) {
1160
- const storage = this.#mastra?.getStorage();
1161
- if (!storage) {
1162
- this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
1163
- return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
1164
- }
1165
- const workflowsStore = await storage.getStore("workflows");
1166
- if (!workflowsStore) {
1167
- return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
1168
- }
1169
- const run = await workflowsStore.getWorkflowRunById({ runId, workflowName: this.id });
1170
- return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
1171
- }
1172
1275
  __registerMastra(mastra) {
1173
1276
  super.__registerMastra(mastra);
1174
1277
  this.#mastra = mastra;
@@ -1190,7 +1293,8 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
1190
1293
  }
1191
1294
  async createRun(options) {
1192
1295
  const runIdToUse = options?.runId || crypto$1.randomUUID();
1193
- const run = this.runs.get(runIdToUse) ?? new InngestRun(
1296
+ const existingInMemoryRun = this.runs.get(runIdToUse);
1297
+ const newRun = new InngestRun(
1194
1298
  {
1195
1299
  workflowId: this.id,
1196
1300
  runId: runIdToUse,
@@ -1207,15 +1311,17 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
1207
1311
  },
1208
1312
  this.inngest
1209
1313
  );
1314
+ const run = existingInMemoryRun ?? newRun;
1210
1315
  this.runs.set(runIdToUse, run);
1211
1316
  const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
1212
1317
  workflowStatus: run.workflowRunStatus,
1213
1318
  stepResults: {}
1214
1319
  });
1215
- const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, {
1320
+ const existingStoredRun = await this.getWorkflowRunById(runIdToUse, {
1216
1321
  withNestedWorkflows: false
1217
1322
  });
1218
- if (!workflowSnapshotInStorage && shouldPersistSnapshot) {
1323
+ const existsInStorage = existingStoredRun && !existingStoredRun.isFromInMemory;
1324
+ if (!existsInStorage && shouldPersistSnapshot) {
1219
1325
  const workflowsStore = await this.mastra?.getStorage()?.getStore("workflows");
1220
1326
  await workflowsStore?.persistWorkflowSnapshot({
1221
1327
  workflowName: this.id,
@@ -1240,6 +1346,30 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
1240
1346
  }
1241
1347
  return run;
1242
1348
  }
1349
+ //createCronFunction is only called if cronConfig.cron is defined.
1350
+ createCronFunction() {
1351
+ if (this.cronFunction) {
1352
+ return this.cronFunction;
1353
+ }
1354
+ this.cronFunction = this.inngest.createFunction(
1355
+ {
1356
+ id: `workflow.${this.id}.cron`,
1357
+ retries: 0,
1358
+ cancelOn: [{ event: `cancel.workflow.${this.id}` }],
1359
+ ...this.flowControlConfig
1360
+ },
1361
+ { cron: this.cronConfig?.cron ?? "" },
1362
+ async () => {
1363
+ const run = await this.createRun();
1364
+ const result = await run.start({
1365
+ inputData: this.cronConfig?.inputData,
1366
+ initialState: this.cronConfig?.initialState
1367
+ });
1368
+ return { result, runId: run.runId };
1369
+ }
1370
+ );
1371
+ return this.cronFunction;
1372
+ }
1243
1373
  getFunction() {
1244
1374
  if (this.function) {
1245
1375
  return this.function;
@@ -1247,54 +1377,127 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
1247
1377
  this.function = this.inngest.createFunction(
1248
1378
  {
1249
1379
  id: `workflow.${this.id}`,
1250
- retries: Math.min(this.retryConfig?.attempts ?? 0, 20),
1380
+ retries: 0,
1251
1381
  cancelOn: [{ event: `cancel.workflow.${this.id}` }],
1252
1382
  // Spread flow control configuration
1253
1383
  ...this.flowControlConfig
1254
1384
  },
1255
1385
  { event: `workflow.${this.id}` },
1256
1386
  async ({ event, step, attempt, publish }) => {
1257
- let { inputData, initialState, runId, resourceId, resume, outputOptions, format, timeTravel, perStep } = event.data;
1387
+ let {
1388
+ inputData,
1389
+ initialState,
1390
+ runId,
1391
+ resourceId,
1392
+ resume,
1393
+ outputOptions,
1394
+ format,
1395
+ timeTravel,
1396
+ perStep,
1397
+ tracingOptions
1398
+ } = event.data;
1258
1399
  if (!runId) {
1259
1400
  runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
1260
1401
  return crypto$1.randomUUID();
1261
1402
  });
1262
1403
  }
1263
1404
  const pubsub = new InngestPubSub(this.inngest, this.id, publish);
1405
+ const requestContext = new di.RequestContext(Object.entries(event.data.requestContext ?? {}));
1406
+ const mastra = this.#mastra;
1407
+ const tracingPolicy = this.options.tracingPolicy;
1408
+ const workflowSpanData = await step.run(`workflow.${this.id}.span.start`, async () => {
1409
+ const observability$1 = mastra?.observability?.getSelectedInstance({ requestContext });
1410
+ if (!observability$1) return void 0;
1411
+ const span = observability$1.startSpan({
1412
+ type: observability.SpanType.WORKFLOW_RUN,
1413
+ name: `workflow run: '${this.id}'`,
1414
+ entityType: observability.EntityType.WORKFLOW_RUN,
1415
+ entityId: this.id,
1416
+ input: inputData,
1417
+ metadata: {
1418
+ resourceId,
1419
+ runId
1420
+ },
1421
+ tracingPolicy,
1422
+ tracingOptions,
1423
+ requestContext
1424
+ });
1425
+ return span?.exportSpan();
1426
+ });
1264
1427
  const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
1265
- const result = await engine.execute({
1266
- workflowId: this.id,
1267
- runId,
1268
- resourceId,
1269
- graph: this.executionGraph,
1270
- serializedStepGraph: this.serializedStepGraph,
1271
- input: inputData,
1272
- initialState,
1273
- pubsub,
1274
- retryConfig: this.retryConfig,
1275
- requestContext: new di.RequestContext(Object.entries(event.data.requestContext ?? {})),
1276
- resume,
1277
- timeTravel,
1278
- perStep,
1279
- format,
1280
- abortController: new AbortController(),
1281
- // currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
1282
- outputOptions,
1283
- outputWriter: async (chunk) => {
1284
- try {
1285
- await pubsub.publish(`workflow.events.v2.${runId}`, {
1286
- type: "watch",
1287
- runId,
1288
- data: chunk
1289
- });
1290
- } catch (err) {
1291
- this.logger.debug?.("Failed to publish watch event:", err);
1428
+ let result;
1429
+ try {
1430
+ result = await engine.execute({
1431
+ workflowId: this.id,
1432
+ runId,
1433
+ resourceId,
1434
+ graph: this.executionGraph,
1435
+ serializedStepGraph: this.serializedStepGraph,
1436
+ input: inputData,
1437
+ initialState,
1438
+ pubsub,
1439
+ retryConfig: this.retryConfig,
1440
+ requestContext,
1441
+ resume,
1442
+ timeTravel,
1443
+ perStep,
1444
+ format,
1445
+ abortController: new AbortController(),
1446
+ // For Inngest, we don't pass workflowSpan - step spans use tracingIds instead
1447
+ workflowSpan: void 0,
1448
+ // Pass tracing IDs for durable span operations
1449
+ tracingIds: workflowSpanData ? {
1450
+ traceId: workflowSpanData.traceId,
1451
+ workflowSpanId: workflowSpanData.id
1452
+ } : void 0,
1453
+ outputOptions,
1454
+ outputWriter: async (chunk) => {
1455
+ try {
1456
+ await pubsub.publish(`workflow.events.v2.${runId}`, {
1457
+ type: "watch",
1458
+ runId,
1459
+ data: chunk
1460
+ });
1461
+ } catch (err) {
1462
+ this.logger.debug?.("Failed to publish watch event:", err);
1463
+ }
1292
1464
  }
1293
- }
1294
- });
1465
+ });
1466
+ } catch (error) {
1467
+ throw error;
1468
+ }
1295
1469
  await step.run(`workflow.${this.id}.finalize`, async () => {
1296
1470
  if (result.status !== "paused") {
1297
- await engine.invokeLifecycleCallbacksInternal(result);
1471
+ await engine.invokeLifecycleCallbacksInternal({
1472
+ status: result.status,
1473
+ result: "result" in result ? result.result : void 0,
1474
+ error: "error" in result ? result.error : void 0,
1475
+ steps: result.steps,
1476
+ tripwire: "tripwire" in result ? result.tripwire : void 0,
1477
+ runId,
1478
+ workflowId: this.id,
1479
+ resourceId,
1480
+ input: inputData,
1481
+ requestContext,
1482
+ state: result.state ?? initialState ?? {}
1483
+ });
1484
+ }
1485
+ if (workflowSpanData) {
1486
+ const observability = mastra?.observability?.getSelectedInstance({ requestContext });
1487
+ if (observability) {
1488
+ const workflowSpan = observability.rebuildSpan(workflowSpanData);
1489
+ if (result.status === "failed") {
1490
+ workflowSpan.error({
1491
+ error: result.error instanceof Error ? result.error : new Error(String(result.error)),
1492
+ attributes: { status: "failed" }
1493
+ });
1494
+ } else {
1495
+ workflowSpan.end({
1496
+ output: result.status === "success" ? result.result : void 0,
1497
+ attributes: { status: result.status }
1498
+ });
1499
+ }
1500
+ }
1298
1501
  }
1299
1502
  if (result.status === "failed") {
1300
1503
  throw new inngest.NonRetriableError(`Workflow failed`, {
@@ -1322,15 +1525,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
1322
1525
  });
1323
1526
  }
1324
1527
  getFunctions() {
1325
- return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
1528
+ return [
1529
+ this.getFunction(),
1530
+ ...this.cronConfig?.cron ? [this.createCronFunction()] : [],
1531
+ ...this.getNestedFunctions(this.executionGraph.steps)
1532
+ ];
1326
1533
  }
1327
1534
  };
1328
- function serve({
1329
- mastra,
1330
- inngest,
1331
- functions: userFunctions = [],
1332
- registerOptions
1333
- }) {
1535
+ function prepareServeOptions({ mastra, inngest, functions: userFunctions = [], registerOptions }) {
1334
1536
  const wfs = mastra.listWorkflows();
1335
1537
  const workflowFunctions = Array.from(
1336
1538
  new Set(
@@ -1343,177 +1545,181 @@ function serve({
1343
1545
  })
1344
1546
  )
1345
1547
  );
1346
- return hono.serve({
1548
+ return {
1347
1549
  ...registerOptions,
1348
1550
  client: inngest,
1349
1551
  functions: [...workflowFunctions, ...userFunctions]
1350
- });
1552
+ };
1553
+ }
1554
+ function createServe(adapter) {
1555
+ return (options) => {
1556
+ const serveOptions = prepareServeOptions(options);
1557
+ return adapter(serveOptions);
1558
+ };
1351
1559
  }
1560
+ var serve = createServe(hono.serve);
1352
1561
 
1353
1562
  // src/types.ts
1354
1563
  var _compatibilityCheck = true;
1355
1564
 
1356
1565
  // src/index.ts
1357
- function isAgent(params) {
1358
- return params?.component === "AGENT";
1566
+ function isInngestWorkflow(input) {
1567
+ return input instanceof InngestWorkflow;
1568
+ }
1569
+ function isAgent(input) {
1570
+ return input instanceof agent.Agent;
1359
1571
  }
1360
- function isTool(params) {
1361
- return params instanceof tools.Tool;
1572
+ function isToolStep(input) {
1573
+ return input instanceof tools.Tool;
1362
1574
  }
1363
- function isInngestWorkflow(params) {
1364
- return params instanceof InngestWorkflow;
1575
+ function isStepParams(input) {
1576
+ return input !== null && typeof input === "object" && "id" in input && "execute" in input && !(input instanceof agent.Agent) && !(input instanceof tools.Tool) && !(input instanceof InngestWorkflow);
1365
1577
  }
1366
- function createStep(params, agentOptions) {
1578
+ function isProcessor(obj) {
1579
+ return obj !== null && typeof obj === "object" && "id" in obj && typeof obj.id === "string" && !(obj instanceof agent.Agent) && !(obj instanceof tools.Tool) && !(obj instanceof InngestWorkflow) && (typeof obj.processInput === "function" || typeof obj.processInputStep === "function" || typeof obj.processOutputStream === "function" || typeof obj.processOutputResult === "function" || typeof obj.processOutputStep === "function");
1580
+ }
1581
+ function createStep(params, agentOrToolOptions) {
1367
1582
  if (isInngestWorkflow(params)) {
1368
1583
  return params;
1369
1584
  }
1370
1585
  if (isAgent(params)) {
1371
- const outputSchema = agentOptions?.structuredOutput?.schema ?? zod.z.object({ text: zod.z.string() });
1372
- return {
1373
- id: params.name,
1374
- description: params.getDescription(),
1375
- inputSchema: zod.z.object({
1376
- prompt: zod.z.string()
1377
- // resourceId: z.string().optional(),
1378
- // threadId: z.string().optional(),
1379
- }),
1380
- outputSchema,
1381
- execute: async ({
1382
- inputData,
1383
- runId,
1384
- [_constants.PUBSUB_SYMBOL]: pubsub,
1385
- [_constants.STREAM_FORMAT_SYMBOL]: streamFormat,
1386
- requestContext,
1387
- tracingContext,
1388
- abortSignal,
1389
- abort,
1390
- writer
1391
- }) => {
1392
- let streamPromise = {};
1393
- streamPromise.promise = new Promise((resolve, reject) => {
1394
- streamPromise.resolve = resolve;
1395
- streamPromise.reject = reject;
1586
+ return createStepFromAgent(params, agentOrToolOptions);
1587
+ }
1588
+ if (isToolStep(params)) {
1589
+ return createStepFromTool(params, agentOrToolOptions);
1590
+ }
1591
+ if (isStepParams(params)) {
1592
+ return createStepFromParams(params);
1593
+ }
1594
+ if (isProcessor(params)) {
1595
+ return createStepFromProcessor(params);
1596
+ }
1597
+ throw new Error("Invalid input: expected StepParams, Agent, ToolStep, Processor, or InngestWorkflow");
1598
+ }
1599
+ function createStepFromParams(params) {
1600
+ return {
1601
+ id: params.id,
1602
+ description: params.description,
1603
+ inputSchema: params.inputSchema,
1604
+ stateSchema: params.stateSchema,
1605
+ outputSchema: params.outputSchema,
1606
+ resumeSchema: params.resumeSchema,
1607
+ suspendSchema: params.suspendSchema,
1608
+ scorers: params.scorers,
1609
+ retries: params.retries,
1610
+ execute: params.execute.bind(params)
1611
+ };
1612
+ }
1613
+ function createStepFromAgent(params, agentOrToolOptions) {
1614
+ const options = agentOrToolOptions ?? {};
1615
+ const outputSchema = options?.structuredOutput?.schema ?? zod.z.object({ text: zod.z.string() });
1616
+ const { retries, scorers, ...agentOptions } = options ?? {};
1617
+ return {
1618
+ id: params.name,
1619
+ description: params.getDescription(),
1620
+ inputSchema: zod.z.object({
1621
+ prompt: zod.z.string()
1622
+ }),
1623
+ outputSchema,
1624
+ retries,
1625
+ scorers,
1626
+ execute: async ({
1627
+ inputData,
1628
+ runId,
1629
+ [_constants.PUBSUB_SYMBOL]: pubsub,
1630
+ [_constants.STREAM_FORMAT_SYMBOL]: streamFormat,
1631
+ requestContext,
1632
+ tracingContext,
1633
+ abortSignal,
1634
+ abort,
1635
+ writer
1636
+ }) => {
1637
+ let streamPromise = {};
1638
+ streamPromise.promise = new Promise((resolve, reject) => {
1639
+ streamPromise.resolve = resolve;
1640
+ streamPromise.reject = reject;
1641
+ });
1642
+ let structuredResult = null;
1643
+ const toolData = {
1644
+ name: params.name,
1645
+ args: inputData
1646
+ };
1647
+ let stream;
1648
+ if ((await params.getModel()).specificationVersion === "v1") {
1649
+ const { fullStream } = await params.streamLegacy(inputData.prompt, {
1650
+ ...agentOptions ?? {},
1651
+ requestContext,
1652
+ tracingContext,
1653
+ onFinish: (result) => {
1654
+ const resultWithObject = result;
1655
+ if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
1656
+ structuredResult = resultWithObject.object;
1657
+ }
1658
+ streamPromise.resolve(result.text);
1659
+ void agentOptions?.onFinish?.(result);
1660
+ },
1661
+ abortSignal
1396
1662
  });
1397
- let structuredResult = null;
1398
- const toolData = {
1399
- name: params.name,
1400
- args: inputData
1401
- };
1402
- let stream;
1403
- if ((await params.getModel()).specificationVersion === "v1") {
1404
- const { fullStream } = await params.streamLegacy(inputData.prompt, {
1405
- ...agentOptions ?? {},
1406
- // resourceId: inputData.resourceId,
1407
- // threadId: inputData.threadId,
1408
- requestContext,
1409
- tracingContext,
1410
- onFinish: (result) => {
1411
- const resultWithObject = result;
1412
- if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
1413
- structuredResult = resultWithObject.object;
1414
- }
1415
- streamPromise.resolve(result.text);
1416
- void agentOptions?.onFinish?.(result);
1417
- },
1418
- abortSignal
1419
- });
1420
- stream = fullStream;
1421
- } else {
1422
- const modelOutput = await params.stream(inputData.prompt, {
1423
- ...agentOptions ?? {},
1424
- requestContext,
1425
- tracingContext,
1426
- onFinish: (result) => {
1427
- const resultWithObject = result;
1428
- if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
1429
- structuredResult = resultWithObject.object;
1430
- }
1431
- streamPromise.resolve(result.text);
1432
- void agentOptions?.onFinish?.(result);
1433
- },
1434
- abortSignal
1435
- });
1436
- stream = modelOutput.fullStream;
1437
- }
1438
- if (streamFormat === "legacy") {
1439
- await pubsub.publish(`workflow.events.v2.${runId}`, {
1440
- type: "watch",
1441
- runId,
1442
- data: { type: "tool-call-streaming-start", ...toolData ?? {} }
1443
- });
1444
- for await (const chunk of stream) {
1445
- if (chunk.type === "text-delta") {
1446
- await pubsub.publish(`workflow.events.v2.${runId}`, {
1447
- type: "watch",
1448
- runId,
1449
- data: { type: "tool-call-delta", ...toolData ?? {}, argsTextDelta: chunk.textDelta }
1450
- });
1663
+ stream = fullStream;
1664
+ } else {
1665
+ const modelOutput = await params.stream(inputData.prompt, {
1666
+ ...agentOptions ?? {},
1667
+ requestContext,
1668
+ tracingContext,
1669
+ onFinish: (result) => {
1670
+ const resultWithObject = result;
1671
+ if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
1672
+ structuredResult = resultWithObject.object;
1451
1673
  }
1452
- }
1453
- await pubsub.publish(`workflow.events.v2.${runId}`, {
1454
- type: "watch",
1455
- runId,
1456
- data: { type: "tool-call-streaming-finish", ...toolData ?? {} }
1457
- });
1458
- } else {
1459
- for await (const chunk of stream) {
1460
- await writer.write(chunk);
1674
+ streamPromise.resolve(result.text);
1675
+ void agentOptions?.onFinish?.(result);
1676
+ },
1677
+ abortSignal
1678
+ });
1679
+ stream = modelOutput.fullStream;
1680
+ }
1681
+ if (streamFormat === "legacy") {
1682
+ await pubsub.publish(`workflow.events.v2.${runId}`, {
1683
+ type: "watch",
1684
+ runId,
1685
+ data: { type: "tool-call-streaming-start", ...toolData ?? {} }
1686
+ });
1687
+ for await (const chunk of stream) {
1688
+ if (chunk.type === "text-delta") {
1689
+ await pubsub.publish(`workflow.events.v2.${runId}`, {
1690
+ type: "watch",
1691
+ runId,
1692
+ data: { type: "tool-call-delta", ...toolData ?? {}, argsTextDelta: chunk.textDelta }
1693
+ });
1461
1694
  }
1462
1695
  }
1463
- if (abortSignal.aborted) {
1464
- return abort();
1465
- }
1466
- if (structuredResult !== null) {
1467
- return structuredResult;
1696
+ await pubsub.publish(`workflow.events.v2.${runId}`, {
1697
+ type: "watch",
1698
+ runId,
1699
+ data: { type: "tool-call-streaming-finish", ...toolData ?? {} }
1700
+ });
1701
+ } else {
1702
+ for await (const chunk of stream) {
1703
+ await writer.write(chunk);
1468
1704
  }
1469
- return {
1470
- text: await streamPromise.promise
1471
- };
1472
- },
1473
- component: params.component
1474
- };
1475
- }
1476
- if (isTool(params)) {
1477
- if (!params.inputSchema || !params.outputSchema) {
1478
- throw new Error("Tool must have input and output schemas defined");
1479
- }
1480
- return {
1481
- // TODO: tool probably should have strong id type
1482
- id: params.id,
1483
- description: params.description,
1484
- inputSchema: params.inputSchema,
1485
- outputSchema: params.outputSchema,
1486
- suspendSchema: params.suspendSchema,
1487
- resumeSchema: params.resumeSchema,
1488
- execute: async ({
1489
- inputData,
1490
- mastra,
1491
- requestContext,
1492
- tracingContext,
1493
- suspend,
1494
- resumeData,
1495
- runId,
1496
- workflowId,
1497
- state,
1498
- setState
1499
- }) => {
1500
- const toolContext = {
1501
- mastra,
1502
- requestContext,
1503
- tracingContext,
1504
- workflow: {
1505
- runId,
1506
- resumeData,
1507
- suspend,
1508
- workflowId,
1509
- state,
1510
- setState
1511
- }
1512
- };
1513
- return params.execute(inputData, toolContext);
1514
- },
1515
- component: "TOOL"
1516
- };
1705
+ }
1706
+ if (abortSignal.aborted) {
1707
+ return abort();
1708
+ }
1709
+ if (structuredResult !== null) {
1710
+ return structuredResult;
1711
+ }
1712
+ return {
1713
+ text: await streamPromise.promise
1714
+ };
1715
+ },
1716
+ component: params.component
1717
+ };
1718
+ }
1719
+ function createStepFromTool(params, agentOrToolOptions) {
1720
+ const toolOpts = agentOrToolOptions;
1721
+ if (!params.inputSchema || !params.outputSchema) {
1722
+ throw new Error("Tool must have input and output schemas defined");
1517
1723
  }
1518
1724
  return {
1519
1725
  id: params.id,
@@ -1522,7 +1728,480 @@ function createStep(params, agentOptions) {
1522
1728
  outputSchema: params.outputSchema,
1523
1729
  resumeSchema: params.resumeSchema,
1524
1730
  suspendSchema: params.suspendSchema,
1525
- execute: params.execute
1731
+ retries: toolOpts?.retries,
1732
+ scorers: toolOpts?.scorers,
1733
+ execute: async ({
1734
+ inputData,
1735
+ mastra,
1736
+ requestContext,
1737
+ tracingContext,
1738
+ suspend,
1739
+ resumeData,
1740
+ runId,
1741
+ workflowId,
1742
+ state,
1743
+ setState
1744
+ }) => {
1745
+ const toolContext = {
1746
+ mastra,
1747
+ requestContext,
1748
+ tracingContext,
1749
+ workflow: {
1750
+ runId,
1751
+ resumeData,
1752
+ suspend,
1753
+ workflowId,
1754
+ state,
1755
+ setState
1756
+ }
1757
+ };
1758
+ return params.execute(inputData, toolContext);
1759
+ },
1760
+ component: "TOOL"
1761
+ };
1762
+ }
1763
+ function createStepFromProcessor(processor) {
1764
+ const getProcessorEntityType = (phase) => {
1765
+ switch (phase) {
1766
+ case "input":
1767
+ return observability.EntityType.INPUT_PROCESSOR;
1768
+ case "inputStep":
1769
+ return observability.EntityType.INPUT_STEP_PROCESSOR;
1770
+ case "outputStream":
1771
+ case "outputResult":
1772
+ return observability.EntityType.OUTPUT_PROCESSOR;
1773
+ case "outputStep":
1774
+ return observability.EntityType.OUTPUT_STEP_PROCESSOR;
1775
+ default:
1776
+ return observability.EntityType.OUTPUT_PROCESSOR;
1777
+ }
1778
+ };
1779
+ const getSpanNamePrefix = (phase) => {
1780
+ switch (phase) {
1781
+ case "input":
1782
+ return "input processor";
1783
+ case "inputStep":
1784
+ return "input step processor";
1785
+ case "outputStream":
1786
+ return "output stream processor";
1787
+ case "outputResult":
1788
+ return "output processor";
1789
+ case "outputStep":
1790
+ return "output step processor";
1791
+ default:
1792
+ return "processor";
1793
+ }
1794
+ };
1795
+ const hasPhaseMethod = (phase) => {
1796
+ switch (phase) {
1797
+ case "input":
1798
+ return !!processor.processInput;
1799
+ case "inputStep":
1800
+ return !!processor.processInputStep;
1801
+ case "outputStream":
1802
+ return !!processor.processOutputStream;
1803
+ case "outputResult":
1804
+ return !!processor.processOutputResult;
1805
+ case "outputStep":
1806
+ return !!processor.processOutputStep;
1807
+ default:
1808
+ return false;
1809
+ }
1810
+ };
1811
+ return {
1812
+ id: `processor:${processor.id}`,
1813
+ description: processor.name ?? `Processor ${processor.id}`,
1814
+ inputSchema: processors.ProcessorStepSchema,
1815
+ outputSchema: processors.ProcessorStepOutputSchema,
1816
+ execute: async ({ inputData, requestContext, tracingContext }) => {
1817
+ const input = inputData;
1818
+ const {
1819
+ phase,
1820
+ messages,
1821
+ messageList,
1822
+ stepNumber,
1823
+ systemMessages,
1824
+ part,
1825
+ streamParts,
1826
+ state,
1827
+ finishReason,
1828
+ toolCalls,
1829
+ text,
1830
+ retryCount,
1831
+ // inputStep phase fields for model/tools configuration
1832
+ model,
1833
+ tools,
1834
+ toolChoice,
1835
+ activeTools,
1836
+ providerOptions,
1837
+ modelSettings,
1838
+ structuredOutput,
1839
+ steps
1840
+ } = input;
1841
+ const abort = (reason, options) => {
1842
+ throw new agent.TripWire(reason || `Tripwire triggered by ${processor.id}`, options, processor.id);
1843
+ };
1844
+ if (!hasPhaseMethod(phase)) {
1845
+ return input;
1846
+ }
1847
+ const currentSpan = tracingContext?.currentSpan;
1848
+ const parentSpan = phase === "inputStep" || phase === "outputStep" ? currentSpan?.findParent(observability.SpanType.MODEL_STEP) || currentSpan : currentSpan?.findParent(observability.SpanType.AGENT_RUN) || currentSpan;
1849
+ const processorSpan = phase !== "outputStream" ? parentSpan?.createChildSpan({
1850
+ type: observability.SpanType.PROCESSOR_RUN,
1851
+ name: `${getSpanNamePrefix(phase)}: ${processor.id}`,
1852
+ entityType: getProcessorEntityType(phase),
1853
+ entityId: processor.id,
1854
+ entityName: processor.name ?? processor.id,
1855
+ input: { phase, messageCount: messages?.length },
1856
+ attributes: {
1857
+ processorExecutor: "workflow",
1858
+ // Read processorIndex from processor (set in combineProcessorsIntoWorkflow)
1859
+ processorIndex: processor.processorIndex
1860
+ }
1861
+ }) : void 0;
1862
+ const processorTracingContext = processorSpan ? { currentSpan: processorSpan } : tracingContext;
1863
+ const baseContext = {
1864
+ abort,
1865
+ retryCount: retryCount ?? 0,
1866
+ requestContext,
1867
+ tracingContext: processorTracingContext
1868
+ };
1869
+ const passThrough = {
1870
+ phase,
1871
+ // Auto-create MessageList from messages if not provided
1872
+ // This enables running processor workflows from the UI where messageList can't be serialized
1873
+ messageList: messageList ?? (Array.isArray(messages) ? new agent.MessageList().add(messages, "input").addSystem(systemMessages ?? []) : void 0),
1874
+ stepNumber,
1875
+ systemMessages,
1876
+ streamParts,
1877
+ state,
1878
+ finishReason,
1879
+ toolCalls,
1880
+ text,
1881
+ retryCount,
1882
+ // inputStep phase fields for model/tools configuration
1883
+ model,
1884
+ tools,
1885
+ toolChoice,
1886
+ activeTools,
1887
+ providerOptions,
1888
+ modelSettings,
1889
+ structuredOutput,
1890
+ steps
1891
+ };
1892
+ const executePhaseWithSpan = async (fn) => {
1893
+ try {
1894
+ const result = await fn();
1895
+ processorSpan?.end({ output: result });
1896
+ return result;
1897
+ } catch (error) {
1898
+ if (error instanceof agent.TripWire) {
1899
+ processorSpan?.end({ output: { tripwire: error.message } });
1900
+ } else {
1901
+ processorSpan?.error({ error, endSpan: true });
1902
+ }
1903
+ throw error;
1904
+ }
1905
+ };
1906
+ return executePhaseWithSpan(async () => {
1907
+ switch (phase) {
1908
+ case "input": {
1909
+ if (processor.processInput) {
1910
+ if (!passThrough.messageList) {
1911
+ throw new error.MastraError({
1912
+ category: error.ErrorCategory.USER,
1913
+ domain: error.ErrorDomain.MASTRA_WORKFLOW,
1914
+ id: "PROCESSOR_MISSING_MESSAGE_LIST",
1915
+ text: `Processor ${processor.id} requires messageList or messages for processInput phase`
1916
+ });
1917
+ }
1918
+ const idsBeforeProcessing = messages.map((m) => m.id);
1919
+ const check = passThrough.messageList.makeMessageSourceChecker();
1920
+ const result = await processor.processInput({
1921
+ ...baseContext,
1922
+ messages,
1923
+ messageList: passThrough.messageList,
1924
+ systemMessages: systemMessages ?? []
1925
+ });
1926
+ if (result instanceof agent.MessageList) {
1927
+ if (result !== passThrough.messageList) {
1928
+ throw new error.MastraError({
1929
+ category: error.ErrorCategory.USER,
1930
+ domain: error.ErrorDomain.MASTRA_WORKFLOW,
1931
+ id: "PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST",
1932
+ text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`
1933
+ });
1934
+ }
1935
+ return {
1936
+ ...passThrough,
1937
+ messages: result.get.all.db(),
1938
+ systemMessages: result.getAllSystemMessages()
1939
+ };
1940
+ } else if (Array.isArray(result)) {
1941
+ processors.ProcessorRunner.applyMessagesToMessageList(
1942
+ result,
1943
+ passThrough.messageList,
1944
+ idsBeforeProcessing,
1945
+ check,
1946
+ "input"
1947
+ );
1948
+ return { ...passThrough, messages: result };
1949
+ } else if (result && "messages" in result && "systemMessages" in result) {
1950
+ const typedResult = result;
1951
+ processors.ProcessorRunner.applyMessagesToMessageList(
1952
+ typedResult.messages,
1953
+ passThrough.messageList,
1954
+ idsBeforeProcessing,
1955
+ check,
1956
+ "input"
1957
+ );
1958
+ passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);
1959
+ return {
1960
+ ...passThrough,
1961
+ messages: typedResult.messages,
1962
+ systemMessages: typedResult.systemMessages
1963
+ };
1964
+ }
1965
+ return { ...passThrough, messages };
1966
+ }
1967
+ return { ...passThrough, messages };
1968
+ }
1969
+ case "inputStep": {
1970
+ if (processor.processInputStep) {
1971
+ if (!passThrough.messageList) {
1972
+ throw new error.MastraError({
1973
+ category: error.ErrorCategory.USER,
1974
+ domain: error.ErrorDomain.MASTRA_WORKFLOW,
1975
+ id: "PROCESSOR_MISSING_MESSAGE_LIST",
1976
+ text: `Processor ${processor.id} requires messageList or messages for processInputStep phase`
1977
+ });
1978
+ }
1979
+ const idsBeforeProcessing = messages.map((m) => m.id);
1980
+ const check = passThrough.messageList.makeMessageSourceChecker();
1981
+ const result = await processor.processInputStep({
1982
+ ...baseContext,
1983
+ messages,
1984
+ messageList: passThrough.messageList,
1985
+ stepNumber: stepNumber ?? 0,
1986
+ systemMessages: systemMessages ?? [],
1987
+ // Pass model/tools configuration fields - types match ProcessInputStepArgs
1988
+ model,
1989
+ tools,
1990
+ toolChoice,
1991
+ activeTools,
1992
+ providerOptions,
1993
+ modelSettings,
1994
+ structuredOutput,
1995
+ steps: steps ?? []
1996
+ });
1997
+ const validatedResult = await processors.ProcessorRunner.validateAndFormatProcessInputStepResult(result, {
1998
+ messageList: passThrough.messageList,
1999
+ processor,
2000
+ stepNumber: stepNumber ?? 0
2001
+ });
2002
+ if (validatedResult.messages) {
2003
+ processors.ProcessorRunner.applyMessagesToMessageList(
2004
+ validatedResult.messages,
2005
+ passThrough.messageList,
2006
+ idsBeforeProcessing,
2007
+ check
2008
+ );
2009
+ }
2010
+ if (validatedResult.systemMessages) {
2011
+ passThrough.messageList.replaceAllSystemMessages(validatedResult.systemMessages);
2012
+ }
2013
+ return { ...passThrough, messages, ...validatedResult };
2014
+ }
2015
+ return { ...passThrough, messages };
2016
+ }
2017
+ case "outputStream": {
2018
+ if (processor.processOutputStream) {
2019
+ const spanKey = `__outputStreamSpan_${processor.id}`;
2020
+ const mutableState = state ?? {};
2021
+ let processorSpan2 = mutableState[spanKey];
2022
+ if (!processorSpan2 && parentSpan) {
2023
+ processorSpan2 = parentSpan.createChildSpan({
2024
+ type: observability.SpanType.PROCESSOR_RUN,
2025
+ name: `output stream processor: ${processor.id}`,
2026
+ entityType: observability.EntityType.OUTPUT_PROCESSOR,
2027
+ entityId: processor.id,
2028
+ entityName: processor.name ?? processor.id,
2029
+ input: { phase, streamParts: [] },
2030
+ attributes: {
2031
+ processorExecutor: "workflow",
2032
+ processorIndex: processor.processorIndex
2033
+ }
2034
+ });
2035
+ mutableState[spanKey] = processorSpan2;
2036
+ }
2037
+ if (processorSpan2) {
2038
+ processorSpan2.input = {
2039
+ phase,
2040
+ streamParts: streamParts ?? [],
2041
+ totalChunks: (streamParts ?? []).length
2042
+ };
2043
+ }
2044
+ const processorTracingContext2 = processorSpan2 ? { currentSpan: processorSpan2 } : baseContext.tracingContext;
2045
+ let result;
2046
+ try {
2047
+ result = await processor.processOutputStream({
2048
+ ...baseContext,
2049
+ tracingContext: processorTracingContext2,
2050
+ part,
2051
+ streamParts: streamParts ?? [],
2052
+ state: mutableState,
2053
+ messageList: passThrough.messageList
2054
+ // Optional for stream processing
2055
+ });
2056
+ if (part && part.type === "finish") {
2057
+ processorSpan2?.end({ output: result });
2058
+ delete mutableState[spanKey];
2059
+ }
2060
+ } catch (error) {
2061
+ if (error instanceof agent.TripWire) {
2062
+ processorSpan2?.end({ output: { tripwire: error.message } });
2063
+ } else {
2064
+ processorSpan2?.error({ error, endSpan: true });
2065
+ }
2066
+ delete mutableState[spanKey];
2067
+ throw error;
2068
+ }
2069
+ return { ...passThrough, state: mutableState, part: result };
2070
+ }
2071
+ return { ...passThrough, part };
2072
+ }
2073
+ case "outputResult": {
2074
+ if (processor.processOutputResult) {
2075
+ if (!passThrough.messageList) {
2076
+ throw new error.MastraError({
2077
+ category: error.ErrorCategory.USER,
2078
+ domain: error.ErrorDomain.MASTRA_WORKFLOW,
2079
+ id: "PROCESSOR_MISSING_MESSAGE_LIST",
2080
+ text: `Processor ${processor.id} requires messageList or messages for processOutputResult phase`
2081
+ });
2082
+ }
2083
+ const idsBeforeProcessing = messages.map((m) => m.id);
2084
+ const check = passThrough.messageList.makeMessageSourceChecker();
2085
+ const result = await processor.processOutputResult({
2086
+ ...baseContext,
2087
+ messages,
2088
+ messageList: passThrough.messageList
2089
+ });
2090
+ if (result instanceof agent.MessageList) {
2091
+ if (result !== passThrough.messageList) {
2092
+ throw new error.MastraError({
2093
+ category: error.ErrorCategory.USER,
2094
+ domain: error.ErrorDomain.MASTRA_WORKFLOW,
2095
+ id: "PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST",
2096
+ text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`
2097
+ });
2098
+ }
2099
+ return {
2100
+ ...passThrough,
2101
+ messages: result.get.all.db(),
2102
+ systemMessages: result.getAllSystemMessages()
2103
+ };
2104
+ } else if (Array.isArray(result)) {
2105
+ processors.ProcessorRunner.applyMessagesToMessageList(
2106
+ result,
2107
+ passThrough.messageList,
2108
+ idsBeforeProcessing,
2109
+ check,
2110
+ "response"
2111
+ );
2112
+ return { ...passThrough, messages: result };
2113
+ } else if (result && "messages" in result && "systemMessages" in result) {
2114
+ const typedResult = result;
2115
+ processors.ProcessorRunner.applyMessagesToMessageList(
2116
+ typedResult.messages,
2117
+ passThrough.messageList,
2118
+ idsBeforeProcessing,
2119
+ check,
2120
+ "response"
2121
+ );
2122
+ passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);
2123
+ return {
2124
+ ...passThrough,
2125
+ messages: typedResult.messages,
2126
+ systemMessages: typedResult.systemMessages
2127
+ };
2128
+ }
2129
+ return { ...passThrough, messages };
2130
+ }
2131
+ return { ...passThrough, messages };
2132
+ }
2133
+ case "outputStep": {
2134
+ if (processor.processOutputStep) {
2135
+ if (!passThrough.messageList) {
2136
+ throw new error.MastraError({
2137
+ category: error.ErrorCategory.USER,
2138
+ domain: error.ErrorDomain.MASTRA_WORKFLOW,
2139
+ id: "PROCESSOR_MISSING_MESSAGE_LIST",
2140
+ text: `Processor ${processor.id} requires messageList or messages for processOutputStep phase`
2141
+ });
2142
+ }
2143
+ const idsBeforeProcessing = messages.map((m) => m.id);
2144
+ const check = passThrough.messageList.makeMessageSourceChecker();
2145
+ const result = await processor.processOutputStep({
2146
+ ...baseContext,
2147
+ messages,
2148
+ messageList: passThrough.messageList,
2149
+ stepNumber: stepNumber ?? 0,
2150
+ finishReason,
2151
+ toolCalls,
2152
+ text,
2153
+ systemMessages: systemMessages ?? [],
2154
+ steps: steps ?? []
2155
+ });
2156
+ if (result instanceof agent.MessageList) {
2157
+ if (result !== passThrough.messageList) {
2158
+ throw new error.MastraError({
2159
+ category: error.ErrorCategory.USER,
2160
+ domain: error.ErrorDomain.MASTRA_WORKFLOW,
2161
+ id: "PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST",
2162
+ text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`
2163
+ });
2164
+ }
2165
+ return {
2166
+ ...passThrough,
2167
+ messages: result.get.all.db(),
2168
+ systemMessages: result.getAllSystemMessages()
2169
+ };
2170
+ } else if (Array.isArray(result)) {
2171
+ processors.ProcessorRunner.applyMessagesToMessageList(
2172
+ result,
2173
+ passThrough.messageList,
2174
+ idsBeforeProcessing,
2175
+ check,
2176
+ "response"
2177
+ );
2178
+ return { ...passThrough, messages: result };
2179
+ } else if (result && "messages" in result && "systemMessages" in result) {
2180
+ const typedResult = result;
2181
+ processors.ProcessorRunner.applyMessagesToMessageList(
2182
+ typedResult.messages,
2183
+ passThrough.messageList,
2184
+ idsBeforeProcessing,
2185
+ check,
2186
+ "response"
2187
+ );
2188
+ passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);
2189
+ return {
2190
+ ...passThrough,
2191
+ messages: typedResult.messages,
2192
+ systemMessages: typedResult.systemMessages
2193
+ };
2194
+ }
2195
+ return { ...passThrough, messages };
2196
+ }
2197
+ return { ...passThrough, messages };
2198
+ }
2199
+ default:
2200
+ return { ...passThrough, messages };
2201
+ }
2202
+ });
2203
+ },
2204
+ component: "PROCESSOR"
1526
2205
  };
1527
2206
  }
1528
2207
  function init(inngest) {
@@ -1570,6 +2249,7 @@ exports.InngestPubSub = InngestPubSub;
1570
2249
  exports.InngestRun = InngestRun;
1571
2250
  exports.InngestWorkflow = InngestWorkflow;
1572
2251
  exports._compatibilityCheck = _compatibilityCheck;
2252
+ exports.createServe = createServe;
1573
2253
  exports.createStep = createStep;
1574
2254
  exports.init = init;
1575
2255
  exports.serve = serve;