@mastra/inngest 0.0.0-pgvector-index-fix-20250905222058 → 0.0.0-playground-studio-cloud-20251031080052
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 +378 -10
- package/dist/index.cjs +597 -384
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +74 -41
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +598 -385
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
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 = stream.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
|
}
|
|
@@ -589,7 +695,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
589
695
|
});
|
|
590
696
|
return result;
|
|
591
697
|
}
|
|
592
|
-
async fmtReturnValue(
|
|
698
|
+
async fmtReturnValue(emitter, stepResults, lastOutput, error) {
|
|
593
699
|
const base = {
|
|
594
700
|
status: lastOutput.status,
|
|
595
701
|
steps: stepResults
|
|
@@ -636,14 +742,13 @@ 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 [];
|
|
643
749
|
});
|
|
644
750
|
base.suspended = suspendedStepIds;
|
|
645
751
|
}
|
|
646
|
-
executionSpan?.end();
|
|
647
752
|
return base;
|
|
648
753
|
}
|
|
649
754
|
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
@@ -669,55 +774,61 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
669
774
|
attributes: {
|
|
670
775
|
durationMs: duration,
|
|
671
776
|
sleepType: fn ? "dynamic" : "fixed"
|
|
672
|
-
}
|
|
777
|
+
},
|
|
778
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
673
779
|
});
|
|
674
780
|
if (fn) {
|
|
675
781
|
const stepCallId = crypto.randomUUID();
|
|
676
782
|
duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
|
|
677
|
-
return await fn(
|
|
678
|
-
|
|
679
|
-
workflowId,
|
|
680
|
-
mastra: this.mastra,
|
|
681
|
-
runtimeContext,
|
|
682
|
-
inputData: prevOutput,
|
|
683
|
-
runCount: -1,
|
|
684
|
-
tracingContext: {
|
|
685
|
-
currentSpan: sleepSpan
|
|
686
|
-
},
|
|
687
|
-
getInitData: () => stepResults?.input,
|
|
688
|
-
getStepResult: (step) => {
|
|
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
|
-
},
|
|
698
|
-
// TODO: this function shouldn't have suspend probably?
|
|
699
|
-
suspend: async (_suspendPayload) => {
|
|
700
|
-
},
|
|
701
|
-
bail: () => {
|
|
702
|
-
},
|
|
703
|
-
abort: () => {
|
|
704
|
-
abortController?.abort();
|
|
705
|
-
},
|
|
706
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
707
|
-
// TODO: add streamVNext support
|
|
708
|
-
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
709
|
-
engine: { step: this.inngestStep },
|
|
710
|
-
abortSignal: abortController?.signal,
|
|
711
|
-
writer: new tools.ToolStream(
|
|
783
|
+
return await fn(
|
|
784
|
+
workflows.createDeprecationProxy(
|
|
712
785
|
{
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
786
|
+
runId,
|
|
787
|
+
workflowId,
|
|
788
|
+
mastra: this.mastra,
|
|
789
|
+
runtimeContext,
|
|
790
|
+
inputData: prevOutput,
|
|
791
|
+
state: executionContext.state,
|
|
792
|
+
setState: (state) => {
|
|
793
|
+
executionContext.state = state;
|
|
794
|
+
},
|
|
795
|
+
runCount: -1,
|
|
796
|
+
retryCount: -1,
|
|
797
|
+
tracingContext: {
|
|
798
|
+
currentSpan: sleepSpan
|
|
799
|
+
},
|
|
800
|
+
getInitData: () => stepResults?.input,
|
|
801
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
802
|
+
// TODO: this function shouldn't have suspend probably?
|
|
803
|
+
suspend: async (_suspendPayload) => {
|
|
804
|
+
},
|
|
805
|
+
bail: () => {
|
|
806
|
+
},
|
|
807
|
+
abort: () => {
|
|
808
|
+
abortController?.abort();
|
|
809
|
+
},
|
|
810
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
811
|
+
// TODO: add streamVNext support
|
|
812
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
813
|
+
engine: { step: this.inngestStep },
|
|
814
|
+
abortSignal: abortController?.signal,
|
|
815
|
+
writer: new tools.ToolStream(
|
|
816
|
+
{
|
|
817
|
+
prefix: "workflow-step",
|
|
818
|
+
callId: stepCallId,
|
|
819
|
+
name: "sleep",
|
|
820
|
+
runId
|
|
821
|
+
},
|
|
822
|
+
writableStream
|
|
823
|
+
)
|
|
717
824
|
},
|
|
718
|
-
|
|
825
|
+
{
|
|
826
|
+
paramName: "runCount",
|
|
827
|
+
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
828
|
+
logger: this.logger
|
|
829
|
+
}
|
|
719
830
|
)
|
|
720
|
-
|
|
831
|
+
);
|
|
721
832
|
});
|
|
722
833
|
sleepSpan?.update({
|
|
723
834
|
attributes: {
|
|
@@ -754,56 +865,65 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
754
865
|
untilDate: date,
|
|
755
866
|
durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
|
|
756
867
|
sleepType: fn ? "dynamic" : "fixed"
|
|
757
|
-
}
|
|
868
|
+
},
|
|
869
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
758
870
|
});
|
|
759
871
|
if (fn) {
|
|
760
872
|
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
761
873
|
const stepCallId = crypto.randomUUID();
|
|
762
|
-
return await fn(
|
|
763
|
-
|
|
764
|
-
workflowId,
|
|
765
|
-
mastra: this.mastra,
|
|
766
|
-
runtimeContext,
|
|
767
|
-
inputData: prevOutput,
|
|
768
|
-
runCount: -1,
|
|
769
|
-
tracingContext: {
|
|
770
|
-
currentSpan: sleepUntilSpan
|
|
771
|
-
},
|
|
772
|
-
getInitData: () => stepResults?.input,
|
|
773
|
-
getStepResult: (step) => {
|
|
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
|
-
},
|
|
783
|
-
// TODO: this function shouldn't have suspend probably?
|
|
784
|
-
suspend: async (_suspendPayload) => {
|
|
785
|
-
},
|
|
786
|
-
bail: () => {
|
|
787
|
-
},
|
|
788
|
-
abort: () => {
|
|
789
|
-
abortController?.abort();
|
|
790
|
-
},
|
|
791
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
792
|
-
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
793
|
-
// TODO: add streamVNext support
|
|
794
|
-
engine: { step: this.inngestStep },
|
|
795
|
-
abortSignal: abortController?.signal,
|
|
796
|
-
writer: new tools.ToolStream(
|
|
874
|
+
return await fn(
|
|
875
|
+
workflows.createDeprecationProxy(
|
|
797
876
|
{
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
877
|
+
runId,
|
|
878
|
+
workflowId,
|
|
879
|
+
mastra: this.mastra,
|
|
880
|
+
runtimeContext,
|
|
881
|
+
inputData: prevOutput,
|
|
882
|
+
state: executionContext.state,
|
|
883
|
+
setState: (state) => {
|
|
884
|
+
executionContext.state = state;
|
|
885
|
+
},
|
|
886
|
+
runCount: -1,
|
|
887
|
+
retryCount: -1,
|
|
888
|
+
tracingContext: {
|
|
889
|
+
currentSpan: sleepUntilSpan
|
|
890
|
+
},
|
|
891
|
+
getInitData: () => stepResults?.input,
|
|
892
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
893
|
+
// TODO: this function shouldn't have suspend probably?
|
|
894
|
+
suspend: async (_suspendPayload) => {
|
|
895
|
+
},
|
|
896
|
+
bail: () => {
|
|
897
|
+
},
|
|
898
|
+
abort: () => {
|
|
899
|
+
abortController?.abort();
|
|
900
|
+
},
|
|
901
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
902
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
903
|
+
// TODO: add streamVNext support
|
|
904
|
+
engine: { step: this.inngestStep },
|
|
905
|
+
abortSignal: abortController?.signal,
|
|
906
|
+
writer: new tools.ToolStream(
|
|
907
|
+
{
|
|
908
|
+
prefix: "workflow-step",
|
|
909
|
+
callId: stepCallId,
|
|
910
|
+
name: "sleep",
|
|
911
|
+
runId
|
|
912
|
+
},
|
|
913
|
+
writableStream
|
|
914
|
+
)
|
|
802
915
|
},
|
|
803
|
-
|
|
916
|
+
{
|
|
917
|
+
paramName: "runCount",
|
|
918
|
+
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
919
|
+
logger: this.logger
|
|
920
|
+
}
|
|
804
921
|
)
|
|
805
|
-
|
|
922
|
+
);
|
|
806
923
|
});
|
|
924
|
+
if (date && !(date instanceof Date)) {
|
|
925
|
+
date = new Date(date);
|
|
926
|
+
}
|
|
807
927
|
const time = !date ? 0 : date.getTime() - Date.now();
|
|
808
928
|
sleepUntilSpan?.update({
|
|
809
929
|
attributes: {
|
|
@@ -852,7 +972,13 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
852
972
|
input: prevOutput,
|
|
853
973
|
attributes: {
|
|
854
974
|
stepId: step.id
|
|
855
|
-
}
|
|
975
|
+
},
|
|
976
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
977
|
+
});
|
|
978
|
+
const { inputData, validationError } = await workflows.validateStepInput({
|
|
979
|
+
prevOutput,
|
|
980
|
+
step,
|
|
981
|
+
validateInputs: this.options?.validateInputs ?? false
|
|
856
982
|
});
|
|
857
983
|
const startedAt = await this.inngestStep.run(
|
|
858
984
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
@@ -884,7 +1010,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
884
1010
|
payload: {
|
|
885
1011
|
id: step.id,
|
|
886
1012
|
status: "running",
|
|
887
|
-
payload:
|
|
1013
|
+
payload: inputData,
|
|
888
1014
|
startedAt: startedAt2
|
|
889
1015
|
}
|
|
890
1016
|
});
|
|
@@ -895,38 +1021,60 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
895
1021
|
const isResume = !!resume?.steps?.length;
|
|
896
1022
|
let result;
|
|
897
1023
|
let runId;
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
1024
|
+
try {
|
|
1025
|
+
if (isResume) {
|
|
1026
|
+
runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
1027
|
+
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
1028
|
+
workflowName: step.id,
|
|
1029
|
+
runId
|
|
1030
|
+
});
|
|
1031
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1032
|
+
function: step.getFunction(),
|
|
1033
|
+
data: {
|
|
1034
|
+
inputData,
|
|
1035
|
+
initialState: executionContext.state ?? snapshot?.value ?? {},
|
|
910
1036
|
runId,
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
1037
|
+
resume: {
|
|
1038
|
+
runId,
|
|
1039
|
+
steps: resume.steps.slice(1),
|
|
1040
|
+
stepResults: snapshot?.context,
|
|
1041
|
+
resumePayload: resume.resumePayload,
|
|
1042
|
+
// @ts-ignore
|
|
1043
|
+
resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
|
|
1044
|
+
},
|
|
1045
|
+
outputOptions: { includeState: true }
|
|
916
1046
|
}
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
1047
|
+
});
|
|
1048
|
+
result = invokeResp.result;
|
|
1049
|
+
runId = invokeResp.runId;
|
|
1050
|
+
executionContext.state = invokeResp.result.state;
|
|
1051
|
+
} else {
|
|
1052
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1053
|
+
function: step.getFunction(),
|
|
1054
|
+
data: {
|
|
1055
|
+
inputData,
|
|
1056
|
+
initialState: executionContext.state ?? {},
|
|
1057
|
+
outputOptions: { includeState: true }
|
|
1058
|
+
}
|
|
1059
|
+
});
|
|
1060
|
+
result = invokeResp.result;
|
|
1061
|
+
runId = invokeResp.runId;
|
|
1062
|
+
executionContext.state = invokeResp.result.state;
|
|
1063
|
+
}
|
|
1064
|
+
} catch (e) {
|
|
1065
|
+
const errorCause = e?.cause;
|
|
1066
|
+
if (errorCause && typeof errorCause === "object") {
|
|
1067
|
+
result = errorCause;
|
|
1068
|
+
runId = errorCause.runId || crypto.randomUUID();
|
|
1069
|
+
} else {
|
|
1070
|
+
runId = crypto.randomUUID();
|
|
1071
|
+
result = {
|
|
1072
|
+
status: "failed",
|
|
1073
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
1074
|
+
steps: {},
|
|
1075
|
+
input: inputData
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
930
1078
|
}
|
|
931
1079
|
const res = await this.inngestStep.run(
|
|
932
1080
|
`workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
|
|
@@ -965,7 +1113,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
965
1113
|
return stepRes2?.status === "suspended";
|
|
966
1114
|
});
|
|
967
1115
|
for (const [stepName, stepResult] of suspendedSteps) {
|
|
968
|
-
const suspendPath = [stepName, ...stepResult?.
|
|
1116
|
+
const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
|
|
969
1117
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
970
1118
|
await emitter.emit("watch", {
|
|
971
1119
|
type: "watch",
|
|
@@ -973,7 +1121,11 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
973
1121
|
currentStep: {
|
|
974
1122
|
id: step.id,
|
|
975
1123
|
status: "suspended",
|
|
976
|
-
payload:
|
|
1124
|
+
payload: stepResult.payload,
|
|
1125
|
+
suspendPayload: {
|
|
1126
|
+
...stepResult?.suspendPayload,
|
|
1127
|
+
__workflow_meta: { runId, path: suspendPath }
|
|
1128
|
+
}
|
|
977
1129
|
},
|
|
978
1130
|
workflowState: {
|
|
979
1131
|
status: "running",
|
|
@@ -995,7 +1147,11 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
995
1147
|
executionContext,
|
|
996
1148
|
result: {
|
|
997
1149
|
status: "suspended",
|
|
998
|
-
payload:
|
|
1150
|
+
payload: stepResult.payload,
|
|
1151
|
+
suspendPayload: {
|
|
1152
|
+
...stepResult?.suspendPayload,
|
|
1153
|
+
__workflow_meta: { runId, path: suspendPath }
|
|
1154
|
+
}
|
|
999
1155
|
}
|
|
1000
1156
|
};
|
|
1001
1157
|
}
|
|
@@ -1060,141 +1216,182 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1060
1216
|
}
|
|
1061
1217
|
);
|
|
1062
1218
|
Object.assign(executionContext, res.executionContext);
|
|
1063
|
-
return
|
|
1219
|
+
return {
|
|
1220
|
+
...res.result,
|
|
1221
|
+
startedAt,
|
|
1222
|
+
endedAt: Date.now(),
|
|
1223
|
+
payload: inputData,
|
|
1224
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1225
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1226
|
+
};
|
|
1064
1227
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1228
|
+
let stepRes;
|
|
1229
|
+
try {
|
|
1230
|
+
stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
1231
|
+
let execResults;
|
|
1232
|
+
let suspended;
|
|
1233
|
+
let bailed;
|
|
1234
|
+
try {
|
|
1235
|
+
if (validationError) {
|
|
1236
|
+
throw validationError;
|
|
1237
|
+
}
|
|
1238
|
+
const result = await step.execute({
|
|
1239
|
+
runId: executionContext.runId,
|
|
1240
|
+
mastra: this.mastra,
|
|
1241
|
+
runtimeContext,
|
|
1242
|
+
writableStream,
|
|
1243
|
+
state: executionContext?.state ?? {},
|
|
1244
|
+
setState: (state) => {
|
|
1245
|
+
executionContext.state = state;
|
|
1246
|
+
},
|
|
1247
|
+
inputData,
|
|
1248
|
+
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
|
|
1249
|
+
tracingContext: {
|
|
1250
|
+
currentSpan: stepAISpan
|
|
1251
|
+
},
|
|
1252
|
+
getInitData: () => stepResults?.input,
|
|
1253
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1254
|
+
suspend: async (suspendPayload, suspendOptions) => {
|
|
1255
|
+
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1256
|
+
if (suspendOptions?.resumeLabel) {
|
|
1257
|
+
const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
|
|
1258
|
+
for (const label of resumeLabel) {
|
|
1259
|
+
executionContext.resumeLabels[label] = {
|
|
1260
|
+
stepId: step.id,
|
|
1261
|
+
foreachIndex: executionContext.foreachIndex
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
suspended = { payload: suspendPayload };
|
|
1266
|
+
},
|
|
1267
|
+
bail: (result2) => {
|
|
1268
|
+
bailed = { payload: result2 };
|
|
1269
|
+
},
|
|
1270
|
+
resume: {
|
|
1271
|
+
steps: resume?.steps?.slice(1) || [],
|
|
1272
|
+
resumePayload: resume?.resumePayload,
|
|
1273
|
+
// @ts-ignore
|
|
1274
|
+
runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
|
|
1275
|
+
},
|
|
1276
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1277
|
+
engine: {
|
|
1278
|
+
step: this.inngestStep
|
|
1279
|
+
},
|
|
1280
|
+
abortSignal: abortController.signal
|
|
1281
|
+
});
|
|
1282
|
+
const endedAt = Date.now();
|
|
1283
|
+
execResults = {
|
|
1284
|
+
status: "success",
|
|
1285
|
+
output: result,
|
|
1286
|
+
startedAt,
|
|
1287
|
+
endedAt,
|
|
1288
|
+
payload: inputData,
|
|
1289
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1290
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1291
|
+
};
|
|
1292
|
+
} catch (e) {
|
|
1293
|
+
const stepFailure = {
|
|
1294
|
+
status: "failed",
|
|
1295
|
+
payload: inputData,
|
|
1296
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1297
|
+
endedAt: Date.now(),
|
|
1298
|
+
startedAt,
|
|
1299
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1300
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1301
|
+
};
|
|
1302
|
+
execResults = stepFailure;
|
|
1303
|
+
const fallbackErrorMessage = `Step ${step.id} failed`;
|
|
1304
|
+
stepAISpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
|
|
1305
|
+
throw new inngest.RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
|
|
1306
|
+
cause: execResults
|
|
1307
|
+
});
|
|
1308
|
+
}
|
|
1309
|
+
if (suspended) {
|
|
1310
|
+
execResults = {
|
|
1311
|
+
status: "suspended",
|
|
1312
|
+
suspendPayload: suspended.payload,
|
|
1313
|
+
payload: inputData,
|
|
1314
|
+
suspendedAt: Date.now(),
|
|
1315
|
+
startedAt,
|
|
1316
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1317
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1318
|
+
};
|
|
1319
|
+
} else if (bailed) {
|
|
1320
|
+
execResults = {
|
|
1321
|
+
status: "bailed",
|
|
1322
|
+
output: bailed.payload,
|
|
1323
|
+
payload: inputData,
|
|
1324
|
+
endedAt: Date.now(),
|
|
1325
|
+
startedAt
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
await emitter.emit("watch", {
|
|
1329
|
+
type: "watch",
|
|
1330
|
+
payload: {
|
|
1331
|
+
currentStep: {
|
|
1332
|
+
id: step.id,
|
|
1333
|
+
...execResults
|
|
1334
|
+
},
|
|
1335
|
+
workflowState: {
|
|
1336
|
+
status: "running",
|
|
1337
|
+
steps: { ...stepResults, [step.id]: execResults },
|
|
1338
|
+
result: null,
|
|
1339
|
+
error: null
|
|
1085
1340
|
}
|
|
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
1341
|
},
|
|
1095
|
-
|
|
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
|
-
},
|
|
1105
|
-
abortSignal: abortController.signal
|
|
1342
|
+
eventTimestamp: Date.now()
|
|
1106
1343
|
});
|
|
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;
|
|
1344
|
+
if (execResults.status === "suspended") {
|
|
1345
|
+
await emitter.emit("watch-v2", {
|
|
1346
|
+
type: "workflow-step-suspended",
|
|
1347
|
+
payload: {
|
|
1348
|
+
id: step.id,
|
|
1349
|
+
...execResults
|
|
1350
|
+
}
|
|
1351
|
+
});
|
|
1352
|
+
} else {
|
|
1353
|
+
await emitter.emit("watch-v2", {
|
|
1354
|
+
type: "workflow-step-result",
|
|
1355
|
+
payload: {
|
|
1356
|
+
id: step.id,
|
|
1357
|
+
...execResults
|
|
1358
|
+
}
|
|
1359
|
+
});
|
|
1360
|
+
await emitter.emit("watch-v2", {
|
|
1361
|
+
type: "workflow-step-finish",
|
|
1362
|
+
payload: {
|
|
1363
|
+
id: step.id,
|
|
1364
|
+
metadata: {}
|
|
1365
|
+
}
|
|
1366
|
+
});
|
|
1146
1367
|
}
|
|
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()
|
|
1368
|
+
stepAISpan?.end({ output: execResults });
|
|
1369
|
+
return { result: execResults, executionContext, stepResults };
|
|
1163
1370
|
});
|
|
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) {
|
|
1371
|
+
} catch (e) {
|
|
1372
|
+
const stepFailure = e instanceof Error ? e?.cause : {
|
|
1373
|
+
status: "failed",
|
|
1374
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1375
|
+
payload: inputData,
|
|
1376
|
+
startedAt,
|
|
1377
|
+
endedAt: Date.now()
|
|
1378
|
+
};
|
|
1379
|
+
stepRes = {
|
|
1380
|
+
result: stepFailure,
|
|
1381
|
+
executionContext,
|
|
1382
|
+
stepResults: {
|
|
1383
|
+
...stepResults,
|
|
1384
|
+
[step.id]: stepFailure
|
|
1385
|
+
}
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
if (disableScorers !== false && stepRes.result.status === "success") {
|
|
1192
1389
|
await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
|
|
1193
1390
|
if (step.scorers) {
|
|
1194
1391
|
await this.runScorers({
|
|
1195
1392
|
scorers: step.scorers,
|
|
1196
1393
|
runId: executionContext.runId,
|
|
1197
|
-
input:
|
|
1394
|
+
input: inputData,
|
|
1198
1395
|
output: stepRes.result,
|
|
1199
1396
|
workflowId: executionContext.workflowId,
|
|
1200
1397
|
stepId: step.id,
|
|
@@ -1207,12 +1404,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1207
1404
|
}
|
|
1208
1405
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
1209
1406
|
Object.assign(stepResults, stepRes.stepResults);
|
|
1407
|
+
executionContext.state = stepRes.executionContext.state;
|
|
1210
1408
|
return stepRes.result;
|
|
1211
1409
|
}
|
|
1212
1410
|
async persistStepUpdate({
|
|
1213
1411
|
workflowId,
|
|
1214
1412
|
runId,
|
|
1215
1413
|
stepResults,
|
|
1414
|
+
resourceId,
|
|
1216
1415
|
executionContext,
|
|
1217
1416
|
serializedStepGraph,
|
|
1218
1417
|
workflowStatus,
|
|
@@ -1222,15 +1421,21 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1222
1421
|
await this.inngestStep.run(
|
|
1223
1422
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
1224
1423
|
async () => {
|
|
1424
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({ stepResults, workflowStatus });
|
|
1425
|
+
if (!shouldPersistSnapshot) {
|
|
1426
|
+
return;
|
|
1427
|
+
}
|
|
1225
1428
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
1226
1429
|
workflowName: workflowId,
|
|
1227
1430
|
runId,
|
|
1431
|
+
resourceId,
|
|
1228
1432
|
snapshot: {
|
|
1229
1433
|
runId,
|
|
1230
|
-
value:
|
|
1434
|
+
value: executionContext.state,
|
|
1231
1435
|
context: stepResults,
|
|
1232
1436
|
activePaths: [],
|
|
1233
1437
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1438
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1234
1439
|
waitingPaths: {},
|
|
1235
1440
|
serializedStepGraph,
|
|
1236
1441
|
status: workflowStatus,
|
|
@@ -1262,11 +1467,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1262
1467
|
}) {
|
|
1263
1468
|
const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1264
1469
|
type: aiTracing.AISpanType.WORKFLOW_CONDITIONAL,
|
|
1265
|
-
name: `conditional: ${entry.conditions.length} conditions`,
|
|
1470
|
+
name: `conditional: '${entry.conditions.length} conditions'`,
|
|
1266
1471
|
input: prevOutput,
|
|
1267
1472
|
attributes: {
|
|
1268
1473
|
conditionCount: entry.conditions.length
|
|
1269
|
-
}
|
|
1474
|
+
},
|
|
1475
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1270
1476
|
});
|
|
1271
1477
|
let execResults;
|
|
1272
1478
|
const truthyIndexes = (await Promise.all(
|
|
@@ -1274,59 +1480,65 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1274
1480
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1275
1481
|
const evalSpan = conditionalSpan?.createChildSpan({
|
|
1276
1482
|
type: aiTracing.AISpanType.WORKFLOW_CONDITIONAL_EVAL,
|
|
1277
|
-
name: `condition ${index}`,
|
|
1483
|
+
name: `condition: '${index}'`,
|
|
1278
1484
|
input: prevOutput,
|
|
1279
1485
|
attributes: {
|
|
1280
1486
|
conditionIndex: index
|
|
1281
|
-
}
|
|
1487
|
+
},
|
|
1488
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1282
1489
|
});
|
|
1283
1490
|
try {
|
|
1284
|
-
const result = await cond(
|
|
1285
|
-
|
|
1286
|
-
workflowId,
|
|
1287
|
-
mastra: this.mastra,
|
|
1288
|
-
runtimeContext,
|
|
1289
|
-
runCount: -1,
|
|
1290
|
-
inputData: prevOutput,
|
|
1291
|
-
tracingContext: {
|
|
1292
|
-
currentSpan: evalSpan
|
|
1293
|
-
},
|
|
1294
|
-
getInitData: () => stepResults?.input,
|
|
1295
|
-
getStepResult: (step) => {
|
|
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
|
-
},
|
|
1305
|
-
// TODO: this function shouldn't have suspend probably?
|
|
1306
|
-
suspend: async (_suspendPayload) => {
|
|
1307
|
-
},
|
|
1308
|
-
bail: () => {
|
|
1309
|
-
},
|
|
1310
|
-
abort: () => {
|
|
1311
|
-
abortController.abort();
|
|
1312
|
-
},
|
|
1313
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1314
|
-
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1315
|
-
// TODO: add streamVNext support
|
|
1316
|
-
engine: {
|
|
1317
|
-
step: this.inngestStep
|
|
1318
|
-
},
|
|
1319
|
-
abortSignal: abortController.signal,
|
|
1320
|
-
writer: new tools.ToolStream(
|
|
1491
|
+
const result = await cond(
|
|
1492
|
+
workflows.createDeprecationProxy(
|
|
1321
1493
|
{
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1494
|
+
runId,
|
|
1495
|
+
workflowId,
|
|
1496
|
+
mastra: this.mastra,
|
|
1497
|
+
runtimeContext,
|
|
1498
|
+
runCount: -1,
|
|
1499
|
+
retryCount: -1,
|
|
1500
|
+
inputData: prevOutput,
|
|
1501
|
+
state: executionContext.state,
|
|
1502
|
+
setState: (state) => {
|
|
1503
|
+
executionContext.state = state;
|
|
1504
|
+
},
|
|
1505
|
+
tracingContext: {
|
|
1506
|
+
currentSpan: evalSpan
|
|
1507
|
+
},
|
|
1508
|
+
getInitData: () => stepResults?.input,
|
|
1509
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1510
|
+
// TODO: this function shouldn't have suspend probably?
|
|
1511
|
+
suspend: async (_suspendPayload) => {
|
|
1512
|
+
},
|
|
1513
|
+
bail: () => {
|
|
1514
|
+
},
|
|
1515
|
+
abort: () => {
|
|
1516
|
+
abortController.abort();
|
|
1517
|
+
},
|
|
1518
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1519
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1520
|
+
// TODO: add streamVNext support
|
|
1521
|
+
engine: {
|
|
1522
|
+
step: this.inngestStep
|
|
1523
|
+
},
|
|
1524
|
+
abortSignal: abortController.signal,
|
|
1525
|
+
writer: new tools.ToolStream(
|
|
1526
|
+
{
|
|
1527
|
+
prefix: "workflow-step",
|
|
1528
|
+
callId: crypto.randomUUID(),
|
|
1529
|
+
name: "conditional",
|
|
1530
|
+
runId
|
|
1531
|
+
},
|
|
1532
|
+
writableStream
|
|
1533
|
+
)
|
|
1326
1534
|
},
|
|
1327
|
-
|
|
1535
|
+
{
|
|
1536
|
+
paramName: "runCount",
|
|
1537
|
+
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
1538
|
+
logger: this.logger
|
|
1539
|
+
}
|
|
1328
1540
|
)
|
|
1329
|
-
|
|
1541
|
+
);
|
|
1330
1542
|
evalSpan?.end({
|
|
1331
1543
|
output: result,
|
|
1332
1544
|
attributes: {
|
|
@@ -1368,8 +1580,9 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1368
1580
|
runId,
|
|
1369
1581
|
executionPath: [...executionContext.executionPath, index],
|
|
1370
1582
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1583
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1371
1584
|
retryConfig: executionContext.retryConfig,
|
|
1372
|
-
|
|
1585
|
+
state: executionContext.state
|
|
1373
1586
|
},
|
|
1374
1587
|
emitter,
|
|
1375
1588
|
abortController,
|
|
@@ -1387,7 +1600,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1387
1600
|
if (hasFailed) {
|
|
1388
1601
|
execResults = { status: "failed", error: hasFailed.result.error };
|
|
1389
1602
|
} else if (hasSuspended) {
|
|
1390
|
-
execResults = { status: "suspended",
|
|
1603
|
+
execResults = { status: "suspended", suspendPayload: hasSuspended.result.suspendPayload };
|
|
1391
1604
|
} else {
|
|
1392
1605
|
execResults = {
|
|
1393
1606
|
status: "success",
|