@mastra/inngest 0.0.0-add-save-score-validation-on-stores-20250911031242 → 0.0.0-agent-error-handling-20251023180025
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 +332 -3
- package/dist/index.cjs +470 -285
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +73 -39
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +471 -286
- package/dist/index.js.map +1 -1
- package/package.json +13 -13
package/dist/index.cjs
CHANGED
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var crypto = require('crypto');
|
|
4
|
+
var web = require('stream/web');
|
|
4
5
|
var realtime = require('@inngest/realtime');
|
|
5
6
|
var aiTracing = require('@mastra/core/ai-tracing');
|
|
6
7
|
var di = require('@mastra/core/di');
|
|
8
|
+
var stream = require('@mastra/core/stream');
|
|
7
9
|
var tools = require('@mastra/core/tools');
|
|
8
10
|
var workflows = require('@mastra/core/workflows');
|
|
9
11
|
var _constants = require('@mastra/core/workflows/_constants');
|
|
12
|
+
var inngest = require('inngest');
|
|
10
13
|
var hono = require('inngest/hono');
|
|
11
14
|
var zod = require('zod');
|
|
12
15
|
|
|
13
16
|
// src/index.ts
|
|
14
|
-
function serve({
|
|
17
|
+
function serve({
|
|
18
|
+
mastra,
|
|
19
|
+
inngest,
|
|
20
|
+
functions: userFunctions = [],
|
|
21
|
+
registerOptions
|
|
22
|
+
}) {
|
|
15
23
|
const wfs = mastra.getWorkflows();
|
|
16
|
-
const
|
|
24
|
+
const workflowFunctions = Array.from(
|
|
17
25
|
new Set(
|
|
18
26
|
Object.values(wfs).flatMap((wf) => {
|
|
19
27
|
if (wf instanceof InngestWorkflow) {
|
|
@@ -25,8 +33,9 @@ function serve({ mastra, inngest }) {
|
|
|
25
33
|
)
|
|
26
34
|
);
|
|
27
35
|
return hono.serve({
|
|
36
|
+
...registerOptions,
|
|
28
37
|
client: inngest,
|
|
29
|
-
functions
|
|
38
|
+
functions: [...workflowFunctions, ...userFunctions]
|
|
30
39
|
});
|
|
31
40
|
}
|
|
32
41
|
var InngestRun = class extends workflows.Run {
|
|
@@ -54,9 +63,15 @@ var InngestRun = class extends workflows.Run {
|
|
|
54
63
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
55
64
|
runs = await this.getRuns(eventId);
|
|
56
65
|
if (runs?.[0]?.status === "Failed") {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
66
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
67
|
+
workflowName: this.workflowId,
|
|
68
|
+
runId: this.runId
|
|
69
|
+
});
|
|
70
|
+
return {
|
|
71
|
+
output: { result: { steps: snapshot?.context, status: "failed", error: runs?.[0]?.output?.message } }
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (runs?.[0]?.status === "Cancelled") {
|
|
60
75
|
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
61
76
|
workflowName: this.workflowId,
|
|
62
77
|
runId: this.runId
|
|
@@ -87,6 +102,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
87
102
|
await this.#mastra?.storage?.persistWorkflowSnapshot({
|
|
88
103
|
workflowName: this.workflowId,
|
|
89
104
|
runId: this.runId,
|
|
105
|
+
resourceId: this.resourceId,
|
|
90
106
|
snapshot: {
|
|
91
107
|
...snapshot,
|
|
92
108
|
status: "canceled"
|
|
@@ -95,11 +111,13 @@ var InngestRun = class extends workflows.Run {
|
|
|
95
111
|
}
|
|
96
112
|
}
|
|
97
113
|
async start({
|
|
98
|
-
inputData
|
|
114
|
+
inputData,
|
|
115
|
+
initialState
|
|
99
116
|
}) {
|
|
100
117
|
await this.#mastra.getStorage()?.persistWorkflowSnapshot({
|
|
101
118
|
workflowName: this.workflowId,
|
|
102
119
|
runId: this.runId,
|
|
120
|
+
resourceId: this.resourceId,
|
|
103
121
|
snapshot: {
|
|
104
122
|
runId: this.runId,
|
|
105
123
|
serializedStepGraph: this.serializedStepGraph,
|
|
@@ -107,16 +125,21 @@ var InngestRun = class extends workflows.Run {
|
|
|
107
125
|
context: {},
|
|
108
126
|
activePaths: [],
|
|
109
127
|
suspendedPaths: {},
|
|
128
|
+
resumeLabels: {},
|
|
110
129
|
waitingPaths: {},
|
|
111
130
|
timestamp: Date.now(),
|
|
112
131
|
status: "running"
|
|
113
132
|
}
|
|
114
133
|
});
|
|
134
|
+
const inputDataToUse = await this._validateInput(inputData);
|
|
135
|
+
const initialStateToUse = await this._validateInitialState(initialState ?? {});
|
|
115
136
|
const eventOutput = await this.inngest.send({
|
|
116
137
|
name: `workflow.${this.workflowId}`,
|
|
117
138
|
data: {
|
|
118
|
-
inputData,
|
|
119
|
-
|
|
139
|
+
inputData: inputDataToUse,
|
|
140
|
+
initialState: initialStateToUse,
|
|
141
|
+
runId: this.runId,
|
|
142
|
+
resourceId: this.resourceId
|
|
120
143
|
}
|
|
121
144
|
});
|
|
122
145
|
const eventId = eventOutput.ids[0];
|
|
@@ -152,17 +175,20 @@ var InngestRun = class extends workflows.Run {
|
|
|
152
175
|
workflowName: this.workflowId,
|
|
153
176
|
runId: this.runId
|
|
154
177
|
});
|
|
178
|
+
const suspendedStep = this.workflowSteps[steps?.[0] ?? ""];
|
|
179
|
+
const resumeDataToUse = await this._validateResumeData(params.resumeData, suspendedStep);
|
|
155
180
|
const eventOutput = await this.inngest.send({
|
|
156
181
|
name: `workflow.${this.workflowId}`,
|
|
157
182
|
data: {
|
|
158
|
-
inputData:
|
|
183
|
+
inputData: resumeDataToUse,
|
|
184
|
+
initialState: snapshot?.value ?? {},
|
|
159
185
|
runId: this.runId,
|
|
160
186
|
workflowId: this.workflowId,
|
|
161
187
|
stepResults: snapshot?.context,
|
|
162
188
|
resume: {
|
|
163
189
|
steps,
|
|
164
190
|
stepResults: snapshot?.context,
|
|
165
|
-
resumePayload:
|
|
191
|
+
resumePayload: resumeDataToUse,
|
|
166
192
|
// @ts-ignore
|
|
167
193
|
resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
|
|
168
194
|
}
|
|
@@ -202,35 +228,11 @@ var InngestRun = class extends workflows.Run {
|
|
|
202
228
|
});
|
|
203
229
|
};
|
|
204
230
|
}
|
|
205
|
-
|
|
231
|
+
streamLegacy({ inputData, runtimeContext } = {}) {
|
|
206
232
|
const { readable, writable } = new TransformStream();
|
|
207
|
-
let currentToolData = void 0;
|
|
208
233
|
const writer = writable.getWriter();
|
|
209
234
|
const unwatch = this.watch(async (event) => {
|
|
210
|
-
if (event.type === "workflow-agent-call-start") {
|
|
211
|
-
currentToolData = {
|
|
212
|
-
name: event.payload.name,
|
|
213
|
-
args: event.payload.args
|
|
214
|
-
};
|
|
215
|
-
await writer.write({
|
|
216
|
-
...event.payload,
|
|
217
|
-
type: "tool-call-streaming-start"
|
|
218
|
-
});
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
235
|
try {
|
|
222
|
-
if (event.type === "workflow-agent-call-finish") {
|
|
223
|
-
return;
|
|
224
|
-
} else if (!event.type.startsWith("workflow-")) {
|
|
225
|
-
if (event.type === "text-delta") {
|
|
226
|
-
await writer.write({
|
|
227
|
-
type: "tool-call-delta",
|
|
228
|
-
...currentToolData ?? {},
|
|
229
|
-
argsTextDelta: event.textDelta
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
236
|
const e = {
|
|
235
237
|
...event,
|
|
236
238
|
type: event.type.replace("workflow-", "")
|
|
@@ -261,6 +263,58 @@ var InngestRun = class extends workflows.Run {
|
|
|
261
263
|
getWorkflowState: () => this.executionResults
|
|
262
264
|
};
|
|
263
265
|
}
|
|
266
|
+
stream({
|
|
267
|
+
inputData,
|
|
268
|
+
runtimeContext,
|
|
269
|
+
closeOnSuspend = true
|
|
270
|
+
} = {}) {
|
|
271
|
+
const self = this;
|
|
272
|
+
let streamOutput;
|
|
273
|
+
const stream$1 = new web.ReadableStream({
|
|
274
|
+
async start(controller) {
|
|
275
|
+
const unwatch = self.watch(async ({ type, from = ChunkFrom.WORKFLOW, payload }) => {
|
|
276
|
+
controller.enqueue({
|
|
277
|
+
type,
|
|
278
|
+
runId: self.runId,
|
|
279
|
+
from,
|
|
280
|
+
payload: {
|
|
281
|
+
stepName: payload.id,
|
|
282
|
+
...payload
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
}, "watch-v2");
|
|
286
|
+
self.closeStreamAction = async () => {
|
|
287
|
+
unwatch();
|
|
288
|
+
try {
|
|
289
|
+
await controller.close();
|
|
290
|
+
} catch (err) {
|
|
291
|
+
console.error("Error closing stream:", err);
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
const executionResultsPromise = self.start({
|
|
295
|
+
inputData,
|
|
296
|
+
runtimeContext
|
|
297
|
+
});
|
|
298
|
+
const executionResults = await executionResultsPromise;
|
|
299
|
+
if (closeOnSuspend) {
|
|
300
|
+
self.closeStreamAction?.().catch(() => {
|
|
301
|
+
});
|
|
302
|
+
} else if (executionResults.status !== "suspended") {
|
|
303
|
+
self.closeStreamAction?.().catch(() => {
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
if (streamOutput) {
|
|
307
|
+
streamOutput.updateResults(executionResults);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
streamOutput = new stream.WorkflowRunOutput({
|
|
312
|
+
runId: this.runId,
|
|
313
|
+
workflowId: this.workflowId,
|
|
314
|
+
stream: stream$1
|
|
315
|
+
});
|
|
316
|
+
return streamOutput;
|
|
317
|
+
}
|
|
264
318
|
};
|
|
265
319
|
var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
266
320
|
#mastra;
|
|
@@ -312,23 +366,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
312
366
|
}
|
|
313
367
|
}
|
|
314
368
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
executionGraph: this.executionGraph,
|
|
323
|
-
serializedStepGraph: this.serializedStepGraph,
|
|
324
|
-
mastra: this.#mastra,
|
|
325
|
-
retryConfig: this.retryConfig,
|
|
326
|
-
cleanup: () => this.runs.delete(runIdToUse)
|
|
327
|
-
},
|
|
328
|
-
this.inngest
|
|
369
|
+
/**
|
|
370
|
+
* @deprecated Use createRunAsync() instead.
|
|
371
|
+
* @throws {Error} Always throws an error directing users to use createRunAsync()
|
|
372
|
+
*/
|
|
373
|
+
createRun(_options) {
|
|
374
|
+
throw new Error(
|
|
375
|
+
"createRun() has been deprecated. Please use createRunAsync() instead.\n\nMigration guide:\n Before: const run = workflow.createRun();\n After: const run = await workflow.createRunAsync();\n\nNote: createRunAsync() is an async method, so make sure your calling function is async."
|
|
329
376
|
);
|
|
330
|
-
this.runs.set(runIdToUse, run);
|
|
331
|
-
return run;
|
|
332
377
|
}
|
|
333
378
|
async createRunAsync(options) {
|
|
334
379
|
const runIdToUse = options?.runId || crypto.randomUUID();
|
|
@@ -336,21 +381,28 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
336
381
|
{
|
|
337
382
|
workflowId: this.id,
|
|
338
383
|
runId: runIdToUse,
|
|
384
|
+
resourceId: options?.resourceId,
|
|
339
385
|
executionEngine: this.executionEngine,
|
|
340
386
|
executionGraph: this.executionGraph,
|
|
341
387
|
serializedStepGraph: this.serializedStepGraph,
|
|
342
388
|
mastra: this.#mastra,
|
|
343
389
|
retryConfig: this.retryConfig,
|
|
344
|
-
cleanup: () => this.runs.delete(runIdToUse)
|
|
390
|
+
cleanup: () => this.runs.delete(runIdToUse),
|
|
391
|
+
workflowSteps: this.steps
|
|
345
392
|
},
|
|
346
393
|
this.inngest
|
|
347
394
|
);
|
|
348
395
|
this.runs.set(runIdToUse, run);
|
|
396
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
|
|
397
|
+
workflowStatus: run.workflowRunStatus,
|
|
398
|
+
stepResults: {}
|
|
399
|
+
});
|
|
349
400
|
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
|
|
350
|
-
if (!workflowSnapshotInStorage) {
|
|
401
|
+
if (!workflowSnapshotInStorage && shouldPersistSnapshot) {
|
|
351
402
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
352
403
|
workflowName: this.id,
|
|
353
404
|
runId: runIdToUse,
|
|
405
|
+
resourceId: options?.resourceId,
|
|
354
406
|
snapshot: {
|
|
355
407
|
runId: runIdToUse,
|
|
356
408
|
status: "pending",
|
|
@@ -360,6 +412,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
360
412
|
waitingPaths: {},
|
|
361
413
|
serializedStepGraph: this.serializedStepGraph,
|
|
362
414
|
suspendedPaths: {},
|
|
415
|
+
resumeLabels: {},
|
|
363
416
|
result: void 0,
|
|
364
417
|
error: void 0,
|
|
365
418
|
// @ts-ignore
|
|
@@ -384,7 +437,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
384
437
|
},
|
|
385
438
|
{ event: `workflow.${this.id}` },
|
|
386
439
|
async ({ event, step, attempt, publish }) => {
|
|
387
|
-
let { inputData, runId, resume } = event.data;
|
|
440
|
+
let { inputData, initialState, runId, resourceId, resume, outputOptions } = event.data;
|
|
388
441
|
if (!runId) {
|
|
389
442
|
runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
|
|
390
443
|
return crypto.randomUUID();
|
|
@@ -412,21 +465,32 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
412
465
|
once: (_event, _callback) => {
|
|
413
466
|
}
|
|
414
467
|
};
|
|
415
|
-
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
468
|
+
const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
|
|
416
469
|
const result = await engine.execute({
|
|
417
470
|
workflowId: this.id,
|
|
418
471
|
runId,
|
|
472
|
+
resourceId,
|
|
419
473
|
graph: this.executionGraph,
|
|
420
474
|
serializedStepGraph: this.serializedStepGraph,
|
|
421
475
|
input: inputData,
|
|
476
|
+
initialState,
|
|
422
477
|
emitter,
|
|
423
478
|
retryConfig: this.retryConfig,
|
|
424
479
|
runtimeContext: new di.RuntimeContext(),
|
|
425
480
|
// TODO
|
|
426
481
|
resume,
|
|
427
482
|
abortController: new AbortController(),
|
|
428
|
-
currentSpan: void 0
|
|
483
|
+
currentSpan: void 0,
|
|
429
484
|
// TODO: Pass actual parent AI span from workflow execution context
|
|
485
|
+
outputOptions
|
|
486
|
+
});
|
|
487
|
+
await step.run(`workflow.${this.id}.finalize`, async () => {
|
|
488
|
+
if (result.status === "failed") {
|
|
489
|
+
throw new inngest.NonRetriableError(`Workflow failed`, {
|
|
490
|
+
cause: result
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
return result;
|
|
430
494
|
});
|
|
431
495
|
return { result, runId };
|
|
432
496
|
}
|
|
@@ -460,11 +524,10 @@ function createStep(params) {
|
|
|
460
524
|
if (isAgent(params)) {
|
|
461
525
|
return {
|
|
462
526
|
id: params.name,
|
|
527
|
+
description: params.getDescription(),
|
|
463
528
|
// @ts-ignore
|
|
464
529
|
inputSchema: zod.z.object({
|
|
465
530
|
prompt: zod.z.string()
|
|
466
|
-
// resourceId: z.string().optional(),
|
|
467
|
-
// threadId: z.string().optional(),
|
|
468
531
|
}),
|
|
469
532
|
// @ts-ignore
|
|
470
533
|
outputSchema: zod.z.object({
|
|
@@ -480,34 +543,66 @@ function createStep(params) {
|
|
|
480
543
|
name: params.name,
|
|
481
544
|
args: inputData
|
|
482
545
|
};
|
|
483
|
-
await
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
546
|
+
if ((await params.getLLM()).getModel().specificationVersion === `v2`) {
|
|
547
|
+
const { fullStream } = await params.stream(inputData.prompt, {
|
|
548
|
+
runtimeContext,
|
|
549
|
+
tracingContext,
|
|
550
|
+
onFinish: (result) => {
|
|
551
|
+
streamPromise.resolve(result.text);
|
|
552
|
+
},
|
|
553
|
+
abortSignal
|
|
554
|
+
});
|
|
555
|
+
if (abortSignal.aborted) {
|
|
556
|
+
return abort();
|
|
557
|
+
}
|
|
558
|
+
await emitter.emit("watch-v2", {
|
|
559
|
+
type: "tool-call-streaming-start",
|
|
560
|
+
...toolData ?? {}
|
|
561
|
+
});
|
|
562
|
+
for await (const chunk of fullStream) {
|
|
563
|
+
if (chunk.type === "text-delta") {
|
|
564
|
+
await emitter.emit("watch-v2", {
|
|
565
|
+
type: "tool-call-delta",
|
|
566
|
+
...toolData ?? {},
|
|
567
|
+
argsTextDelta: chunk.payload.text
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
} else {
|
|
572
|
+
const { fullStream } = await params.streamLegacy(inputData.prompt, {
|
|
573
|
+
runtimeContext,
|
|
574
|
+
tracingContext,
|
|
575
|
+
onFinish: (result) => {
|
|
576
|
+
streamPromise.resolve(result.text);
|
|
577
|
+
},
|
|
578
|
+
abortSignal
|
|
579
|
+
});
|
|
580
|
+
if (abortSignal.aborted) {
|
|
581
|
+
return abort();
|
|
582
|
+
}
|
|
583
|
+
await emitter.emit("watch-v2", {
|
|
584
|
+
type: "tool-call-streaming-start",
|
|
585
|
+
...toolData ?? {}
|
|
586
|
+
});
|
|
587
|
+
for await (const chunk of fullStream) {
|
|
588
|
+
if (chunk.type === "text-delta") {
|
|
589
|
+
await emitter.emit("watch-v2", {
|
|
590
|
+
type: "tool-call-delta",
|
|
591
|
+
...toolData ?? {},
|
|
592
|
+
argsTextDelta: chunk.textDelta
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
}
|
|
502
596
|
}
|
|
503
597
|
await emitter.emit("watch-v2", {
|
|
504
|
-
type: "
|
|
505
|
-
|
|
598
|
+
type: "tool-call-streaming-finish",
|
|
599
|
+
...toolData ?? {}
|
|
506
600
|
});
|
|
507
601
|
return {
|
|
508
602
|
text: await streamPromise.promise
|
|
509
603
|
};
|
|
510
|
-
}
|
|
604
|
+
},
|
|
605
|
+
component: params.component
|
|
511
606
|
};
|
|
512
607
|
}
|
|
513
608
|
if (isTool(params)) {
|
|
@@ -518,16 +613,20 @@ function createStep(params) {
|
|
|
518
613
|
// TODO: tool probably should have strong id type
|
|
519
614
|
// @ts-ignore
|
|
520
615
|
id: params.id,
|
|
616
|
+
description: params.description,
|
|
521
617
|
inputSchema: params.inputSchema,
|
|
522
618
|
outputSchema: params.outputSchema,
|
|
523
|
-
execute: async ({ inputData, mastra, runtimeContext, tracingContext }) => {
|
|
619
|
+
execute: async ({ inputData, mastra, runtimeContext, tracingContext, suspend, resumeData }) => {
|
|
524
620
|
return params.execute({
|
|
525
621
|
context: inputData,
|
|
526
622
|
mastra: aiTracing.wrapMastra(mastra, tracingContext),
|
|
527
623
|
runtimeContext,
|
|
528
|
-
tracingContext
|
|
624
|
+
tracingContext,
|
|
625
|
+
suspend,
|
|
626
|
+
resumeData
|
|
529
627
|
});
|
|
530
|
-
}
|
|
628
|
+
},
|
|
629
|
+
component: "TOOL"
|
|
531
630
|
};
|
|
532
631
|
}
|
|
533
632
|
return {
|
|
@@ -543,7 +642,10 @@ function createStep(params) {
|
|
|
543
642
|
function init(inngest) {
|
|
544
643
|
return {
|
|
545
644
|
createWorkflow(params) {
|
|
546
|
-
return new InngestWorkflow(
|
|
645
|
+
return new InngestWorkflow(
|
|
646
|
+
params,
|
|
647
|
+
inngest
|
|
648
|
+
);
|
|
547
649
|
},
|
|
548
650
|
createStep,
|
|
549
651
|
cloneStep(step, opts) {
|
|
@@ -552,7 +654,11 @@ function init(inngest) {
|
|
|
552
654
|
description: step.description,
|
|
553
655
|
inputSchema: step.inputSchema,
|
|
554
656
|
outputSchema: step.outputSchema,
|
|
555
|
-
|
|
657
|
+
resumeSchema: step.resumeSchema,
|
|
658
|
+
suspendSchema: step.suspendSchema,
|
|
659
|
+
stateSchema: step.stateSchema,
|
|
660
|
+
execute: step.execute,
|
|
661
|
+
component: step.component
|
|
556
662
|
};
|
|
557
663
|
},
|
|
558
664
|
cloneWorkflow(workflow, opts) {
|
|
@@ -572,8 +678,8 @@ function init(inngest) {
|
|
|
572
678
|
var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
573
679
|
inngestStep;
|
|
574
680
|
inngestAttempts;
|
|
575
|
-
constructor(mastra, inngestStep, inngestAttempts = 0) {
|
|
576
|
-
super({ mastra });
|
|
681
|
+
constructor(mastra, inngestStep, inngestAttempts = 0, options) {
|
|
682
|
+
super({ mastra, options });
|
|
577
683
|
this.inngestStep = inngestStep;
|
|
578
684
|
this.inngestAttempts = inngestAttempts;
|
|
579
685
|
}
|
|
@@ -636,7 +742,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
636
742
|
});
|
|
637
743
|
const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
|
|
638
744
|
if (stepResult?.status === "suspended") {
|
|
639
|
-
const nestedPath = stepResult?.
|
|
745
|
+
const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
|
|
640
746
|
return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
|
|
641
747
|
}
|
|
642
748
|
return [];
|
|
@@ -669,7 +775,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
669
775
|
attributes: {
|
|
670
776
|
durationMs: duration,
|
|
671
777
|
sleepType: fn ? "dynamic" : "fixed"
|
|
672
|
-
}
|
|
778
|
+
},
|
|
779
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
673
780
|
});
|
|
674
781
|
if (fn) {
|
|
675
782
|
const stepCallId = crypto.randomUUID();
|
|
@@ -680,21 +787,16 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
680
787
|
mastra: this.mastra,
|
|
681
788
|
runtimeContext,
|
|
682
789
|
inputData: prevOutput,
|
|
790
|
+
state: executionContext.state,
|
|
791
|
+
setState: (state) => {
|
|
792
|
+
executionContext.state = state;
|
|
793
|
+
},
|
|
683
794
|
runCount: -1,
|
|
684
795
|
tracingContext: {
|
|
685
796
|
currentSpan: sleepSpan
|
|
686
797
|
},
|
|
687
798
|
getInitData: () => stepResults?.input,
|
|
688
|
-
getStepResult: (
|
|
689
|
-
if (!step?.id) {
|
|
690
|
-
return null;
|
|
691
|
-
}
|
|
692
|
-
const result = stepResults[step.id];
|
|
693
|
-
if (result?.status === "success") {
|
|
694
|
-
return result.output;
|
|
695
|
-
}
|
|
696
|
-
return null;
|
|
697
|
-
},
|
|
799
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
698
800
|
// TODO: this function shouldn't have suspend probably?
|
|
699
801
|
suspend: async (_suspendPayload) => {
|
|
700
802
|
},
|
|
@@ -754,7 +856,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
754
856
|
untilDate: date,
|
|
755
857
|
durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
|
|
756
858
|
sleepType: fn ? "dynamic" : "fixed"
|
|
757
|
-
}
|
|
859
|
+
},
|
|
860
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
758
861
|
});
|
|
759
862
|
if (fn) {
|
|
760
863
|
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
@@ -765,21 +868,16 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
765
868
|
mastra: this.mastra,
|
|
766
869
|
runtimeContext,
|
|
767
870
|
inputData: prevOutput,
|
|
871
|
+
state: executionContext.state,
|
|
872
|
+
setState: (state) => {
|
|
873
|
+
executionContext.state = state;
|
|
874
|
+
},
|
|
768
875
|
runCount: -1,
|
|
769
876
|
tracingContext: {
|
|
770
877
|
currentSpan: sleepUntilSpan
|
|
771
878
|
},
|
|
772
879
|
getInitData: () => stepResults?.input,
|
|
773
|
-
getStepResult: (
|
|
774
|
-
if (!step?.id) {
|
|
775
|
-
return null;
|
|
776
|
-
}
|
|
777
|
-
const result = stepResults[step.id];
|
|
778
|
-
if (result?.status === "success") {
|
|
779
|
-
return result.output;
|
|
780
|
-
}
|
|
781
|
-
return null;
|
|
782
|
-
},
|
|
880
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
783
881
|
// TODO: this function shouldn't have suspend probably?
|
|
784
882
|
suspend: async (_suspendPayload) => {
|
|
785
883
|
},
|
|
@@ -804,6 +902,9 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
804
902
|
)
|
|
805
903
|
});
|
|
806
904
|
});
|
|
905
|
+
if (date && !(date instanceof Date)) {
|
|
906
|
+
date = new Date(date);
|
|
907
|
+
}
|
|
807
908
|
const time = !date ? 0 : date.getTime() - Date.now();
|
|
808
909
|
sleepUntilSpan?.update({
|
|
809
910
|
attributes: {
|
|
@@ -852,7 +953,13 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
852
953
|
input: prevOutput,
|
|
853
954
|
attributes: {
|
|
854
955
|
stepId: step.id
|
|
855
|
-
}
|
|
956
|
+
},
|
|
957
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
958
|
+
});
|
|
959
|
+
const { inputData, validationError } = await workflows.validateStepInput({
|
|
960
|
+
prevOutput,
|
|
961
|
+
step,
|
|
962
|
+
validateInputs: this.options?.validateInputs ?? false
|
|
856
963
|
});
|
|
857
964
|
const startedAt = await this.inngestStep.run(
|
|
858
965
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
@@ -884,7 +991,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
884
991
|
payload: {
|
|
885
992
|
id: step.id,
|
|
886
993
|
status: "running",
|
|
887
|
-
payload:
|
|
994
|
+
payload: inputData,
|
|
888
995
|
startedAt: startedAt2
|
|
889
996
|
}
|
|
890
997
|
});
|
|
@@ -895,38 +1002,60 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
895
1002
|
const isResume = !!resume?.steps?.length;
|
|
896
1003
|
let result;
|
|
897
1004
|
let runId;
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
1005
|
+
try {
|
|
1006
|
+
if (isResume) {
|
|
1007
|
+
runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
1008
|
+
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
1009
|
+
workflowName: step.id,
|
|
1010
|
+
runId
|
|
1011
|
+
});
|
|
1012
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1013
|
+
function: step.getFunction(),
|
|
1014
|
+
data: {
|
|
1015
|
+
inputData,
|
|
1016
|
+
initialState: executionContext.state ?? snapshot?.value ?? {},
|
|
910
1017
|
runId,
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
1018
|
+
resume: {
|
|
1019
|
+
runId,
|
|
1020
|
+
steps: resume.steps.slice(1),
|
|
1021
|
+
stepResults: snapshot?.context,
|
|
1022
|
+
resumePayload: resume.resumePayload,
|
|
1023
|
+
// @ts-ignore
|
|
1024
|
+
resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
|
|
1025
|
+
},
|
|
1026
|
+
outputOptions: { includeState: true }
|
|
916
1027
|
}
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
1028
|
+
});
|
|
1029
|
+
result = invokeResp.result;
|
|
1030
|
+
runId = invokeResp.runId;
|
|
1031
|
+
executionContext.state = invokeResp.result.state;
|
|
1032
|
+
} else {
|
|
1033
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1034
|
+
function: step.getFunction(),
|
|
1035
|
+
data: {
|
|
1036
|
+
inputData,
|
|
1037
|
+
initialState: executionContext.state ?? {},
|
|
1038
|
+
outputOptions: { includeState: true }
|
|
1039
|
+
}
|
|
1040
|
+
});
|
|
1041
|
+
result = invokeResp.result;
|
|
1042
|
+
runId = invokeResp.runId;
|
|
1043
|
+
executionContext.state = invokeResp.result.state;
|
|
1044
|
+
}
|
|
1045
|
+
} catch (e) {
|
|
1046
|
+
const errorCause = e?.cause;
|
|
1047
|
+
if (errorCause && typeof errorCause === "object") {
|
|
1048
|
+
result = errorCause;
|
|
1049
|
+
runId = errorCause.runId || crypto.randomUUID();
|
|
1050
|
+
} else {
|
|
1051
|
+
runId = crypto.randomUUID();
|
|
1052
|
+
result = {
|
|
1053
|
+
status: "failed",
|
|
1054
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
1055
|
+
steps: {},
|
|
1056
|
+
input: inputData
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
930
1059
|
}
|
|
931
1060
|
const res = await this.inngestStep.run(
|
|
932
1061
|
`workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
|
|
@@ -965,7 +1094,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
965
1094
|
return stepRes2?.status === "suspended";
|
|
966
1095
|
});
|
|
967
1096
|
for (const [stepName, stepResult] of suspendedSteps) {
|
|
968
|
-
const suspendPath = [stepName, ...stepResult?.
|
|
1097
|
+
const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
|
|
969
1098
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
970
1099
|
await emitter.emit("watch", {
|
|
971
1100
|
type: "watch",
|
|
@@ -973,7 +1102,11 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
973
1102
|
currentStep: {
|
|
974
1103
|
id: step.id,
|
|
975
1104
|
status: "suspended",
|
|
976
|
-
payload:
|
|
1105
|
+
payload: stepResult.payload,
|
|
1106
|
+
suspendPayload: {
|
|
1107
|
+
...stepResult?.suspendPayload,
|
|
1108
|
+
__workflow_meta: { runId, path: suspendPath }
|
|
1109
|
+
}
|
|
977
1110
|
},
|
|
978
1111
|
workflowState: {
|
|
979
1112
|
status: "running",
|
|
@@ -995,7 +1128,11 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
995
1128
|
executionContext,
|
|
996
1129
|
result: {
|
|
997
1130
|
status: "suspended",
|
|
998
|
-
payload:
|
|
1131
|
+
payload: stepResult.payload,
|
|
1132
|
+
suspendPayload: {
|
|
1133
|
+
...stepResult?.suspendPayload,
|
|
1134
|
+
__workflow_meta: { runId, path: suspendPath }
|
|
1135
|
+
}
|
|
999
1136
|
}
|
|
1000
1137
|
};
|
|
1001
1138
|
}
|
|
@@ -1060,141 +1197,182 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1060
1197
|
}
|
|
1061
1198
|
);
|
|
1062
1199
|
Object.assign(executionContext, res.executionContext);
|
|
1063
|
-
return
|
|
1200
|
+
return {
|
|
1201
|
+
...res.result,
|
|
1202
|
+
startedAt,
|
|
1203
|
+
endedAt: Date.now(),
|
|
1204
|
+
payload: inputData,
|
|
1205
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1206
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1207
|
+
};
|
|
1064
1208
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1209
|
+
let stepRes;
|
|
1210
|
+
try {
|
|
1211
|
+
stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
1212
|
+
let execResults;
|
|
1213
|
+
let suspended;
|
|
1214
|
+
let bailed;
|
|
1215
|
+
try {
|
|
1216
|
+
if (validationError) {
|
|
1217
|
+
throw validationError;
|
|
1218
|
+
}
|
|
1219
|
+
const result = await step.execute({
|
|
1220
|
+
runId: executionContext.runId,
|
|
1221
|
+
mastra: this.mastra,
|
|
1222
|
+
runtimeContext,
|
|
1223
|
+
writableStream,
|
|
1224
|
+
state: executionContext?.state ?? {},
|
|
1225
|
+
setState: (state) => {
|
|
1226
|
+
executionContext.state = state;
|
|
1227
|
+
},
|
|
1228
|
+
inputData,
|
|
1229
|
+
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
|
|
1230
|
+
tracingContext: {
|
|
1231
|
+
currentSpan: stepAISpan
|
|
1232
|
+
},
|
|
1233
|
+
getInitData: () => stepResults?.input,
|
|
1234
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1235
|
+
suspend: async (suspendPayload, suspendOptions) => {
|
|
1236
|
+
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1237
|
+
if (suspendOptions?.resumeLabel) {
|
|
1238
|
+
const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
|
|
1239
|
+
for (const label of resumeLabel) {
|
|
1240
|
+
executionContext.resumeLabels[label] = {
|
|
1241
|
+
stepId: step.id,
|
|
1242
|
+
foreachIndex: executionContext.foreachIndex
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
suspended = { payload: suspendPayload };
|
|
1247
|
+
},
|
|
1248
|
+
bail: (result2) => {
|
|
1249
|
+
bailed = { payload: result2 };
|
|
1250
|
+
},
|
|
1251
|
+
resume: {
|
|
1252
|
+
steps: resume?.steps?.slice(1) || [],
|
|
1253
|
+
resumePayload: resume?.resumePayload,
|
|
1254
|
+
// @ts-ignore
|
|
1255
|
+
runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
|
|
1256
|
+
},
|
|
1257
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1258
|
+
engine: {
|
|
1259
|
+
step: this.inngestStep
|
|
1260
|
+
},
|
|
1261
|
+
abortSignal: abortController.signal
|
|
1262
|
+
});
|
|
1263
|
+
const endedAt = Date.now();
|
|
1264
|
+
execResults = {
|
|
1265
|
+
status: "success",
|
|
1266
|
+
output: result,
|
|
1267
|
+
startedAt,
|
|
1268
|
+
endedAt,
|
|
1269
|
+
payload: inputData,
|
|
1270
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1271
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1272
|
+
};
|
|
1273
|
+
} catch (e) {
|
|
1274
|
+
const stepFailure = {
|
|
1275
|
+
status: "failed",
|
|
1276
|
+
payload: inputData,
|
|
1277
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1278
|
+
endedAt: Date.now(),
|
|
1279
|
+
startedAt,
|
|
1280
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1281
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1282
|
+
};
|
|
1283
|
+
execResults = stepFailure;
|
|
1284
|
+
const fallbackErrorMessage = `Step ${step.id} failed`;
|
|
1285
|
+
stepAISpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
|
|
1286
|
+
throw new inngest.RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
|
|
1287
|
+
cause: execResults
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
if (suspended) {
|
|
1291
|
+
execResults = {
|
|
1292
|
+
status: "suspended",
|
|
1293
|
+
suspendPayload: suspended.payload,
|
|
1294
|
+
payload: inputData,
|
|
1295
|
+
suspendedAt: Date.now(),
|
|
1296
|
+
startedAt,
|
|
1297
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1298
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1299
|
+
};
|
|
1300
|
+
} else if (bailed) {
|
|
1301
|
+
execResults = {
|
|
1302
|
+
status: "bailed",
|
|
1303
|
+
output: bailed.payload,
|
|
1304
|
+
payload: inputData,
|
|
1305
|
+
endedAt: Date.now(),
|
|
1306
|
+
startedAt
|
|
1307
|
+
};
|
|
1308
|
+
}
|
|
1309
|
+
await emitter.emit("watch", {
|
|
1310
|
+
type: "watch",
|
|
1311
|
+
payload: {
|
|
1312
|
+
currentStep: {
|
|
1313
|
+
id: step.id,
|
|
1314
|
+
...execResults
|
|
1315
|
+
},
|
|
1316
|
+
workflowState: {
|
|
1317
|
+
status: "running",
|
|
1318
|
+
steps: { ...stepResults, [step.id]: execResults },
|
|
1319
|
+
result: null,
|
|
1320
|
+
error: null
|
|
1085
1321
|
}
|
|
1086
|
-
return null;
|
|
1087
|
-
},
|
|
1088
|
-
suspend: async (suspendPayload) => {
|
|
1089
|
-
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1090
|
-
suspended = { payload: suspendPayload };
|
|
1091
|
-
},
|
|
1092
|
-
bail: (result2) => {
|
|
1093
|
-
bailed = { payload: result2 };
|
|
1094
|
-
},
|
|
1095
|
-
resume: {
|
|
1096
|
-
steps: resume?.steps?.slice(1) || [],
|
|
1097
|
-
resumePayload: resume?.resumePayload,
|
|
1098
|
-
// @ts-ignore
|
|
1099
|
-
runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
|
|
1100
|
-
},
|
|
1101
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1102
|
-
engine: {
|
|
1103
|
-
step: this.inngestStep
|
|
1104
1322
|
},
|
|
1105
|
-
|
|
1323
|
+
eventTimestamp: Date.now()
|
|
1106
1324
|
});
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
status: "suspended",
|
|
1131
|
-
suspendedPayload: suspended.payload,
|
|
1132
|
-
payload: prevOutput,
|
|
1133
|
-
suspendedAt: Date.now(),
|
|
1134
|
-
startedAt,
|
|
1135
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1136
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1137
|
-
};
|
|
1138
|
-
} else if (bailed) {
|
|
1139
|
-
execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
1140
|
-
}
|
|
1141
|
-
if (execResults.status === "failed") {
|
|
1142
|
-
if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
|
|
1143
|
-
const error = new Error(execResults.error);
|
|
1144
|
-
stepAISpan?.error({ error });
|
|
1145
|
-
throw error;
|
|
1325
|
+
if (execResults.status === "suspended") {
|
|
1326
|
+
await emitter.emit("watch-v2", {
|
|
1327
|
+
type: "workflow-step-suspended",
|
|
1328
|
+
payload: {
|
|
1329
|
+
id: step.id,
|
|
1330
|
+
...execResults
|
|
1331
|
+
}
|
|
1332
|
+
});
|
|
1333
|
+
} else {
|
|
1334
|
+
await emitter.emit("watch-v2", {
|
|
1335
|
+
type: "workflow-step-result",
|
|
1336
|
+
payload: {
|
|
1337
|
+
id: step.id,
|
|
1338
|
+
...execResults
|
|
1339
|
+
}
|
|
1340
|
+
});
|
|
1341
|
+
await emitter.emit("watch-v2", {
|
|
1342
|
+
type: "workflow-step-finish",
|
|
1343
|
+
payload: {
|
|
1344
|
+
id: step.id,
|
|
1345
|
+
metadata: {}
|
|
1346
|
+
}
|
|
1347
|
+
});
|
|
1146
1348
|
}
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
type: "watch",
|
|
1150
|
-
payload: {
|
|
1151
|
-
currentStep: {
|
|
1152
|
-
id: step.id,
|
|
1153
|
-
...execResults
|
|
1154
|
-
},
|
|
1155
|
-
workflowState: {
|
|
1156
|
-
status: "running",
|
|
1157
|
-
steps: { ...stepResults, [step.id]: execResults },
|
|
1158
|
-
result: null,
|
|
1159
|
-
error: null
|
|
1160
|
-
}
|
|
1161
|
-
},
|
|
1162
|
-
eventTimestamp: Date.now()
|
|
1349
|
+
stepAISpan?.end({ output: execResults });
|
|
1350
|
+
return { result: execResults, executionContext, stepResults };
|
|
1163
1351
|
});
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
payload: {
|
|
1183
|
-
id: step.id,
|
|
1184
|
-
metadata: {}
|
|
1185
|
-
}
|
|
1186
|
-
});
|
|
1187
|
-
}
|
|
1188
|
-
stepAISpan?.end({ output: execResults });
|
|
1189
|
-
return { result: execResults, executionContext, stepResults };
|
|
1190
|
-
});
|
|
1191
|
-
if (disableScorers !== false) {
|
|
1352
|
+
} catch (e) {
|
|
1353
|
+
const stepFailure = e instanceof Error ? e?.cause : {
|
|
1354
|
+
status: "failed",
|
|
1355
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1356
|
+
payload: inputData,
|
|
1357
|
+
startedAt,
|
|
1358
|
+
endedAt: Date.now()
|
|
1359
|
+
};
|
|
1360
|
+
stepRes = {
|
|
1361
|
+
result: stepFailure,
|
|
1362
|
+
executionContext,
|
|
1363
|
+
stepResults: {
|
|
1364
|
+
...stepResults,
|
|
1365
|
+
[step.id]: stepFailure
|
|
1366
|
+
}
|
|
1367
|
+
};
|
|
1368
|
+
}
|
|
1369
|
+
if (disableScorers !== false && stepRes.result.status === "success") {
|
|
1192
1370
|
await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
|
|
1193
1371
|
if (step.scorers) {
|
|
1194
1372
|
await this.runScorers({
|
|
1195
1373
|
scorers: step.scorers,
|
|
1196
1374
|
runId: executionContext.runId,
|
|
1197
|
-
input:
|
|
1375
|
+
input: inputData,
|
|
1198
1376
|
output: stepRes.result,
|
|
1199
1377
|
workflowId: executionContext.workflowId,
|
|
1200
1378
|
stepId: step.id,
|
|
@@ -1207,12 +1385,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1207
1385
|
}
|
|
1208
1386
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
1209
1387
|
Object.assign(stepResults, stepRes.stepResults);
|
|
1388
|
+
executionContext.state = stepRes.executionContext.state;
|
|
1210
1389
|
return stepRes.result;
|
|
1211
1390
|
}
|
|
1212
1391
|
async persistStepUpdate({
|
|
1213
1392
|
workflowId,
|
|
1214
1393
|
runId,
|
|
1215
1394
|
stepResults,
|
|
1395
|
+
resourceId,
|
|
1216
1396
|
executionContext,
|
|
1217
1397
|
serializedStepGraph,
|
|
1218
1398
|
workflowStatus,
|
|
@@ -1222,15 +1402,21 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1222
1402
|
await this.inngestStep.run(
|
|
1223
1403
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
1224
1404
|
async () => {
|
|
1405
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({ stepResults, workflowStatus });
|
|
1406
|
+
if (!shouldPersistSnapshot) {
|
|
1407
|
+
return;
|
|
1408
|
+
}
|
|
1225
1409
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
1226
1410
|
workflowName: workflowId,
|
|
1227
1411
|
runId,
|
|
1412
|
+
resourceId,
|
|
1228
1413
|
snapshot: {
|
|
1229
1414
|
runId,
|
|
1230
|
-
value:
|
|
1415
|
+
value: executionContext.state,
|
|
1231
1416
|
context: stepResults,
|
|
1232
1417
|
activePaths: [],
|
|
1233
1418
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1419
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1234
1420
|
waitingPaths: {},
|
|
1235
1421
|
serializedStepGraph,
|
|
1236
1422
|
status: workflowStatus,
|
|
@@ -1266,7 +1452,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1266
1452
|
input: prevOutput,
|
|
1267
1453
|
attributes: {
|
|
1268
1454
|
conditionCount: entry.conditions.length
|
|
1269
|
-
}
|
|
1455
|
+
},
|
|
1456
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1270
1457
|
});
|
|
1271
1458
|
let execResults;
|
|
1272
1459
|
const truthyIndexes = (await Promise.all(
|
|
@@ -1278,7 +1465,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1278
1465
|
input: prevOutput,
|
|
1279
1466
|
attributes: {
|
|
1280
1467
|
conditionIndex: index
|
|
1281
|
-
}
|
|
1468
|
+
},
|
|
1469
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1282
1470
|
});
|
|
1283
1471
|
try {
|
|
1284
1472
|
const result = await cond({
|
|
@@ -1288,20 +1476,15 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1288
1476
|
runtimeContext,
|
|
1289
1477
|
runCount: -1,
|
|
1290
1478
|
inputData: prevOutput,
|
|
1479
|
+
state: executionContext.state,
|
|
1480
|
+
setState: (state) => {
|
|
1481
|
+
executionContext.state = state;
|
|
1482
|
+
},
|
|
1291
1483
|
tracingContext: {
|
|
1292
1484
|
currentSpan: evalSpan
|
|
1293
1485
|
},
|
|
1294
1486
|
getInitData: () => stepResults?.input,
|
|
1295
|
-
getStepResult: (
|
|
1296
|
-
if (!step?.id) {
|
|
1297
|
-
return null;
|
|
1298
|
-
}
|
|
1299
|
-
const result2 = stepResults[step.id];
|
|
1300
|
-
if (result2?.status === "success") {
|
|
1301
|
-
return result2.output;
|
|
1302
|
-
}
|
|
1303
|
-
return null;
|
|
1304
|
-
},
|
|
1487
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1305
1488
|
// TODO: this function shouldn't have suspend probably?
|
|
1306
1489
|
suspend: async (_suspendPayload) => {
|
|
1307
1490
|
},
|
|
@@ -1368,8 +1551,10 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1368
1551
|
runId,
|
|
1369
1552
|
executionPath: [...executionContext.executionPath, index],
|
|
1370
1553
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1554
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1371
1555
|
retryConfig: executionContext.retryConfig,
|
|
1372
|
-
executionSpan: executionContext.executionSpan
|
|
1556
|
+
executionSpan: executionContext.executionSpan,
|
|
1557
|
+
state: executionContext.state
|
|
1373
1558
|
},
|
|
1374
1559
|
emitter,
|
|
1375
1560
|
abortController,
|
|
@@ -1387,7 +1572,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1387
1572
|
if (hasFailed) {
|
|
1388
1573
|
execResults = { status: "failed", error: hasFailed.result.error };
|
|
1389
1574
|
} else if (hasSuspended) {
|
|
1390
|
-
execResults = { status: "suspended",
|
|
1575
|
+
execResults = { status: "suspended", suspendPayload: hasSuspended.result.suspendPayload };
|
|
1391
1576
|
} else {
|
|
1392
1577
|
execResults = {
|
|
1393
1578
|
status: "success",
|