@mastra/inngest 1.0.0-beta.8 → 1.0.0
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 +1275 -0
- package/dist/__tests__/adapters/_utils.d.ts +18 -0
- package/dist/__tests__/adapters/_utils.d.ts.map +1 -0
- package/dist/execution-engine.d.ts +102 -5
- package/dist/execution-engine.d.ts.map +1 -1
- package/dist/index.cjs +1041 -289
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +70 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1042 -291
- package/dist/index.js.map +1 -1
- package/dist/run.d.ts +59 -51
- package/dist/run.d.ts.map +1 -1
- package/dist/serve.d.ts +66 -3
- package/dist/serve.d.ts.map +1 -1
- package/dist/types.d.ts +7 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/workflow.d.ts +5 -4
- package/dist/workflow.d.ts.map +1 -1
- package/package.json +22 -10
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
*
|
|
111
|
-
*
|
|
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
|
|
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
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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.
|
|
@@ -158,7 +263,23 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
158
263
|
if (!(params.step instanceof InngestWorkflow)) {
|
|
159
264
|
return null;
|
|
160
265
|
}
|
|
161
|
-
const {
|
|
266
|
+
const {
|
|
267
|
+
step,
|
|
268
|
+
stepResults,
|
|
269
|
+
executionContext,
|
|
270
|
+
resume,
|
|
271
|
+
timeTravel,
|
|
272
|
+
prevOutput,
|
|
273
|
+
inputData,
|
|
274
|
+
pubsub,
|
|
275
|
+
startedAt,
|
|
276
|
+
perStep,
|
|
277
|
+
stepSpan
|
|
278
|
+
} = params;
|
|
279
|
+
const nestedTracingContext = executionContext.tracingIds?.traceId ? {
|
|
280
|
+
traceId: executionContext.tracingIds.traceId,
|
|
281
|
+
parentSpanId: stepSpan?.id
|
|
282
|
+
} : void 0;
|
|
162
283
|
const isResume = !!resume?.steps?.length;
|
|
163
284
|
let result;
|
|
164
285
|
let runId;
|
|
@@ -166,7 +287,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
166
287
|
try {
|
|
167
288
|
if (isResume) {
|
|
168
289
|
runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? crypto$1.randomUUID();
|
|
169
|
-
const
|
|
290
|
+
const workflowsStore = await this.mastra?.getStorage()?.getStore("workflows");
|
|
291
|
+
const snapshot = await workflowsStore?.loadWorkflowSnapshot({
|
|
170
292
|
workflowName: step.id,
|
|
171
293
|
runId
|
|
172
294
|
});
|
|
@@ -183,14 +305,17 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
183
305
|
resumePayload: resume.resumePayload,
|
|
184
306
|
resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
|
|
185
307
|
},
|
|
186
|
-
outputOptions: { includeState: true }
|
|
308
|
+
outputOptions: { includeState: true },
|
|
309
|
+
perStep,
|
|
310
|
+
tracingOptions: nestedTracingContext
|
|
187
311
|
}
|
|
188
312
|
});
|
|
189
313
|
result = invokeResp.result;
|
|
190
314
|
runId = invokeResp.runId;
|
|
191
315
|
executionContext.state = invokeResp.result.state;
|
|
192
316
|
} else if (isTimeTravel) {
|
|
193
|
-
const
|
|
317
|
+
const workflowsStoreForTimeTravel = await this.mastra?.getStorage()?.getStore("workflows");
|
|
318
|
+
const snapshot = await workflowsStoreForTimeTravel?.loadWorkflowSnapshot({
|
|
194
319
|
workflowName: step.id,
|
|
195
320
|
runId: executionContext.runId
|
|
196
321
|
}) ?? { context: {} };
|
|
@@ -209,7 +334,9 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
209
334
|
timeTravel: timeTravelParams,
|
|
210
335
|
initialState: executionContext.state ?? {},
|
|
211
336
|
runId: executionContext.runId,
|
|
212
|
-
outputOptions: { includeState: true }
|
|
337
|
+
outputOptions: { includeState: true },
|
|
338
|
+
perStep,
|
|
339
|
+
tracingOptions: nestedTracingContext
|
|
213
340
|
}
|
|
214
341
|
});
|
|
215
342
|
result = invokeResp.result;
|
|
@@ -221,7 +348,9 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
221
348
|
data: {
|
|
222
349
|
inputData,
|
|
223
350
|
initialState: executionContext.state ?? {},
|
|
224
|
-
outputOptions: { includeState: true }
|
|
351
|
+
outputOptions: { includeState: true },
|
|
352
|
+
perStep,
|
|
353
|
+
tracingOptions: nestedTracingContext
|
|
225
354
|
}
|
|
226
355
|
});
|
|
227
356
|
result = invokeResp.result;
|
|
@@ -260,7 +389,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
260
389
|
}
|
|
261
390
|
}
|
|
262
391
|
});
|
|
263
|
-
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
392
|
+
return { executionContext, result: { status: "failed", error: result?.error, endedAt: Date.now() } };
|
|
264
393
|
} else if (result.status === "suspended") {
|
|
265
394
|
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
266
395
|
const stepRes = stepResult;
|
|
@@ -284,6 +413,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
284
413
|
executionContext,
|
|
285
414
|
result: {
|
|
286
415
|
status: "suspended",
|
|
416
|
+
suspendedAt: Date.now(),
|
|
287
417
|
payload: stepResult.payload,
|
|
288
418
|
suspendPayload: {
|
|
289
419
|
...stepResult?.suspendPayload,
|
|
@@ -296,6 +426,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
296
426
|
executionContext,
|
|
297
427
|
result: {
|
|
298
428
|
status: "suspended",
|
|
429
|
+
suspendedAt: Date.now(),
|
|
299
430
|
payload: {}
|
|
300
431
|
}
|
|
301
432
|
};
|
|
@@ -317,9 +448,34 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
317
448
|
executionContext,
|
|
318
449
|
result: {
|
|
319
450
|
status: "tripwire",
|
|
320
|
-
tripwire: result?.tripwire
|
|
451
|
+
tripwire: result?.tripwire,
|
|
452
|
+
endedAt: Date.now()
|
|
321
453
|
}
|
|
322
454
|
};
|
|
455
|
+
} else if (perStep || result.status === "paused") {
|
|
456
|
+
await pubsub.publish(`workflow.events.v2.${executionContext.runId}`, {
|
|
457
|
+
type: "watch",
|
|
458
|
+
runId: executionContext.runId,
|
|
459
|
+
data: {
|
|
460
|
+
type: "workflow-step-result",
|
|
461
|
+
payload: {
|
|
462
|
+
id: step.id,
|
|
463
|
+
status: "paused"
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
await pubsub.publish(`workflow.events.v2.${executionContext.runId}`, {
|
|
468
|
+
type: "watch",
|
|
469
|
+
runId: executionContext.runId,
|
|
470
|
+
data: {
|
|
471
|
+
type: "workflow-step-finish",
|
|
472
|
+
payload: {
|
|
473
|
+
id: step.id,
|
|
474
|
+
metadata: {}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
return { executionContext, result: { status: "paused" } };
|
|
323
479
|
}
|
|
324
480
|
await pubsub.publish(`workflow.events.v2.${executionContext.runId}`, {
|
|
325
481
|
type: "watch",
|
|
@@ -344,14 +500,13 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
344
500
|
}
|
|
345
501
|
}
|
|
346
502
|
});
|
|
347
|
-
return { executionContext, result: { status: "success", output: result?.result } };
|
|
503
|
+
return { executionContext, result: { status: "success", output: result?.result, endedAt: Date.now() } };
|
|
348
504
|
}
|
|
349
505
|
);
|
|
350
506
|
Object.assign(executionContext, res.executionContext);
|
|
351
507
|
return {
|
|
352
508
|
...res.result,
|
|
353
509
|
startedAt,
|
|
354
|
-
endedAt: Date.now(),
|
|
355
510
|
payload: inputData,
|
|
356
511
|
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
357
512
|
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
@@ -520,6 +675,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
520
675
|
async getRunOutput(eventId, maxWaitMs = 3e5) {
|
|
521
676
|
const startTime = Date.now();
|
|
522
677
|
const storage = this.#mastra?.getStorage();
|
|
678
|
+
const workflowsStore = await storage?.getStore("workflows");
|
|
523
679
|
while (Date.now() - startTime < maxWaitMs) {
|
|
524
680
|
let runs;
|
|
525
681
|
try {
|
|
@@ -536,7 +692,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
536
692
|
return runs[0];
|
|
537
693
|
}
|
|
538
694
|
if (runs?.[0]?.status === "Failed") {
|
|
539
|
-
const snapshot = await
|
|
695
|
+
const snapshot = await workflowsStore?.loadWorkflowSnapshot({
|
|
540
696
|
workflowName: this.workflowId,
|
|
541
697
|
runId: this.runId
|
|
542
698
|
});
|
|
@@ -555,7 +711,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
555
711
|
};
|
|
556
712
|
}
|
|
557
713
|
if (runs?.[0]?.status === "Cancelled") {
|
|
558
|
-
const snapshot = await
|
|
714
|
+
const snapshot = await workflowsStore?.loadWorkflowSnapshot({
|
|
559
715
|
workflowName: this.workflowId,
|
|
560
716
|
runId: this.runId
|
|
561
717
|
});
|
|
@@ -573,12 +729,13 @@ var InngestRun = class extends workflows.Run {
|
|
|
573
729
|
runId: this.runId
|
|
574
730
|
}
|
|
575
731
|
});
|
|
576
|
-
const
|
|
732
|
+
const workflowsStore = await storage?.getStore("workflows");
|
|
733
|
+
const snapshot = await workflowsStore?.loadWorkflowSnapshot({
|
|
577
734
|
workflowName: this.workflowId,
|
|
578
735
|
runId: this.runId
|
|
579
736
|
});
|
|
580
737
|
if (snapshot) {
|
|
581
|
-
await
|
|
738
|
+
await workflowsStore?.persistWorkflowSnapshot({
|
|
582
739
|
workflowName: this.workflowId,
|
|
583
740
|
runId: this.runId,
|
|
584
741
|
resourceId: this.resourceId,
|
|
@@ -590,8 +747,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
590
747
|
});
|
|
591
748
|
}
|
|
592
749
|
}
|
|
593
|
-
async start(
|
|
594
|
-
return this._start(
|
|
750
|
+
async start(args) {
|
|
751
|
+
return this._start(args);
|
|
595
752
|
}
|
|
596
753
|
/**
|
|
597
754
|
* Starts the workflow execution without waiting for completion (fire-and-forget).
|
|
@@ -599,8 +756,9 @@ var InngestRun = class extends workflows.Run {
|
|
|
599
756
|
* The workflow executes independently in Inngest.
|
|
600
757
|
* Use this when you don't need to wait for the result or want to avoid polling failures.
|
|
601
758
|
*/
|
|
602
|
-
async startAsync(
|
|
603
|
-
await this.#mastra.getStorage()?.
|
|
759
|
+
async startAsync(args) {
|
|
760
|
+
const workflowsStore = await this.#mastra.getStorage()?.getStore("workflows");
|
|
761
|
+
await workflowsStore?.persistWorkflowSnapshot({
|
|
604
762
|
workflowName: this.workflowId,
|
|
605
763
|
runId: this.runId,
|
|
606
764
|
resourceId: this.resourceId,
|
|
@@ -618,8 +776,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
618
776
|
timestamp: Date.now()
|
|
619
777
|
}
|
|
620
778
|
});
|
|
621
|
-
const inputDataToUse = await this._validateInput(
|
|
622
|
-
const initialStateToUse = await this._validateInitialState(
|
|
779
|
+
const inputDataToUse = await this._validateInput(args.inputData);
|
|
780
|
+
const initialStateToUse = await this._validateInitialState(args.initialState ?? {});
|
|
623
781
|
const eventOutput = await this.inngest.send({
|
|
624
782
|
name: `workflow.${this.workflowId}`,
|
|
625
783
|
data: {
|
|
@@ -627,9 +785,10 @@ var InngestRun = class extends workflows.Run {
|
|
|
627
785
|
initialState: initialStateToUse,
|
|
628
786
|
runId: this.runId,
|
|
629
787
|
resourceId: this.resourceId,
|
|
630
|
-
outputOptions:
|
|
631
|
-
tracingOptions:
|
|
632
|
-
requestContext:
|
|
788
|
+
outputOptions: args.outputOptions,
|
|
789
|
+
tracingOptions: args.tracingOptions,
|
|
790
|
+
requestContext: args.requestContext ? Object.fromEntries(args.requestContext.entries()) : {},
|
|
791
|
+
perStep: args.perStep
|
|
633
792
|
}
|
|
634
793
|
});
|
|
635
794
|
const eventId = eventOutput.ids[0];
|
|
@@ -644,9 +803,11 @@ var InngestRun = class extends workflows.Run {
|
|
|
644
803
|
outputOptions,
|
|
645
804
|
tracingOptions,
|
|
646
805
|
format,
|
|
647
|
-
requestContext
|
|
806
|
+
requestContext,
|
|
807
|
+
perStep
|
|
648
808
|
}) {
|
|
649
|
-
await this.#mastra.getStorage()?.
|
|
809
|
+
const workflowsStore = await this.#mastra.getStorage()?.getStore("workflows");
|
|
810
|
+
await workflowsStore?.persistWorkflowSnapshot({
|
|
650
811
|
workflowName: this.workflowId,
|
|
651
812
|
runId: this.runId,
|
|
652
813
|
resourceId: this.resourceId,
|
|
@@ -676,7 +837,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
676
837
|
outputOptions,
|
|
677
838
|
tracingOptions,
|
|
678
839
|
format,
|
|
679
|
-
requestContext: requestContext ? Object.fromEntries(requestContext.entries()) : {}
|
|
840
|
+
requestContext: requestContext ? Object.fromEntries(requestContext.entries()) : {},
|
|
841
|
+
perStep
|
|
680
842
|
}
|
|
681
843
|
});
|
|
682
844
|
const eventId = eventOutput.ids[0];
|
|
@@ -712,7 +874,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
712
874
|
(step) => typeof step === "string" ? step : step?.id
|
|
713
875
|
);
|
|
714
876
|
}
|
|
715
|
-
const
|
|
877
|
+
const workflowsStore = await storage?.getStore("workflows");
|
|
878
|
+
const snapshot = await workflowsStore?.loadWorkflowSnapshot({
|
|
716
879
|
workflowName: this.workflowId,
|
|
717
880
|
runId: this.runId
|
|
718
881
|
});
|
|
@@ -735,7 +898,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
735
898
|
resumePayload: resumeDataToUse,
|
|
736
899
|
resumePath: steps?.[0] ? snapshot?.suspendedPaths?.[steps?.[0]] : void 0
|
|
737
900
|
},
|
|
738
|
-
requestContext: mergedRequestContext
|
|
901
|
+
requestContext: mergedRequestContext,
|
|
902
|
+
perStep: params.perStep
|
|
739
903
|
}
|
|
740
904
|
});
|
|
741
905
|
const eventId = eventOutput.ids[0];
|
|
@@ -774,12 +938,13 @@ var InngestRun = class extends workflows.Run {
|
|
|
774
938
|
throw new Error("No steps provided to timeTravel");
|
|
775
939
|
}
|
|
776
940
|
const storage = this.#mastra?.getStorage();
|
|
777
|
-
const
|
|
941
|
+
const workflowsStore = await storage?.getStore("workflows");
|
|
942
|
+
const snapshot = await workflowsStore?.loadWorkflowSnapshot({
|
|
778
943
|
workflowName: this.workflowId,
|
|
779
944
|
runId: this.runId
|
|
780
945
|
});
|
|
781
946
|
if (!snapshot) {
|
|
782
|
-
await
|
|
947
|
+
await workflowsStore?.persistWorkflowSnapshot({
|
|
783
948
|
workflowName: this.workflowId,
|
|
784
949
|
runId: this.runId,
|
|
785
950
|
resourceId: this.resourceId,
|
|
@@ -813,7 +978,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
813
978
|
nestedStepsContext: params.nestedStepsContext,
|
|
814
979
|
snapshot: snapshot ?? { context: {} },
|
|
815
980
|
graph: this.executionGraph,
|
|
816
|
-
initialState: params.initialState
|
|
981
|
+
initialState: params.initialState,
|
|
982
|
+
perStep: params.perStep
|
|
817
983
|
});
|
|
818
984
|
const eventOutput = await this.inngest.send({
|
|
819
985
|
name: `workflow.${this.workflowId}`,
|
|
@@ -825,7 +991,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
825
991
|
timeTravel: timeTravelData,
|
|
826
992
|
tracingOptions: params.tracingOptions,
|
|
827
993
|
outputOptions: params.outputOptions,
|
|
828
|
-
requestContext: params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {}
|
|
994
|
+
requestContext: params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {},
|
|
995
|
+
perStep: params.perStep
|
|
829
996
|
}
|
|
830
997
|
});
|
|
831
998
|
const eventId = eventOutput.ids[0];
|
|
@@ -916,7 +1083,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
916
1083
|
tracingOptions,
|
|
917
1084
|
closeOnSuspend = true,
|
|
918
1085
|
initialState,
|
|
919
|
-
outputOptions
|
|
1086
|
+
outputOptions,
|
|
1087
|
+
perStep
|
|
920
1088
|
} = {}) {
|
|
921
1089
|
if (this.closeStreamAction && this.streamOutput) {
|
|
922
1090
|
return this.streamOutput;
|
|
@@ -952,7 +1120,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
952
1120
|
initialState,
|
|
953
1121
|
tracingOptions,
|
|
954
1122
|
outputOptions,
|
|
955
|
-
format: "vnext"
|
|
1123
|
+
format: "vnext",
|
|
1124
|
+
perStep
|
|
956
1125
|
});
|
|
957
1126
|
let executionResults;
|
|
958
1127
|
try {
|
|
@@ -983,9 +1152,6 @@ var InngestRun = class extends workflows.Run {
|
|
|
983
1152
|
});
|
|
984
1153
|
return this.streamOutput;
|
|
985
1154
|
}
|
|
986
|
-
streamVNext(args = {}) {
|
|
987
|
-
return this.stream(args);
|
|
988
|
-
}
|
|
989
1155
|
timeTravelStream({
|
|
990
1156
|
inputData,
|
|
991
1157
|
resumeData,
|
|
@@ -994,8 +1160,10 @@ var InngestRun = class extends workflows.Run {
|
|
|
994
1160
|
context,
|
|
995
1161
|
nestedStepsContext,
|
|
996
1162
|
requestContext,
|
|
1163
|
+
// tracingContext,
|
|
997
1164
|
tracingOptions,
|
|
998
|
-
outputOptions
|
|
1165
|
+
outputOptions,
|
|
1166
|
+
perStep
|
|
999
1167
|
}) {
|
|
1000
1168
|
this.closeStreamAction = async () => {
|
|
1001
1169
|
};
|
|
@@ -1030,7 +1198,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
1030
1198
|
initialState,
|
|
1031
1199
|
requestContext,
|
|
1032
1200
|
tracingOptions,
|
|
1033
|
-
outputOptions
|
|
1201
|
+
outputOptions,
|
|
1202
|
+
perStep
|
|
1034
1203
|
});
|
|
1035
1204
|
self.executionResults = executionResultsPromise;
|
|
1036
1205
|
let executionResults;
|
|
@@ -1074,9 +1243,11 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
1074
1243
|
#mastra;
|
|
1075
1244
|
inngest;
|
|
1076
1245
|
function;
|
|
1246
|
+
cronFunction;
|
|
1077
1247
|
flowControlConfig;
|
|
1248
|
+
cronConfig;
|
|
1078
1249
|
constructor(params, inngest) {
|
|
1079
|
-
const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
|
|
1250
|
+
const { concurrency, rateLimit, throttle, debounce, priority, cron, inputData, initialState, ...workflowParams } = params;
|
|
1080
1251
|
super(workflowParams);
|
|
1081
1252
|
this.engineType = "inngest";
|
|
1082
1253
|
const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
|
|
@@ -1085,6 +1256,9 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
1085
1256
|
this.flowControlConfig = flowControlEntries.length > 0 ? Object.fromEntries(flowControlEntries) : void 0;
|
|
1086
1257
|
this.#mastra = params.mastra;
|
|
1087
1258
|
this.inngest = inngest;
|
|
1259
|
+
if (cron) {
|
|
1260
|
+
this.cronConfig = { cron, inputData, initialState };
|
|
1261
|
+
}
|
|
1088
1262
|
}
|
|
1089
1263
|
async listWorkflowRuns(args) {
|
|
1090
1264
|
const storage = this.#mastra?.getStorage();
|
|
@@ -1092,16 +1266,11 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
1092
1266
|
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
1093
1267
|
return { runs: [], total: 0 };
|
|
1094
1268
|
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
const storage = this.#mastra?.getStorage();
|
|
1099
|
-
if (!storage) {
|
|
1100
|
-
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
1101
|
-
return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
|
|
1269
|
+
const workflowsStore = await storage.getStore("workflows");
|
|
1270
|
+
if (!workflowsStore) {
|
|
1271
|
+
return { runs: [], total: 0 };
|
|
1102
1272
|
}
|
|
1103
|
-
|
|
1104
|
-
return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
|
|
1273
|
+
return workflowsStore.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
|
|
1105
1274
|
}
|
|
1106
1275
|
__registerMastra(mastra) {
|
|
1107
1276
|
super.__registerMastra(mastra);
|
|
@@ -1124,7 +1293,8 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
1124
1293
|
}
|
|
1125
1294
|
async createRun(options) {
|
|
1126
1295
|
const runIdToUse = options?.runId || crypto$1.randomUUID();
|
|
1127
|
-
const
|
|
1296
|
+
const existingInMemoryRun = this.runs.get(runIdToUse);
|
|
1297
|
+
const newRun = new InngestRun(
|
|
1128
1298
|
{
|
|
1129
1299
|
workflowId: this.id,
|
|
1130
1300
|
runId: runIdToUse,
|
|
@@ -1141,14 +1311,19 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
1141
1311
|
},
|
|
1142
1312
|
this.inngest
|
|
1143
1313
|
);
|
|
1314
|
+
const run = existingInMemoryRun ?? newRun;
|
|
1144
1315
|
this.runs.set(runIdToUse, run);
|
|
1145
1316
|
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
|
|
1146
1317
|
workflowStatus: run.workflowRunStatus,
|
|
1147
1318
|
stepResults: {}
|
|
1148
1319
|
});
|
|
1149
|
-
const
|
|
1150
|
-
|
|
1151
|
-
|
|
1320
|
+
const existingStoredRun = await this.getWorkflowRunById(runIdToUse, {
|
|
1321
|
+
withNestedWorkflows: false
|
|
1322
|
+
});
|
|
1323
|
+
const existsInStorage = existingStoredRun && !existingStoredRun.isFromInMemory;
|
|
1324
|
+
if (!existsInStorage && shouldPersistSnapshot) {
|
|
1325
|
+
const workflowsStore = await this.mastra?.getStorage()?.getStore("workflows");
|
|
1326
|
+
await workflowsStore?.persistWorkflowSnapshot({
|
|
1152
1327
|
workflowName: this.id,
|
|
1153
1328
|
runId: runIdToUse,
|
|
1154
1329
|
resourceId: options?.resourceId,
|
|
@@ -1171,6 +1346,30 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
1171
1346
|
}
|
|
1172
1347
|
return run;
|
|
1173
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
|
+
}
|
|
1174
1373
|
getFunction() {
|
|
1175
1374
|
if (this.function) {
|
|
1176
1375
|
return this.function;
|
|
@@ -1178,52 +1377,128 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
1178
1377
|
this.function = this.inngest.createFunction(
|
|
1179
1378
|
{
|
|
1180
1379
|
id: `workflow.${this.id}`,
|
|
1181
|
-
retries:
|
|
1380
|
+
retries: 0,
|
|
1182
1381
|
cancelOn: [{ event: `cancel.workflow.${this.id}` }],
|
|
1183
1382
|
// Spread flow control configuration
|
|
1184
1383
|
...this.flowControlConfig
|
|
1185
1384
|
},
|
|
1186
1385
|
{ event: `workflow.${this.id}` },
|
|
1187
1386
|
async ({ event, step, attempt, publish }) => {
|
|
1188
|
-
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;
|
|
1189
1399
|
if (!runId) {
|
|
1190
1400
|
runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
|
|
1191
1401
|
return crypto$1.randomUUID();
|
|
1192
1402
|
});
|
|
1193
1403
|
}
|
|
1194
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
|
+
});
|
|
1195
1427
|
const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
}
|
|
1221
|
-
|
|
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
|
+
}
|
|
1222
1464
|
}
|
|
1223
|
-
}
|
|
1224
|
-
})
|
|
1465
|
+
});
|
|
1466
|
+
} catch (error) {
|
|
1467
|
+
throw error;
|
|
1468
|
+
}
|
|
1225
1469
|
await step.run(`workflow.${this.id}.finalize`, async () => {
|
|
1226
|
-
|
|
1470
|
+
if (result.status !== "paused") {
|
|
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
|
+
}
|
|
1501
|
+
}
|
|
1227
1502
|
if (result.status === "failed") {
|
|
1228
1503
|
throw new inngest.NonRetriableError(`Workflow failed`, {
|
|
1229
1504
|
cause: result
|
|
@@ -1250,15 +1525,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
1250
1525
|
});
|
|
1251
1526
|
}
|
|
1252
1527
|
getFunctions() {
|
|
1253
|
-
return [
|
|
1528
|
+
return [
|
|
1529
|
+
this.getFunction(),
|
|
1530
|
+
...this.cronConfig?.cron ? [this.createCronFunction()] : [],
|
|
1531
|
+
...this.getNestedFunctions(this.executionGraph.steps)
|
|
1532
|
+
];
|
|
1254
1533
|
}
|
|
1255
1534
|
};
|
|
1256
|
-
function
|
|
1257
|
-
mastra,
|
|
1258
|
-
inngest,
|
|
1259
|
-
functions: userFunctions = [],
|
|
1260
|
-
registerOptions
|
|
1261
|
-
}) {
|
|
1535
|
+
function prepareServeOptions({ mastra, inngest, functions: userFunctions = [], registerOptions }) {
|
|
1262
1536
|
const wfs = mastra.listWorkflows();
|
|
1263
1537
|
const workflowFunctions = Array.from(
|
|
1264
1538
|
new Set(
|
|
@@ -1271,177 +1545,181 @@ function serve({
|
|
|
1271
1545
|
})
|
|
1272
1546
|
)
|
|
1273
1547
|
);
|
|
1274
|
-
return
|
|
1548
|
+
return {
|
|
1275
1549
|
...registerOptions,
|
|
1276
1550
|
client: inngest,
|
|
1277
1551
|
functions: [...workflowFunctions, ...userFunctions]
|
|
1278
|
-
}
|
|
1552
|
+
};
|
|
1279
1553
|
}
|
|
1554
|
+
function createServe(adapter) {
|
|
1555
|
+
return (options) => {
|
|
1556
|
+
const serveOptions = prepareServeOptions(options);
|
|
1557
|
+
return adapter(serveOptions);
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
var serve = createServe(hono.serve);
|
|
1280
1561
|
|
|
1281
1562
|
// src/types.ts
|
|
1282
1563
|
var _compatibilityCheck = true;
|
|
1283
1564
|
|
|
1284
1565
|
// src/index.ts
|
|
1285
|
-
function
|
|
1286
|
-
return
|
|
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;
|
|
1287
1574
|
}
|
|
1288
|
-
function
|
|
1289
|
-
return
|
|
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);
|
|
1290
1577
|
}
|
|
1291
|
-
function
|
|
1292
|
-
return
|
|
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");
|
|
1293
1580
|
}
|
|
1294
|
-
function createStep(params,
|
|
1581
|
+
function createStep(params, agentOrToolOptions) {
|
|
1295
1582
|
if (isInngestWorkflow(params)) {
|
|
1296
1583
|
return params;
|
|
1297
1584
|
}
|
|
1298
1585
|
if (isAgent(params)) {
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
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
|
|
1324
1662
|
});
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
// threadId: inputData.threadId,
|
|
1336
|
-
requestContext,
|
|
1337
|
-
tracingContext,
|
|
1338
|
-
onFinish: (result) => {
|
|
1339
|
-
const resultWithObject = result;
|
|
1340
|
-
if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
|
|
1341
|
-
structuredResult = resultWithObject.object;
|
|
1342
|
-
}
|
|
1343
|
-
streamPromise.resolve(result.text);
|
|
1344
|
-
void agentOptions?.onFinish?.(result);
|
|
1345
|
-
},
|
|
1346
|
-
abortSignal
|
|
1347
|
-
});
|
|
1348
|
-
stream = fullStream;
|
|
1349
|
-
} else {
|
|
1350
|
-
const modelOutput = await params.stream(inputData.prompt, {
|
|
1351
|
-
...agentOptions ?? {},
|
|
1352
|
-
requestContext,
|
|
1353
|
-
tracingContext,
|
|
1354
|
-
onFinish: (result) => {
|
|
1355
|
-
const resultWithObject = result;
|
|
1356
|
-
if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
|
|
1357
|
-
structuredResult = resultWithObject.object;
|
|
1358
|
-
}
|
|
1359
|
-
streamPromise.resolve(result.text);
|
|
1360
|
-
void agentOptions?.onFinish?.(result);
|
|
1361
|
-
},
|
|
1362
|
-
abortSignal
|
|
1363
|
-
});
|
|
1364
|
-
stream = modelOutput.fullStream;
|
|
1365
|
-
}
|
|
1366
|
-
if (streamFormat === "legacy") {
|
|
1367
|
-
await pubsub.publish(`workflow.events.v2.${runId}`, {
|
|
1368
|
-
type: "watch",
|
|
1369
|
-
runId,
|
|
1370
|
-
data: { type: "tool-call-streaming-start", ...toolData ?? {} }
|
|
1371
|
-
});
|
|
1372
|
-
for await (const chunk of stream) {
|
|
1373
|
-
if (chunk.type === "text-delta") {
|
|
1374
|
-
await pubsub.publish(`workflow.events.v2.${runId}`, {
|
|
1375
|
-
type: "watch",
|
|
1376
|
-
runId,
|
|
1377
|
-
data: { type: "tool-call-delta", ...toolData ?? {}, argsTextDelta: chunk.textDelta }
|
|
1378
|
-
});
|
|
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;
|
|
1379
1673
|
}
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
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
|
+
});
|
|
1389
1694
|
}
|
|
1390
1695
|
}
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
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);
|
|
1396
1704
|
}
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
}
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
resumeSchema: params.resumeSchema,
|
|
1416
|
-
execute: async ({
|
|
1417
|
-
inputData,
|
|
1418
|
-
mastra,
|
|
1419
|
-
requestContext,
|
|
1420
|
-
tracingContext,
|
|
1421
|
-
suspend,
|
|
1422
|
-
resumeData,
|
|
1423
|
-
runId,
|
|
1424
|
-
workflowId,
|
|
1425
|
-
state,
|
|
1426
|
-
setState
|
|
1427
|
-
}) => {
|
|
1428
|
-
const toolContext = {
|
|
1429
|
-
mastra,
|
|
1430
|
-
requestContext,
|
|
1431
|
-
tracingContext,
|
|
1432
|
-
workflow: {
|
|
1433
|
-
runId,
|
|
1434
|
-
resumeData,
|
|
1435
|
-
suspend,
|
|
1436
|
-
workflowId,
|
|
1437
|
-
state,
|
|
1438
|
-
setState
|
|
1439
|
-
}
|
|
1440
|
-
};
|
|
1441
|
-
return params.execute(inputData, toolContext);
|
|
1442
|
-
},
|
|
1443
|
-
component: "TOOL"
|
|
1444
|
-
};
|
|
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");
|
|
1445
1723
|
}
|
|
1446
1724
|
return {
|
|
1447
1725
|
id: params.id,
|
|
@@ -1450,7 +1728,480 @@ function createStep(params, agentOptions) {
|
|
|
1450
1728
|
outputSchema: params.outputSchema,
|
|
1451
1729
|
resumeSchema: params.resumeSchema,
|
|
1452
1730
|
suspendSchema: params.suspendSchema,
|
|
1453
|
-
|
|
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"
|
|
1454
2205
|
};
|
|
1455
2206
|
}
|
|
1456
2207
|
function init(inngest) {
|
|
@@ -1498,6 +2249,7 @@ exports.InngestPubSub = InngestPubSub;
|
|
|
1498
2249
|
exports.InngestRun = InngestRun;
|
|
1499
2250
|
exports.InngestWorkflow = InngestWorkflow;
|
|
1500
2251
|
exports._compatibilityCheck = _compatibilityCheck;
|
|
2252
|
+
exports.createServe = createServe;
|
|
1501
2253
|
exports.createStep = createStep;
|
|
1502
2254
|
exports.init = init;
|
|
1503
2255
|
exports.serve = serve;
|