@mastra/inngest 1.0.0-beta.12 → 1.0.0-beta.13
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/CHANGELOG.md +94 -0
- package/dist/execution-engine.d.ts +87 -2
- package/dist/execution-engine.d.ts.map +1 -1
- package/dist/index.cjs +853 -203
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +63 -28
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +854 -204
- package/dist/index.js.map +1 -1
- package/dist/run.d.ts +48 -37
- package/dist/run.d.ts.map +1 -1
- package/dist/types.d.ts +4 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/workflow.d.ts +1 -2
- package/dist/workflow.d.ts.map +1 -1
- package/package.json +5 -4
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
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');
|
|
4
7
|
var tools = require('@mastra/core/tools');
|
|
5
8
|
var workflows = require('@mastra/core/workflows');
|
|
6
9
|
var _constants = require('@mastra/core/workflows/_constants');
|
|
@@ -8,7 +11,6 @@ var zod = require('zod');
|
|
|
8
11
|
var crypto$1 = require('crypto');
|
|
9
12
|
var di = require('@mastra/core/di');
|
|
10
13
|
var inngest = require('inngest');
|
|
11
|
-
var error = require('@mastra/core/error');
|
|
12
14
|
var realtime = require('@inngest/realtime');
|
|
13
15
|
var events = require('@mastra/core/events');
|
|
14
16
|
var web = require('stream/web');
|
|
@@ -116,15 +118,32 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
116
118
|
}
|
|
117
119
|
/**
|
|
118
120
|
* Wrap durable operations in Inngest step.run() for durability.
|
|
119
|
-
*
|
|
120
|
-
*
|
|
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.
|
|
121
130
|
*/
|
|
122
131
|
async wrapDurableOperation(operationId, operationFn) {
|
|
123
132
|
return this.inngestStep.run(operationId, async () => {
|
|
124
133
|
try {
|
|
125
134
|
return await operationFn();
|
|
126
135
|
} catch (e) {
|
|
127
|
-
|
|
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
|
+
});
|
|
128
147
|
}
|
|
129
148
|
});
|
|
130
149
|
}
|
|
@@ -146,6 +165,96 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
146
165
|
async invokeLifecycleCallbacksInternal(result) {
|
|
147
166
|
return super.invokeLifecycleCallbacks(result);
|
|
148
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
|
+
}
|
|
149
258
|
/**
|
|
150
259
|
* Execute nested InngestWorkflow using inngestStep.invoke() for durability.
|
|
151
260
|
* This MUST be called directly (not inside step.run()) due to Inngest constraints.
|
|
@@ -164,8 +273,13 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
164
273
|
inputData,
|
|
165
274
|
pubsub,
|
|
166
275
|
startedAt,
|
|
167
|
-
perStep
|
|
276
|
+
perStep,
|
|
277
|
+
stepSpan
|
|
168
278
|
} = params;
|
|
279
|
+
const nestedTracingContext = executionContext.tracingIds?.traceId ? {
|
|
280
|
+
traceId: executionContext.tracingIds.traceId,
|
|
281
|
+
parentSpanId: stepSpan?.id
|
|
282
|
+
} : void 0;
|
|
169
283
|
const isResume = !!resume?.steps?.length;
|
|
170
284
|
let result;
|
|
171
285
|
let runId;
|
|
@@ -192,7 +306,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
192
306
|
resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
|
|
193
307
|
},
|
|
194
308
|
outputOptions: { includeState: true },
|
|
195
|
-
perStep
|
|
309
|
+
perStep,
|
|
310
|
+
tracingOptions: nestedTracingContext
|
|
196
311
|
}
|
|
197
312
|
});
|
|
198
313
|
result = invokeResp.result;
|
|
@@ -220,7 +335,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
220
335
|
initialState: executionContext.state ?? {},
|
|
221
336
|
runId: executionContext.runId,
|
|
222
337
|
outputOptions: { includeState: true },
|
|
223
|
-
perStep
|
|
338
|
+
perStep,
|
|
339
|
+
tracingOptions: nestedTracingContext
|
|
224
340
|
}
|
|
225
341
|
});
|
|
226
342
|
result = invokeResp.result;
|
|
@@ -233,7 +349,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
233
349
|
inputData,
|
|
234
350
|
initialState: executionContext.state ?? {},
|
|
235
351
|
outputOptions: { includeState: true },
|
|
236
|
-
perStep
|
|
352
|
+
perStep,
|
|
353
|
+
tracingOptions: nestedTracingContext
|
|
237
354
|
}
|
|
238
355
|
});
|
|
239
356
|
result = invokeResp.result;
|
|
@@ -630,8 +747,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
630
747
|
});
|
|
631
748
|
}
|
|
632
749
|
}
|
|
633
|
-
async start(
|
|
634
|
-
return this._start(
|
|
750
|
+
async start(args) {
|
|
751
|
+
return this._start(args);
|
|
635
752
|
}
|
|
636
753
|
/**
|
|
637
754
|
* Starts the workflow execution without waiting for completion (fire-and-forget).
|
|
@@ -639,7 +756,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
639
756
|
* The workflow executes independently in Inngest.
|
|
640
757
|
* Use this when you don't need to wait for the result or want to avoid polling failures.
|
|
641
758
|
*/
|
|
642
|
-
async startAsync(
|
|
759
|
+
async startAsync(args) {
|
|
643
760
|
const workflowsStore = await this.#mastra.getStorage()?.getStore("workflows");
|
|
644
761
|
await workflowsStore?.persistWorkflowSnapshot({
|
|
645
762
|
workflowName: this.workflowId,
|
|
@@ -659,8 +776,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
659
776
|
timestamp: Date.now()
|
|
660
777
|
}
|
|
661
778
|
});
|
|
662
|
-
const inputDataToUse = await this._validateInput(
|
|
663
|
-
const initialStateToUse = await this._validateInitialState(
|
|
779
|
+
const inputDataToUse = await this._validateInput(args.inputData);
|
|
780
|
+
const initialStateToUse = await this._validateInitialState(args.initialState ?? {});
|
|
664
781
|
const eventOutput = await this.inngest.send({
|
|
665
782
|
name: `workflow.${this.workflowId}`,
|
|
666
783
|
data: {
|
|
@@ -668,10 +785,10 @@ var InngestRun = class extends workflows.Run {
|
|
|
668
785
|
initialState: initialStateToUse,
|
|
669
786
|
runId: this.runId,
|
|
670
787
|
resourceId: this.resourceId,
|
|
671
|
-
outputOptions:
|
|
672
|
-
tracingOptions:
|
|
673
|
-
requestContext:
|
|
674
|
-
perStep:
|
|
788
|
+
outputOptions: args.outputOptions,
|
|
789
|
+
tracingOptions: args.tracingOptions,
|
|
790
|
+
requestContext: args.requestContext ? Object.fromEntries(args.requestContext.entries()) : {},
|
|
791
|
+
perStep: args.perStep
|
|
675
792
|
}
|
|
676
793
|
});
|
|
677
794
|
const eventId = eventOutput.ids[0];
|
|
@@ -1043,6 +1160,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
1043
1160
|
context,
|
|
1044
1161
|
nestedStepsContext,
|
|
1045
1162
|
requestContext,
|
|
1163
|
+
// tracingContext,
|
|
1046
1164
|
tracingOptions,
|
|
1047
1165
|
outputOptions,
|
|
1048
1166
|
perStep
|
|
@@ -1175,7 +1293,8 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
1175
1293
|
}
|
|
1176
1294
|
async createRun(options) {
|
|
1177
1295
|
const runIdToUse = options?.runId || crypto$1.randomUUID();
|
|
1178
|
-
const
|
|
1296
|
+
const existingInMemoryRun = this.runs.get(runIdToUse);
|
|
1297
|
+
const newRun = new InngestRun(
|
|
1179
1298
|
{
|
|
1180
1299
|
workflowId: this.id,
|
|
1181
1300
|
runId: runIdToUse,
|
|
@@ -1192,15 +1311,16 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
1192
1311
|
},
|
|
1193
1312
|
this.inngest
|
|
1194
1313
|
);
|
|
1314
|
+
const run = existingInMemoryRun ?? newRun;
|
|
1195
1315
|
this.runs.set(runIdToUse, run);
|
|
1196
1316
|
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
|
|
1197
1317
|
workflowStatus: run.workflowRunStatus,
|
|
1198
1318
|
stepResults: {}
|
|
1199
1319
|
});
|
|
1200
|
-
const
|
|
1320
|
+
const existingStoredRun = await this.getWorkflowRunById(runIdToUse, {
|
|
1201
1321
|
withNestedWorkflows: false
|
|
1202
1322
|
});
|
|
1203
|
-
const existsInStorage =
|
|
1323
|
+
const existsInStorage = existingStoredRun && !existingStoredRun.isFromInMemory;
|
|
1204
1324
|
if (!existsInStorage && shouldPersistSnapshot) {
|
|
1205
1325
|
const workflowsStore = await this.mastra?.getStorage()?.getStore("workflows");
|
|
1206
1326
|
await workflowsStore?.persistWorkflowSnapshot({
|
|
@@ -1264,7 +1384,18 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
1264
1384
|
},
|
|
1265
1385
|
{ event: `workflow.${this.id}` },
|
|
1266
1386
|
async ({ event, step, attempt, publish }) => {
|
|
1267
|
-
let {
|
|
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;
|
|
1268
1399
|
if (!runId) {
|
|
1269
1400
|
runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
|
|
1270
1401
|
return crypto$1.randomUUID();
|
|
@@ -1272,37 +1403,69 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
1272
1403
|
}
|
|
1273
1404
|
const pubsub = new InngestPubSub(this.inngest, this.id, publish);
|
|
1274
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
|
+
});
|
|
1275
1427
|
const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
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
|
+
}
|
|
1303
1464
|
}
|
|
1304
|
-
}
|
|
1305
|
-
})
|
|
1465
|
+
});
|
|
1466
|
+
} catch (error) {
|
|
1467
|
+
throw error;
|
|
1468
|
+
}
|
|
1306
1469
|
await step.run(`workflow.${this.id}.finalize`, async () => {
|
|
1307
1470
|
if (result.status !== "paused") {
|
|
1308
1471
|
await engine.invokeLifecycleCallbacksInternal({
|
|
@@ -1319,6 +1482,23 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
1319
1482
|
state: result.state ?? initialState ?? {}
|
|
1320
1483
|
});
|
|
1321
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
|
+
}
|
|
1501
|
+
}
|
|
1322
1502
|
if (result.status === "failed") {
|
|
1323
1503
|
throw new inngest.NonRetriableError(`Workflow failed`, {
|
|
1324
1504
|
cause: result
|
|
@@ -1383,164 +1563,163 @@ var serve = createServe(hono.serve);
|
|
|
1383
1563
|
var _compatibilityCheck = true;
|
|
1384
1564
|
|
|
1385
1565
|
// src/index.ts
|
|
1566
|
+
function isInngestWorkflow(input) {
|
|
1567
|
+
return input instanceof InngestWorkflow;
|
|
1568
|
+
}
|
|
1569
|
+
function isAgent(input) {
|
|
1570
|
+
return input instanceof agent.Agent;
|
|
1571
|
+
}
|
|
1572
|
+
function isToolStep(input) {
|
|
1573
|
+
return input instanceof tools.Tool;
|
|
1574
|
+
}
|
|
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);
|
|
1577
|
+
}
|
|
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
|
+
}
|
|
1386
1581
|
function createStep(params, agentOrToolOptions) {
|
|
1387
|
-
if (params
|
|
1582
|
+
if (isInngestWorkflow(params)) {
|
|
1388
1583
|
return params;
|
|
1389
1584
|
}
|
|
1390
|
-
if (params
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
return
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1585
|
+
if (isAgent(params)) {
|
|
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
|
|
1420
1662
|
});
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
// threadId: inputData.threadId,
|
|
1432
|
-
requestContext,
|
|
1433
|
-
tracingContext,
|
|
1434
|
-
onFinish: (result) => {
|
|
1435
|
-
const resultWithObject = result;
|
|
1436
|
-
if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
|
|
1437
|
-
structuredResult = resultWithObject.object;
|
|
1438
|
-
}
|
|
1439
|
-
streamPromise.resolve(result.text);
|
|
1440
|
-
void agentOptions?.onFinish?.(result);
|
|
1441
|
-
},
|
|
1442
|
-
abortSignal
|
|
1443
|
-
});
|
|
1444
|
-
stream = fullStream;
|
|
1445
|
-
} else {
|
|
1446
|
-
const modelOutput = await params.stream(inputData.prompt, {
|
|
1447
|
-
...agentOptions ?? {},
|
|
1448
|
-
requestContext,
|
|
1449
|
-
tracingContext,
|
|
1450
|
-
onFinish: (result) => {
|
|
1451
|
-
const resultWithObject = result;
|
|
1452
|
-
if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
|
|
1453
|
-
structuredResult = resultWithObject.object;
|
|
1454
|
-
}
|
|
1455
|
-
streamPromise.resolve(result.text);
|
|
1456
|
-
void agentOptions?.onFinish?.(result);
|
|
1457
|
-
},
|
|
1458
|
-
abortSignal
|
|
1459
|
-
});
|
|
1460
|
-
stream = modelOutput.fullStream;
|
|
1461
|
-
}
|
|
1462
|
-
if (streamFormat === "legacy") {
|
|
1463
|
-
await pubsub.publish(`workflow.events.v2.${runId}`, {
|
|
1464
|
-
type: "watch",
|
|
1465
|
-
runId,
|
|
1466
|
-
data: { type: "tool-call-streaming-start", ...toolData ?? {} }
|
|
1467
|
-
});
|
|
1468
|
-
for await (const chunk of stream) {
|
|
1469
|
-
if (chunk.type === "text-delta") {
|
|
1470
|
-
await pubsub.publish(`workflow.events.v2.${runId}`, {
|
|
1471
|
-
type: "watch",
|
|
1472
|
-
runId,
|
|
1473
|
-
data: { type: "tool-call-delta", ...toolData ?? {}, argsTextDelta: chunk.textDelta }
|
|
1474
|
-
});
|
|
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;
|
|
1475
1673
|
}
|
|
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
|
+
});
|
|
1476
1694
|
}
|
|
1477
|
-
await pubsub.publish(`workflow.events.v2.${runId}`, {
|
|
1478
|
-
type: "watch",
|
|
1479
|
-
runId,
|
|
1480
|
-
data: { type: "tool-call-streaming-finish", ...toolData ?? {} }
|
|
1481
|
-
});
|
|
1482
|
-
} else {
|
|
1483
|
-
for await (const chunk of stream) {
|
|
1484
|
-
await writer.write(chunk);
|
|
1485
|
-
}
|
|
1486
|
-
}
|
|
1487
|
-
if (abortSignal.aborted) {
|
|
1488
|
-
return abort();
|
|
1489
1695
|
}
|
|
1490
|
-
|
|
1491
|
-
|
|
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);
|
|
1492
1704
|
}
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
}
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
suspendSchema: params.suspendSchema,
|
|
1512
|
-
resumeSchema: params.resumeSchema,
|
|
1513
|
-
retries: toolOpts?.retries,
|
|
1514
|
-
scorers: toolOpts?.scorers,
|
|
1515
|
-
execute: async ({
|
|
1516
|
-
inputData,
|
|
1517
|
-
mastra,
|
|
1518
|
-
requestContext,
|
|
1519
|
-
tracingContext,
|
|
1520
|
-
suspend,
|
|
1521
|
-
resumeData,
|
|
1522
|
-
runId,
|
|
1523
|
-
workflowId,
|
|
1524
|
-
state,
|
|
1525
|
-
setState
|
|
1526
|
-
}) => {
|
|
1527
|
-
const toolContext = {
|
|
1528
|
-
mastra,
|
|
1529
|
-
requestContext,
|
|
1530
|
-
tracingContext,
|
|
1531
|
-
workflow: {
|
|
1532
|
-
runId,
|
|
1533
|
-
resumeData,
|
|
1534
|
-
suspend,
|
|
1535
|
-
workflowId,
|
|
1536
|
-
state,
|
|
1537
|
-
setState
|
|
1538
|
-
}
|
|
1539
|
-
};
|
|
1540
|
-
return params.execute(inputData, toolContext);
|
|
1541
|
-
},
|
|
1542
|
-
component: "TOOL"
|
|
1543
|
-
};
|
|
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");
|
|
1544
1723
|
}
|
|
1545
1724
|
return {
|
|
1546
1725
|
id: params.id,
|
|
@@ -1549,9 +1728,480 @@ function createStep(params, agentOrToolOptions) {
|
|
|
1549
1728
|
outputSchema: params.outputSchema,
|
|
1550
1729
|
resumeSchema: params.resumeSchema,
|
|
1551
1730
|
suspendSchema: params.suspendSchema,
|
|
1552
|
-
retries:
|
|
1553
|
-
scorers:
|
|
1554
|
-
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"
|
|
1555
2205
|
};
|
|
1556
2206
|
}
|
|
1557
2207
|
function init(inngest) {
|