@mastra/inngest 0.0.0-iterate-traces-ui-again-20250912091900 → 0.0.0-main-test-20251105183450
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 +447 -3
- package/dist/index.cjs +687 -567
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +119 -83
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +688 -568
- package/dist/index.js.map +1 -1
- package/package.json +17 -14
package/dist/index.js
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
|
+
import { ReadableStream } from 'stream/web';
|
|
2
3
|
import { subscribe } from '@inngest/realtime';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
4
|
+
import { RequestContext } from '@mastra/core/di';
|
|
5
|
+
import { wrapMastra, SpanType } from '@mastra/core/observability';
|
|
6
|
+
import { ChunkFrom, WorkflowRunOutput } from '@mastra/core/stream';
|
|
5
7
|
import { ToolStream, Tool } from '@mastra/core/tools';
|
|
6
|
-
import { Run, Workflow, DefaultExecutionEngine } from '@mastra/core/workflows';
|
|
8
|
+
import { Run, Workflow, DefaultExecutionEngine, createDeprecationProxy, getStepResult, runCountDeprecationMessage, validateStepInput } from '@mastra/core/workflows';
|
|
7
9
|
import { EMITTER_SYMBOL, STREAM_FORMAT_SYMBOL } from '@mastra/core/workflows/_constants';
|
|
10
|
+
import { NonRetriableError, RetryAfterError } from 'inngest';
|
|
8
11
|
import { serve as serve$1 } from 'inngest/hono';
|
|
9
12
|
import { z } from 'zod';
|
|
10
13
|
|
|
11
14
|
// src/index.ts
|
|
12
|
-
function serve({
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
function serve({
|
|
16
|
+
mastra,
|
|
17
|
+
inngest,
|
|
18
|
+
functions: userFunctions = [],
|
|
19
|
+
registerOptions
|
|
20
|
+
}) {
|
|
21
|
+
const wfs = mastra.listWorkflows();
|
|
22
|
+
const workflowFunctions = Array.from(
|
|
15
23
|
new Set(
|
|
16
24
|
Object.values(wfs).flatMap((wf) => {
|
|
17
25
|
if (wf instanceof InngestWorkflow) {
|
|
@@ -23,8 +31,9 @@ function serve({ mastra, inngest }) {
|
|
|
23
31
|
)
|
|
24
32
|
);
|
|
25
33
|
return serve$1({
|
|
34
|
+
...registerOptions,
|
|
26
35
|
client: inngest,
|
|
27
|
-
functions
|
|
36
|
+
functions: [...workflowFunctions, ...userFunctions]
|
|
28
37
|
});
|
|
29
38
|
}
|
|
30
39
|
var InngestRun = class extends Run {
|
|
@@ -48,14 +57,21 @@ var InngestRun = class extends Run {
|
|
|
48
57
|
}
|
|
49
58
|
async getRunOutput(eventId) {
|
|
50
59
|
let runs = await this.getRuns(eventId);
|
|
60
|
+
const storage = this.#mastra?.getStorage();
|
|
51
61
|
while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
|
|
52
62
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
53
63
|
runs = await this.getRuns(eventId);
|
|
54
64
|
if (runs?.[0]?.status === "Failed") {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
65
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
66
|
+
workflowName: this.workflowId,
|
|
67
|
+
runId: this.runId
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
output: { result: { steps: snapshot?.context, status: "failed", error: runs?.[0]?.output?.message } }
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (runs?.[0]?.status === "Cancelled") {
|
|
74
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
59
75
|
workflowName: this.workflowId,
|
|
60
76
|
runId: this.runId
|
|
61
77
|
});
|
|
@@ -71,20 +87,22 @@ var InngestRun = class extends Run {
|
|
|
71
87
|
});
|
|
72
88
|
}
|
|
73
89
|
async cancel() {
|
|
90
|
+
const storage = this.#mastra?.getStorage();
|
|
74
91
|
await this.inngest.send({
|
|
75
92
|
name: `cancel.workflow.${this.workflowId}`,
|
|
76
93
|
data: {
|
|
77
94
|
runId: this.runId
|
|
78
95
|
}
|
|
79
96
|
});
|
|
80
|
-
const snapshot = await
|
|
97
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
81
98
|
workflowName: this.workflowId,
|
|
82
99
|
runId: this.runId
|
|
83
100
|
});
|
|
84
101
|
if (snapshot) {
|
|
85
|
-
await
|
|
102
|
+
await storage?.persistWorkflowSnapshot({
|
|
86
103
|
workflowName: this.workflowId,
|
|
87
104
|
runId: this.runId,
|
|
105
|
+
resourceId: this.resourceId,
|
|
88
106
|
snapshot: {
|
|
89
107
|
...snapshot,
|
|
90
108
|
status: "canceled"
|
|
@@ -92,12 +110,20 @@ var InngestRun = class extends Run {
|
|
|
92
110
|
});
|
|
93
111
|
}
|
|
94
112
|
}
|
|
95
|
-
async start({
|
|
96
|
-
|
|
113
|
+
async start(params) {
|
|
114
|
+
return this._start(params);
|
|
115
|
+
}
|
|
116
|
+
async _start({
|
|
117
|
+
inputData,
|
|
118
|
+
initialState,
|
|
119
|
+
outputOptions,
|
|
120
|
+
tracingOptions,
|
|
121
|
+
format
|
|
97
122
|
}) {
|
|
98
123
|
await this.#mastra.getStorage()?.persistWorkflowSnapshot({
|
|
99
124
|
workflowName: this.workflowId,
|
|
100
125
|
runId: this.runId,
|
|
126
|
+
resourceId: this.resourceId,
|
|
101
127
|
snapshot: {
|
|
102
128
|
runId: this.runId,
|
|
103
129
|
serializedStepGraph: this.serializedStepGraph,
|
|
@@ -105,16 +131,24 @@ var InngestRun = class extends Run {
|
|
|
105
131
|
context: {},
|
|
106
132
|
activePaths: [],
|
|
107
133
|
suspendedPaths: {},
|
|
134
|
+
resumeLabels: {},
|
|
108
135
|
waitingPaths: {},
|
|
109
136
|
timestamp: Date.now(),
|
|
110
137
|
status: "running"
|
|
111
138
|
}
|
|
112
139
|
});
|
|
140
|
+
const inputDataToUse = await this._validateInput(inputData);
|
|
141
|
+
const initialStateToUse = await this._validateInitialState(initialState ?? {});
|
|
113
142
|
const eventOutput = await this.inngest.send({
|
|
114
143
|
name: `workflow.${this.workflowId}`,
|
|
115
144
|
data: {
|
|
116
|
-
inputData,
|
|
117
|
-
|
|
145
|
+
inputData: inputDataToUse,
|
|
146
|
+
initialState: initialStateToUse,
|
|
147
|
+
runId: this.runId,
|
|
148
|
+
resourceId: this.resourceId,
|
|
149
|
+
outputOptions,
|
|
150
|
+
tracingOptions,
|
|
151
|
+
format
|
|
118
152
|
}
|
|
119
153
|
});
|
|
120
154
|
const eventId = eventOutput.ids[0];
|
|
@@ -143,24 +177,28 @@ var InngestRun = class extends Run {
|
|
|
143
177
|
return p;
|
|
144
178
|
}
|
|
145
179
|
async _resume(params) {
|
|
180
|
+
const storage = this.#mastra?.getStorage();
|
|
146
181
|
const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
147
182
|
(step) => typeof step === "string" ? step : step?.id
|
|
148
183
|
);
|
|
149
|
-
const snapshot = await
|
|
184
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
150
185
|
workflowName: this.workflowId,
|
|
151
186
|
runId: this.runId
|
|
152
187
|
});
|
|
188
|
+
const suspendedStep = this.workflowSteps[steps?.[0] ?? ""];
|
|
189
|
+
const resumeDataToUse = await this._validateResumeData(params.resumeData, suspendedStep);
|
|
153
190
|
const eventOutput = await this.inngest.send({
|
|
154
191
|
name: `workflow.${this.workflowId}`,
|
|
155
192
|
data: {
|
|
156
|
-
inputData:
|
|
193
|
+
inputData: resumeDataToUse,
|
|
194
|
+
initialState: snapshot?.value ?? {},
|
|
157
195
|
runId: this.runId,
|
|
158
196
|
workflowId: this.workflowId,
|
|
159
197
|
stepResults: snapshot?.context,
|
|
160
198
|
resume: {
|
|
161
199
|
steps,
|
|
162
200
|
stepResults: snapshot?.context,
|
|
163
|
-
resumePayload:
|
|
201
|
+
resumePayload: resumeDataToUse,
|
|
164
202
|
// @ts-ignore
|
|
165
203
|
resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
|
|
166
204
|
}
|
|
@@ -177,12 +215,12 @@ var InngestRun = class extends Run {
|
|
|
177
215
|
}
|
|
178
216
|
return result;
|
|
179
217
|
}
|
|
180
|
-
watch(cb
|
|
218
|
+
watch(cb) {
|
|
181
219
|
let active = true;
|
|
182
220
|
const streamPromise = subscribe(
|
|
183
221
|
{
|
|
184
222
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
185
|
-
topics: [
|
|
223
|
+
topics: ["watch"],
|
|
186
224
|
app: this.inngest
|
|
187
225
|
},
|
|
188
226
|
(message) => {
|
|
@@ -200,44 +238,35 @@ var InngestRun = class extends Run {
|
|
|
200
238
|
});
|
|
201
239
|
};
|
|
202
240
|
}
|
|
203
|
-
|
|
241
|
+
streamLegacy({ inputData, requestContext } = {}) {
|
|
204
242
|
const { readable, writable } = new TransformStream();
|
|
205
|
-
let currentToolData = void 0;
|
|
206
243
|
const writer = writable.getWriter();
|
|
207
244
|
const unwatch = this.watch(async (event) => {
|
|
208
|
-
|
|
209
|
-
currentToolData = {
|
|
210
|
-
name: event.payload.name,
|
|
211
|
-
args: event.payload.args
|
|
212
|
-
};
|
|
245
|
+
try {
|
|
213
246
|
await writer.write({
|
|
214
|
-
|
|
215
|
-
type: "
|
|
247
|
+
// @ts-ignore
|
|
248
|
+
type: "start",
|
|
249
|
+
// @ts-ignore
|
|
250
|
+
payload: { runId: this.runId }
|
|
216
251
|
});
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
try {
|
|
220
|
-
if (event.type === "workflow-agent-call-finish") {
|
|
221
|
-
return;
|
|
222
|
-
} else if (!event.type.startsWith("workflow-")) {
|
|
223
|
-
if (event.type === "text-delta") {
|
|
224
|
-
await writer.write({
|
|
225
|
-
type: "tool-call-delta",
|
|
226
|
-
...currentToolData ?? {},
|
|
227
|
-
argsTextDelta: event.textDelta
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
252
|
const e = {
|
|
233
253
|
...event,
|
|
234
254
|
type: event.type.replace("workflow-", "")
|
|
235
255
|
};
|
|
256
|
+
if (e.type === "step-output") {
|
|
257
|
+
e.type = e.payload.output.type;
|
|
258
|
+
e.payload = e.payload.output.payload;
|
|
259
|
+
}
|
|
236
260
|
await writer.write(e);
|
|
237
261
|
} catch {
|
|
238
262
|
}
|
|
239
|
-
}
|
|
263
|
+
});
|
|
240
264
|
this.closeStreamAction = async () => {
|
|
265
|
+
await writer.write({
|
|
266
|
+
type: "finish",
|
|
267
|
+
// @ts-ignore
|
|
268
|
+
payload: { runId: this.runId }
|
|
269
|
+
});
|
|
241
270
|
unwatch();
|
|
242
271
|
try {
|
|
243
272
|
await writer.close();
|
|
@@ -247,7 +276,7 @@ var InngestRun = class extends Run {
|
|
|
247
276
|
writer.releaseLock();
|
|
248
277
|
}
|
|
249
278
|
};
|
|
250
|
-
this.executionResults = this.
|
|
279
|
+
this.executionResults = this._start({ inputData, requestContext, format: "legacy" }).then((result) => {
|
|
251
280
|
if (result.status !== "suspended") {
|
|
252
281
|
this.closeStreamAction?.().catch(() => {
|
|
253
282
|
});
|
|
@@ -259,6 +288,82 @@ var InngestRun = class extends Run {
|
|
|
259
288
|
getWorkflowState: () => this.executionResults
|
|
260
289
|
};
|
|
261
290
|
}
|
|
291
|
+
stream({
|
|
292
|
+
inputData,
|
|
293
|
+
requestContext,
|
|
294
|
+
tracingOptions,
|
|
295
|
+
closeOnSuspend = true,
|
|
296
|
+
initialState,
|
|
297
|
+
outputOptions
|
|
298
|
+
} = {}) {
|
|
299
|
+
if (this.closeStreamAction && this.streamOutput) {
|
|
300
|
+
return this.streamOutput;
|
|
301
|
+
}
|
|
302
|
+
this.closeStreamAction = async () => {
|
|
303
|
+
};
|
|
304
|
+
const self = this;
|
|
305
|
+
const stream = new ReadableStream({
|
|
306
|
+
async start(controller) {
|
|
307
|
+
const unwatch = self.watch(async ({ type, from = ChunkFrom.WORKFLOW, payload }) => {
|
|
308
|
+
controller.enqueue({
|
|
309
|
+
type,
|
|
310
|
+
runId: self.runId,
|
|
311
|
+
from,
|
|
312
|
+
payload: {
|
|
313
|
+
stepName: payload?.id,
|
|
314
|
+
...payload
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
self.closeStreamAction = async () => {
|
|
319
|
+
unwatch();
|
|
320
|
+
try {
|
|
321
|
+
await controller.close();
|
|
322
|
+
} catch (err) {
|
|
323
|
+
console.error("Error closing stream:", err);
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
const executionResultsPromise = self._start({
|
|
327
|
+
inputData,
|
|
328
|
+
requestContext,
|
|
329
|
+
// tracingContext, // We are not able to pass a reference to a span here, what to do?
|
|
330
|
+
initialState,
|
|
331
|
+
tracingOptions,
|
|
332
|
+
outputOptions,
|
|
333
|
+
format: "vnext"
|
|
334
|
+
});
|
|
335
|
+
let executionResults;
|
|
336
|
+
try {
|
|
337
|
+
executionResults = await executionResultsPromise;
|
|
338
|
+
if (closeOnSuspend) {
|
|
339
|
+
self.closeStreamAction?.().catch(() => {
|
|
340
|
+
});
|
|
341
|
+
} else if (executionResults.status !== "suspended") {
|
|
342
|
+
self.closeStreamAction?.().catch(() => {
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
if (self.streamOutput) {
|
|
346
|
+
self.streamOutput.updateResults(
|
|
347
|
+
executionResults
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
} catch (err) {
|
|
351
|
+
self.streamOutput?.rejectResults(err);
|
|
352
|
+
self.closeStreamAction?.().catch(() => {
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
this.streamOutput = new WorkflowRunOutput({
|
|
358
|
+
runId: this.runId,
|
|
359
|
+
workflowId: this.workflowId,
|
|
360
|
+
stream
|
|
361
|
+
});
|
|
362
|
+
return this.streamOutput;
|
|
363
|
+
}
|
|
364
|
+
streamVNext(args = {}) {
|
|
365
|
+
return this.stream(args);
|
|
366
|
+
}
|
|
262
367
|
};
|
|
263
368
|
var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
264
369
|
#mastra;
|
|
@@ -275,13 +380,13 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
275
380
|
this.#mastra = params.mastra;
|
|
276
381
|
this.inngest = inngest;
|
|
277
382
|
}
|
|
278
|
-
async
|
|
383
|
+
async listWorkflowRuns(args) {
|
|
279
384
|
const storage = this.#mastra?.getStorage();
|
|
280
385
|
if (!storage) {
|
|
281
386
|
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
282
387
|
return { runs: [], total: 0 };
|
|
283
388
|
}
|
|
284
|
-
return storage.
|
|
389
|
+
return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
|
|
285
390
|
}
|
|
286
391
|
async getWorkflowRunById(runId) {
|
|
287
392
|
const storage = this.#mastra?.getStorage();
|
|
@@ -310,45 +415,34 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
310
415
|
}
|
|
311
416
|
}
|
|
312
417
|
}
|
|
313
|
-
createRun(options) {
|
|
314
|
-
const runIdToUse = options?.runId || randomUUID();
|
|
315
|
-
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
316
|
-
{
|
|
317
|
-
workflowId: this.id,
|
|
318
|
-
runId: runIdToUse,
|
|
319
|
-
executionEngine: this.executionEngine,
|
|
320
|
-
executionGraph: this.executionGraph,
|
|
321
|
-
serializedStepGraph: this.serializedStepGraph,
|
|
322
|
-
mastra: this.#mastra,
|
|
323
|
-
retryConfig: this.retryConfig,
|
|
324
|
-
cleanup: () => this.runs.delete(runIdToUse)
|
|
325
|
-
},
|
|
326
|
-
this.inngest
|
|
327
|
-
);
|
|
328
|
-
this.runs.set(runIdToUse, run);
|
|
329
|
-
return run;
|
|
330
|
-
}
|
|
331
|
-
async createRunAsync(options) {
|
|
418
|
+
async createRun(options) {
|
|
332
419
|
const runIdToUse = options?.runId || randomUUID();
|
|
333
420
|
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
334
421
|
{
|
|
335
422
|
workflowId: this.id,
|
|
336
423
|
runId: runIdToUse,
|
|
424
|
+
resourceId: options?.resourceId,
|
|
337
425
|
executionEngine: this.executionEngine,
|
|
338
426
|
executionGraph: this.executionGraph,
|
|
339
427
|
serializedStepGraph: this.serializedStepGraph,
|
|
340
428
|
mastra: this.#mastra,
|
|
341
429
|
retryConfig: this.retryConfig,
|
|
342
|
-
cleanup: () => this.runs.delete(runIdToUse)
|
|
430
|
+
cleanup: () => this.runs.delete(runIdToUse),
|
|
431
|
+
workflowSteps: this.steps
|
|
343
432
|
},
|
|
344
433
|
this.inngest
|
|
345
434
|
);
|
|
346
435
|
this.runs.set(runIdToUse, run);
|
|
436
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
|
|
437
|
+
workflowStatus: run.workflowRunStatus,
|
|
438
|
+
stepResults: {}
|
|
439
|
+
});
|
|
347
440
|
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
|
|
348
|
-
if (!workflowSnapshotInStorage) {
|
|
441
|
+
if (!workflowSnapshotInStorage && shouldPersistSnapshot) {
|
|
349
442
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
350
443
|
workflowName: this.id,
|
|
351
444
|
runId: runIdToUse,
|
|
445
|
+
resourceId: options?.resourceId,
|
|
352
446
|
snapshot: {
|
|
353
447
|
runId: runIdToUse,
|
|
354
448
|
status: "pending",
|
|
@@ -358,6 +452,7 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
358
452
|
waitingPaths: {},
|
|
359
453
|
serializedStepGraph: this.serializedStepGraph,
|
|
360
454
|
suspendedPaths: {},
|
|
455
|
+
resumeLabels: {},
|
|
361
456
|
result: void 0,
|
|
362
457
|
error: void 0,
|
|
363
458
|
// @ts-ignore
|
|
@@ -382,7 +477,7 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
382
477
|
},
|
|
383
478
|
{ event: `workflow.${this.id}` },
|
|
384
479
|
async ({ event, step, attempt, publish }) => {
|
|
385
|
-
let { inputData, runId, resume } = event.data;
|
|
480
|
+
let { inputData, initialState, runId, resourceId, resume, outputOptions, format } = event.data;
|
|
386
481
|
if (!runId) {
|
|
387
482
|
runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
|
|
388
483
|
return randomUUID();
|
|
@@ -410,21 +505,38 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
410
505
|
once: (_event, _callback) => {
|
|
411
506
|
}
|
|
412
507
|
};
|
|
413
|
-
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
508
|
+
const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
|
|
414
509
|
const result = await engine.execute({
|
|
415
510
|
workflowId: this.id,
|
|
416
511
|
runId,
|
|
512
|
+
resourceId,
|
|
417
513
|
graph: this.executionGraph,
|
|
418
514
|
serializedStepGraph: this.serializedStepGraph,
|
|
419
515
|
input: inputData,
|
|
516
|
+
initialState,
|
|
420
517
|
emitter,
|
|
421
518
|
retryConfig: this.retryConfig,
|
|
422
|
-
|
|
519
|
+
requestContext: new RequestContext(),
|
|
423
520
|
// TODO
|
|
424
521
|
resume,
|
|
522
|
+
format,
|
|
425
523
|
abortController: new AbortController(),
|
|
426
|
-
currentSpan:
|
|
427
|
-
|
|
524
|
+
// currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
|
|
525
|
+
outputOptions,
|
|
526
|
+
writableStream: new WritableStream({
|
|
527
|
+
write(chunk) {
|
|
528
|
+
void emitter.emit("watch", chunk).catch(() => {
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
})
|
|
532
|
+
});
|
|
533
|
+
await step.run(`workflow.${this.id}.finalize`, async () => {
|
|
534
|
+
if (result.status === "failed") {
|
|
535
|
+
throw new NonRetriableError(`Workflow failed`, {
|
|
536
|
+
cause: result
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
return result;
|
|
428
540
|
});
|
|
429
541
|
return { result, runId };
|
|
430
542
|
}
|
|
@@ -454,10 +566,11 @@ function isAgent(params) {
|
|
|
454
566
|
function isTool(params) {
|
|
455
567
|
return params instanceof Tool;
|
|
456
568
|
}
|
|
457
|
-
function createStep(params) {
|
|
569
|
+
function createStep(params, agentOptions) {
|
|
458
570
|
if (isAgent(params)) {
|
|
459
571
|
return {
|
|
460
572
|
id: params.name,
|
|
573
|
+
description: params.getDescription(),
|
|
461
574
|
// @ts-ignore
|
|
462
575
|
inputSchema: z.object({
|
|
463
576
|
prompt: z.string()
|
|
@@ -468,7 +581,16 @@ function createStep(params) {
|
|
|
468
581
|
outputSchema: z.object({
|
|
469
582
|
text: z.string()
|
|
470
583
|
}),
|
|
471
|
-
execute: async ({
|
|
584
|
+
execute: async ({
|
|
585
|
+
inputData,
|
|
586
|
+
[EMITTER_SYMBOL]: emitter,
|
|
587
|
+
[STREAM_FORMAT_SYMBOL]: streamFormat,
|
|
588
|
+
requestContext,
|
|
589
|
+
tracingContext,
|
|
590
|
+
abortSignal,
|
|
591
|
+
abort,
|
|
592
|
+
writer
|
|
593
|
+
}) => {
|
|
472
594
|
let streamPromise = {};
|
|
473
595
|
streamPromise.promise = new Promise((resolve, reject) => {
|
|
474
596
|
streamPromise.resolve = resolve;
|
|
@@ -478,34 +600,65 @@ function createStep(params) {
|
|
|
478
600
|
name: params.name,
|
|
479
601
|
args: inputData
|
|
480
602
|
};
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
603
|
+
let stream;
|
|
604
|
+
if ((await params.getModel()).specificationVersion === "v1") {
|
|
605
|
+
const { fullStream } = await params.streamLegacy(inputData.prompt, {
|
|
606
|
+
...agentOptions ?? {},
|
|
607
|
+
// resourceId: inputData.resourceId,
|
|
608
|
+
// threadId: inputData.threadId,
|
|
609
|
+
requestContext,
|
|
610
|
+
tracingContext,
|
|
611
|
+
onFinish: (result) => {
|
|
612
|
+
streamPromise.resolve(result.text);
|
|
613
|
+
void agentOptions?.onFinish?.(result);
|
|
614
|
+
},
|
|
615
|
+
abortSignal
|
|
616
|
+
});
|
|
617
|
+
stream = fullStream;
|
|
618
|
+
} else {
|
|
619
|
+
const modelOutput = await params.stream(inputData.prompt, {
|
|
620
|
+
...agentOptions ?? {},
|
|
621
|
+
requestContext,
|
|
622
|
+
tracingContext,
|
|
623
|
+
onFinish: (result) => {
|
|
624
|
+
streamPromise.resolve(result.text);
|
|
625
|
+
void agentOptions?.onFinish?.(result);
|
|
626
|
+
},
|
|
627
|
+
abortSignal
|
|
628
|
+
});
|
|
629
|
+
stream = modelOutput.fullStream;
|
|
630
|
+
}
|
|
631
|
+
if (streamFormat === "legacy") {
|
|
632
|
+
await emitter.emit("watch", {
|
|
633
|
+
type: "tool-call-streaming-start",
|
|
634
|
+
...toolData ?? {}
|
|
635
|
+
});
|
|
636
|
+
for await (const chunk of stream) {
|
|
637
|
+
if (chunk.type === "text-delta") {
|
|
638
|
+
await emitter.emit("watch", {
|
|
639
|
+
type: "tool-call-delta",
|
|
640
|
+
...toolData ?? {},
|
|
641
|
+
argsTextDelta: chunk.textDelta
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
await emitter.emit("watch", {
|
|
646
|
+
type: "tool-call-streaming-finish",
|
|
647
|
+
...toolData ?? {}
|
|
648
|
+
});
|
|
649
|
+
} else {
|
|
650
|
+
for await (const chunk of stream) {
|
|
651
|
+
await writer.write(chunk);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
495
654
|
if (abortSignal.aborted) {
|
|
496
655
|
return abort();
|
|
497
656
|
}
|
|
498
|
-
for await (const chunk of fullStream) {
|
|
499
|
-
await emitter.emit("watch-v2", chunk);
|
|
500
|
-
}
|
|
501
|
-
await emitter.emit("watch-v2", {
|
|
502
|
-
type: "workflow-agent-call-finish",
|
|
503
|
-
payload: toolData
|
|
504
|
-
});
|
|
505
657
|
return {
|
|
506
658
|
text: await streamPromise.promise
|
|
507
659
|
};
|
|
508
|
-
}
|
|
660
|
+
},
|
|
661
|
+
component: params.component
|
|
509
662
|
};
|
|
510
663
|
}
|
|
511
664
|
if (isTool(params)) {
|
|
@@ -516,16 +669,20 @@ function createStep(params) {
|
|
|
516
669
|
// TODO: tool probably should have strong id type
|
|
517
670
|
// @ts-ignore
|
|
518
671
|
id: params.id,
|
|
672
|
+
description: params.description,
|
|
519
673
|
inputSchema: params.inputSchema,
|
|
520
674
|
outputSchema: params.outputSchema,
|
|
521
|
-
execute: async ({ inputData, mastra,
|
|
675
|
+
execute: async ({ inputData, mastra, requestContext, tracingContext, suspend, resumeData }) => {
|
|
522
676
|
return params.execute({
|
|
523
677
|
context: inputData,
|
|
524
678
|
mastra: wrapMastra(mastra, tracingContext),
|
|
525
|
-
|
|
526
|
-
tracingContext
|
|
679
|
+
requestContext,
|
|
680
|
+
tracingContext,
|
|
681
|
+
suspend,
|
|
682
|
+
resumeData
|
|
527
683
|
});
|
|
528
|
-
}
|
|
684
|
+
},
|
|
685
|
+
component: "TOOL"
|
|
529
686
|
};
|
|
530
687
|
}
|
|
531
688
|
return {
|
|
@@ -541,7 +698,10 @@ function createStep(params) {
|
|
|
541
698
|
function init(inngest) {
|
|
542
699
|
return {
|
|
543
700
|
createWorkflow(params) {
|
|
544
|
-
return new InngestWorkflow(
|
|
701
|
+
return new InngestWorkflow(
|
|
702
|
+
params,
|
|
703
|
+
inngest
|
|
704
|
+
);
|
|
545
705
|
},
|
|
546
706
|
createStep,
|
|
547
707
|
cloneStep(step, opts) {
|
|
@@ -550,7 +710,11 @@ function init(inngest) {
|
|
|
550
710
|
description: step.description,
|
|
551
711
|
inputSchema: step.inputSchema,
|
|
552
712
|
outputSchema: step.outputSchema,
|
|
553
|
-
|
|
713
|
+
resumeSchema: step.resumeSchema,
|
|
714
|
+
suspendSchema: step.suspendSchema,
|
|
715
|
+
stateSchema: step.stateSchema,
|
|
716
|
+
execute: step.execute,
|
|
717
|
+
component: step.component
|
|
554
718
|
};
|
|
555
719
|
},
|
|
556
720
|
cloneWorkflow(workflow, opts) {
|
|
@@ -570,78 +734,30 @@ function init(inngest) {
|
|
|
570
734
|
var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
571
735
|
inngestStep;
|
|
572
736
|
inngestAttempts;
|
|
573
|
-
constructor(mastra, inngestStep, inngestAttempts = 0) {
|
|
574
|
-
super({ mastra });
|
|
737
|
+
constructor(mastra, inngestStep, inngestAttempts = 0, options) {
|
|
738
|
+
super({ mastra, options });
|
|
575
739
|
this.inngestStep = inngestStep;
|
|
576
740
|
this.inngestAttempts = inngestAttempts;
|
|
577
741
|
}
|
|
578
|
-
async
|
|
579
|
-
await params.emitter.emit("watch-v2", {
|
|
580
|
-
type: "workflow-start",
|
|
581
|
-
payload: { runId: params.runId }
|
|
582
|
-
});
|
|
583
|
-
const result = await super.execute(params);
|
|
584
|
-
await params.emitter.emit("watch-v2", {
|
|
585
|
-
type: "workflow-finish",
|
|
586
|
-
payload: { runId: params.runId }
|
|
587
|
-
});
|
|
588
|
-
return result;
|
|
589
|
-
}
|
|
590
|
-
async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
|
|
742
|
+
async fmtReturnValue(emitter, stepResults, lastOutput, error) {
|
|
591
743
|
const base = {
|
|
592
744
|
status: lastOutput.status,
|
|
593
745
|
steps: stepResults
|
|
594
746
|
};
|
|
595
747
|
if (lastOutput.status === "success") {
|
|
596
|
-
await emitter.emit("watch", {
|
|
597
|
-
type: "watch",
|
|
598
|
-
payload: {
|
|
599
|
-
workflowState: {
|
|
600
|
-
status: lastOutput.status,
|
|
601
|
-
steps: stepResults,
|
|
602
|
-
result: lastOutput.output
|
|
603
|
-
}
|
|
604
|
-
},
|
|
605
|
-
eventTimestamp: Date.now()
|
|
606
|
-
});
|
|
607
748
|
base.result = lastOutput.output;
|
|
608
749
|
} else if (lastOutput.status === "failed") {
|
|
609
750
|
base.error = error instanceof Error ? error?.stack ?? error.message : lastOutput?.error instanceof Error ? lastOutput.error.message : lastOutput.error ?? error ?? "Unknown error";
|
|
610
|
-
await emitter.emit("watch", {
|
|
611
|
-
type: "watch",
|
|
612
|
-
payload: {
|
|
613
|
-
workflowState: {
|
|
614
|
-
status: lastOutput.status,
|
|
615
|
-
steps: stepResults,
|
|
616
|
-
result: null,
|
|
617
|
-
error: base.error
|
|
618
|
-
}
|
|
619
|
-
},
|
|
620
|
-
eventTimestamp: Date.now()
|
|
621
|
-
});
|
|
622
751
|
} else if (lastOutput.status === "suspended") {
|
|
623
|
-
await emitter.emit("watch", {
|
|
624
|
-
type: "watch",
|
|
625
|
-
payload: {
|
|
626
|
-
workflowState: {
|
|
627
|
-
status: lastOutput.status,
|
|
628
|
-
steps: stepResults,
|
|
629
|
-
result: null,
|
|
630
|
-
error: null
|
|
631
|
-
}
|
|
632
|
-
},
|
|
633
|
-
eventTimestamp: Date.now()
|
|
634
|
-
});
|
|
635
752
|
const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
|
|
636
753
|
if (stepResult?.status === "suspended") {
|
|
637
|
-
const nestedPath = stepResult?.
|
|
754
|
+
const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
|
|
638
755
|
return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
|
|
639
756
|
}
|
|
640
757
|
return [];
|
|
641
758
|
});
|
|
642
759
|
base.suspended = suspendedStepIds;
|
|
643
760
|
}
|
|
644
|
-
executionSpan?.end();
|
|
645
761
|
return base;
|
|
646
762
|
}
|
|
647
763
|
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
@@ -655,67 +771,71 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
655
771
|
stepResults,
|
|
656
772
|
emitter,
|
|
657
773
|
abortController,
|
|
658
|
-
|
|
774
|
+
requestContext,
|
|
659
775
|
executionContext,
|
|
660
776
|
writableStream,
|
|
661
777
|
tracingContext
|
|
662
778
|
}) {
|
|
663
779
|
let { duration, fn } = entry;
|
|
664
780
|
const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
665
|
-
type:
|
|
781
|
+
type: SpanType.WORKFLOW_SLEEP,
|
|
666
782
|
name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
|
|
667
783
|
attributes: {
|
|
668
784
|
durationMs: duration,
|
|
669
785
|
sleepType: fn ? "dynamic" : "fixed"
|
|
670
|
-
}
|
|
786
|
+
},
|
|
787
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
671
788
|
});
|
|
672
789
|
if (fn) {
|
|
673
790
|
const stepCallId = randomUUID();
|
|
674
791
|
duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
|
|
675
|
-
return await fn(
|
|
676
|
-
|
|
677
|
-
workflowId,
|
|
678
|
-
mastra: this.mastra,
|
|
679
|
-
runtimeContext,
|
|
680
|
-
inputData: prevOutput,
|
|
681
|
-
runCount: -1,
|
|
682
|
-
tracingContext: {
|
|
683
|
-
currentSpan: sleepSpan
|
|
684
|
-
},
|
|
685
|
-
getInitData: () => stepResults?.input,
|
|
686
|
-
getStepResult: (step) => {
|
|
687
|
-
if (!step?.id) {
|
|
688
|
-
return null;
|
|
689
|
-
}
|
|
690
|
-
const result = stepResults[step.id];
|
|
691
|
-
if (result?.status === "success") {
|
|
692
|
-
return result.output;
|
|
693
|
-
}
|
|
694
|
-
return null;
|
|
695
|
-
},
|
|
696
|
-
// TODO: this function shouldn't have suspend probably?
|
|
697
|
-
suspend: async (_suspendPayload) => {
|
|
698
|
-
},
|
|
699
|
-
bail: () => {
|
|
700
|
-
},
|
|
701
|
-
abort: () => {
|
|
702
|
-
abortController?.abort();
|
|
703
|
-
},
|
|
704
|
-
[EMITTER_SYMBOL]: emitter,
|
|
705
|
-
// TODO: add streamVNext support
|
|
706
|
-
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
707
|
-
engine: { step: this.inngestStep },
|
|
708
|
-
abortSignal: abortController?.signal,
|
|
709
|
-
writer: new ToolStream(
|
|
792
|
+
return await fn(
|
|
793
|
+
createDeprecationProxy(
|
|
710
794
|
{
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
795
|
+
runId,
|
|
796
|
+
workflowId,
|
|
797
|
+
mastra: this.mastra,
|
|
798
|
+
requestContext,
|
|
799
|
+
inputData: prevOutput,
|
|
800
|
+
state: executionContext.state,
|
|
801
|
+
setState: (state) => {
|
|
802
|
+
executionContext.state = state;
|
|
803
|
+
},
|
|
804
|
+
retryCount: -1,
|
|
805
|
+
tracingContext: {
|
|
806
|
+
currentSpan: sleepSpan
|
|
807
|
+
},
|
|
808
|
+
getInitData: () => stepResults?.input,
|
|
809
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
810
|
+
// TODO: this function shouldn't have suspend probably?
|
|
811
|
+
suspend: async (_suspendPayload) => {
|
|
812
|
+
},
|
|
813
|
+
bail: () => {
|
|
814
|
+
},
|
|
815
|
+
abort: () => {
|
|
816
|
+
abortController?.abort();
|
|
817
|
+
},
|
|
818
|
+
[EMITTER_SYMBOL]: emitter,
|
|
819
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
820
|
+
engine: { step: this.inngestStep },
|
|
821
|
+
abortSignal: abortController?.signal,
|
|
822
|
+
writer: new ToolStream(
|
|
823
|
+
{
|
|
824
|
+
prefix: "workflow-step",
|
|
825
|
+
callId: stepCallId,
|
|
826
|
+
name: "sleep",
|
|
827
|
+
runId
|
|
828
|
+
},
|
|
829
|
+
writableStream
|
|
830
|
+
)
|
|
715
831
|
},
|
|
716
|
-
|
|
832
|
+
{
|
|
833
|
+
paramName: "runCount",
|
|
834
|
+
deprecationMessage: runCountDeprecationMessage,
|
|
835
|
+
logger: this.logger
|
|
836
|
+
}
|
|
717
837
|
)
|
|
718
|
-
|
|
838
|
+
);
|
|
719
839
|
});
|
|
720
840
|
sleepSpan?.update({
|
|
721
841
|
attributes: {
|
|
@@ -739,69 +859,76 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
739
859
|
stepResults,
|
|
740
860
|
emitter,
|
|
741
861
|
abortController,
|
|
742
|
-
|
|
862
|
+
requestContext,
|
|
743
863
|
executionContext,
|
|
744
864
|
writableStream,
|
|
745
865
|
tracingContext
|
|
746
866
|
}) {
|
|
747
867
|
let { date, fn } = entry;
|
|
748
868
|
const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
749
|
-
type:
|
|
869
|
+
type: SpanType.WORKFLOW_SLEEP,
|
|
750
870
|
name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
|
|
751
871
|
attributes: {
|
|
752
872
|
untilDate: date,
|
|
753
873
|
durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
|
|
754
874
|
sleepType: fn ? "dynamic" : "fixed"
|
|
755
|
-
}
|
|
875
|
+
},
|
|
876
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
756
877
|
});
|
|
757
878
|
if (fn) {
|
|
758
879
|
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
759
880
|
const stepCallId = randomUUID();
|
|
760
|
-
return await fn(
|
|
761
|
-
|
|
762
|
-
workflowId,
|
|
763
|
-
mastra: this.mastra,
|
|
764
|
-
runtimeContext,
|
|
765
|
-
inputData: prevOutput,
|
|
766
|
-
runCount: -1,
|
|
767
|
-
tracingContext: {
|
|
768
|
-
currentSpan: sleepUntilSpan
|
|
769
|
-
},
|
|
770
|
-
getInitData: () => stepResults?.input,
|
|
771
|
-
getStepResult: (step) => {
|
|
772
|
-
if (!step?.id) {
|
|
773
|
-
return null;
|
|
774
|
-
}
|
|
775
|
-
const result = stepResults[step.id];
|
|
776
|
-
if (result?.status === "success") {
|
|
777
|
-
return result.output;
|
|
778
|
-
}
|
|
779
|
-
return null;
|
|
780
|
-
},
|
|
781
|
-
// TODO: this function shouldn't have suspend probably?
|
|
782
|
-
suspend: async (_suspendPayload) => {
|
|
783
|
-
},
|
|
784
|
-
bail: () => {
|
|
785
|
-
},
|
|
786
|
-
abort: () => {
|
|
787
|
-
abortController?.abort();
|
|
788
|
-
},
|
|
789
|
-
[EMITTER_SYMBOL]: emitter,
|
|
790
|
-
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
791
|
-
// TODO: add streamVNext support
|
|
792
|
-
engine: { step: this.inngestStep },
|
|
793
|
-
abortSignal: abortController?.signal,
|
|
794
|
-
writer: new ToolStream(
|
|
881
|
+
return await fn(
|
|
882
|
+
createDeprecationProxy(
|
|
795
883
|
{
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
884
|
+
runId,
|
|
885
|
+
workflowId,
|
|
886
|
+
mastra: this.mastra,
|
|
887
|
+
requestContext,
|
|
888
|
+
inputData: prevOutput,
|
|
889
|
+
state: executionContext.state,
|
|
890
|
+
setState: (state) => {
|
|
891
|
+
executionContext.state = state;
|
|
892
|
+
},
|
|
893
|
+
retryCount: -1,
|
|
894
|
+
tracingContext: {
|
|
895
|
+
currentSpan: sleepUntilSpan
|
|
896
|
+
},
|
|
897
|
+
getInitData: () => stepResults?.input,
|
|
898
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
899
|
+
// TODO: this function shouldn't have suspend probably?
|
|
900
|
+
suspend: async (_suspendPayload) => {
|
|
901
|
+
},
|
|
902
|
+
bail: () => {
|
|
903
|
+
},
|
|
904
|
+
abort: () => {
|
|
905
|
+
abortController?.abort();
|
|
906
|
+
},
|
|
907
|
+
[EMITTER_SYMBOL]: emitter,
|
|
908
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
909
|
+
engine: { step: this.inngestStep },
|
|
910
|
+
abortSignal: abortController?.signal,
|
|
911
|
+
writer: new ToolStream(
|
|
912
|
+
{
|
|
913
|
+
prefix: "workflow-step",
|
|
914
|
+
callId: stepCallId,
|
|
915
|
+
name: "sleep",
|
|
916
|
+
runId
|
|
917
|
+
},
|
|
918
|
+
writableStream
|
|
919
|
+
)
|
|
800
920
|
},
|
|
801
|
-
|
|
921
|
+
{
|
|
922
|
+
paramName: "runCount",
|
|
923
|
+
deprecationMessage: runCountDeprecationMessage,
|
|
924
|
+
logger: this.logger
|
|
925
|
+
}
|
|
802
926
|
)
|
|
803
|
-
|
|
927
|
+
);
|
|
804
928
|
});
|
|
929
|
+
if (date && !(date instanceof Date)) {
|
|
930
|
+
date = new Date(date);
|
|
931
|
+
}
|
|
805
932
|
const time = !date ? 0 : date.getTime() - Date.now();
|
|
806
933
|
sleepUntilSpan?.update({
|
|
807
934
|
attributes: {
|
|
@@ -839,50 +966,35 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
839
966
|
prevOutput,
|
|
840
967
|
emitter,
|
|
841
968
|
abortController,
|
|
842
|
-
|
|
969
|
+
requestContext,
|
|
843
970
|
tracingContext,
|
|
844
971
|
writableStream,
|
|
845
972
|
disableScorers
|
|
846
973
|
}) {
|
|
847
|
-
const
|
|
974
|
+
const stepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
848
975
|
name: `workflow step: '${step.id}'`,
|
|
849
|
-
type:
|
|
976
|
+
type: SpanType.WORKFLOW_STEP,
|
|
850
977
|
input: prevOutput,
|
|
851
978
|
attributes: {
|
|
852
979
|
stepId: step.id
|
|
853
|
-
}
|
|
980
|
+
},
|
|
981
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
982
|
+
});
|
|
983
|
+
const { inputData, validationError } = await validateStepInput({
|
|
984
|
+
prevOutput,
|
|
985
|
+
step,
|
|
986
|
+
validateInputs: this.options?.validateInputs ?? false
|
|
854
987
|
});
|
|
855
988
|
const startedAt = await this.inngestStep.run(
|
|
856
989
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
857
990
|
async () => {
|
|
858
991
|
const startedAt2 = Date.now();
|
|
859
992
|
await emitter.emit("watch", {
|
|
860
|
-
type: "watch",
|
|
861
|
-
payload: {
|
|
862
|
-
currentStep: {
|
|
863
|
-
id: step.id,
|
|
864
|
-
status: "running"
|
|
865
|
-
},
|
|
866
|
-
workflowState: {
|
|
867
|
-
status: "running",
|
|
868
|
-
steps: {
|
|
869
|
-
...stepResults,
|
|
870
|
-
[step.id]: {
|
|
871
|
-
status: "running"
|
|
872
|
-
}
|
|
873
|
-
},
|
|
874
|
-
result: null,
|
|
875
|
-
error: null
|
|
876
|
-
}
|
|
877
|
-
},
|
|
878
|
-
eventTimestamp: Date.now()
|
|
879
|
-
});
|
|
880
|
-
await emitter.emit("watch-v2", {
|
|
881
993
|
type: "workflow-step-start",
|
|
882
994
|
payload: {
|
|
883
995
|
id: step.id,
|
|
884
996
|
status: "running",
|
|
885
|
-
payload:
|
|
997
|
+
payload: inputData,
|
|
886
998
|
startedAt: startedAt2
|
|
887
999
|
}
|
|
888
1000
|
});
|
|
@@ -893,61 +1005,66 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
893
1005
|
const isResume = !!resume?.steps?.length;
|
|
894
1006
|
let result;
|
|
895
1007
|
let runId;
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
1008
|
+
try {
|
|
1009
|
+
if (isResume) {
|
|
1010
|
+
runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? randomUUID();
|
|
1011
|
+
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
1012
|
+
workflowName: step.id,
|
|
1013
|
+
runId
|
|
1014
|
+
});
|
|
1015
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1016
|
+
function: step.getFunction(),
|
|
1017
|
+
data: {
|
|
1018
|
+
inputData,
|
|
1019
|
+
initialState: executionContext.state ?? snapshot?.value ?? {},
|
|
908
1020
|
runId,
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
1021
|
+
resume: {
|
|
1022
|
+
runId,
|
|
1023
|
+
steps: resume.steps.slice(1),
|
|
1024
|
+
stepResults: snapshot?.context,
|
|
1025
|
+
resumePayload: resume.resumePayload,
|
|
1026
|
+
// @ts-ignore
|
|
1027
|
+
resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
|
|
1028
|
+
},
|
|
1029
|
+
outputOptions: { includeState: true }
|
|
914
1030
|
}
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
1031
|
+
});
|
|
1032
|
+
result = invokeResp.result;
|
|
1033
|
+
runId = invokeResp.runId;
|
|
1034
|
+
executionContext.state = invokeResp.result.state;
|
|
1035
|
+
} else {
|
|
1036
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1037
|
+
function: step.getFunction(),
|
|
1038
|
+
data: {
|
|
1039
|
+
inputData,
|
|
1040
|
+
initialState: executionContext.state ?? {},
|
|
1041
|
+
outputOptions: { includeState: true }
|
|
1042
|
+
}
|
|
1043
|
+
});
|
|
1044
|
+
result = invokeResp.result;
|
|
1045
|
+
runId = invokeResp.runId;
|
|
1046
|
+
executionContext.state = invokeResp.result.state;
|
|
1047
|
+
}
|
|
1048
|
+
} catch (e) {
|
|
1049
|
+
const errorCause = e?.cause;
|
|
1050
|
+
if (errorCause && typeof errorCause === "object") {
|
|
1051
|
+
result = errorCause;
|
|
1052
|
+
runId = errorCause.runId || randomUUID();
|
|
1053
|
+
} else {
|
|
1054
|
+
runId = randomUUID();
|
|
1055
|
+
result = {
|
|
1056
|
+
status: "failed",
|
|
1057
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
1058
|
+
steps: {},
|
|
1059
|
+
input: inputData
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
928
1062
|
}
|
|
929
1063
|
const res = await this.inngestStep.run(
|
|
930
1064
|
`workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
|
|
931
1065
|
async () => {
|
|
932
1066
|
if (result.status === "failed") {
|
|
933
1067
|
await emitter.emit("watch", {
|
|
934
|
-
type: "watch",
|
|
935
|
-
payload: {
|
|
936
|
-
currentStep: {
|
|
937
|
-
id: step.id,
|
|
938
|
-
status: "failed",
|
|
939
|
-
error: result?.error
|
|
940
|
-
},
|
|
941
|
-
workflowState: {
|
|
942
|
-
status: "running",
|
|
943
|
-
steps: stepResults,
|
|
944
|
-
result: null,
|
|
945
|
-
error: null
|
|
946
|
-
}
|
|
947
|
-
},
|
|
948
|
-
eventTimestamp: Date.now()
|
|
949
|
-
});
|
|
950
|
-
await emitter.emit("watch-v2", {
|
|
951
1068
|
type: "workflow-step-result",
|
|
952
1069
|
payload: {
|
|
953
1070
|
id: step.id,
|
|
@@ -963,26 +1080,9 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
963
1080
|
return stepRes2?.status === "suspended";
|
|
964
1081
|
});
|
|
965
1082
|
for (const [stepName, stepResult] of suspendedSteps) {
|
|
966
|
-
const suspendPath = [stepName, ...stepResult?.
|
|
1083
|
+
const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
|
|
967
1084
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
968
1085
|
await emitter.emit("watch", {
|
|
969
|
-
type: "watch",
|
|
970
|
-
payload: {
|
|
971
|
-
currentStep: {
|
|
972
|
-
id: step.id,
|
|
973
|
-
status: "suspended",
|
|
974
|
-
payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
|
|
975
|
-
},
|
|
976
|
-
workflowState: {
|
|
977
|
-
status: "running",
|
|
978
|
-
steps: stepResults,
|
|
979
|
-
result: null,
|
|
980
|
-
error: null
|
|
981
|
-
}
|
|
982
|
-
},
|
|
983
|
-
eventTimestamp: Date.now()
|
|
984
|
-
});
|
|
985
|
-
await emitter.emit("watch-v2", {
|
|
986
1086
|
type: "workflow-step-suspended",
|
|
987
1087
|
payload: {
|
|
988
1088
|
id: step.id,
|
|
@@ -993,27 +1093,14 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
993
1093
|
executionContext,
|
|
994
1094
|
result: {
|
|
995
1095
|
status: "suspended",
|
|
996
|
-
payload:
|
|
1096
|
+
payload: stepResult.payload,
|
|
1097
|
+
suspendPayload: {
|
|
1098
|
+
...stepResult?.suspendPayload,
|
|
1099
|
+
__workflow_meta: { runId, path: suspendPath }
|
|
1100
|
+
}
|
|
997
1101
|
}
|
|
998
1102
|
};
|
|
999
1103
|
}
|
|
1000
|
-
await emitter.emit("watch", {
|
|
1001
|
-
type: "watch",
|
|
1002
|
-
payload: {
|
|
1003
|
-
currentStep: {
|
|
1004
|
-
id: step.id,
|
|
1005
|
-
status: "suspended",
|
|
1006
|
-
payload: {}
|
|
1007
|
-
},
|
|
1008
|
-
workflowState: {
|
|
1009
|
-
status: "running",
|
|
1010
|
-
steps: stepResults,
|
|
1011
|
-
result: null,
|
|
1012
|
-
error: null
|
|
1013
|
-
}
|
|
1014
|
-
},
|
|
1015
|
-
eventTimestamp: Date.now()
|
|
1016
|
-
});
|
|
1017
1104
|
return {
|
|
1018
1105
|
executionContext,
|
|
1019
1106
|
result: {
|
|
@@ -1023,23 +1110,6 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1023
1110
|
};
|
|
1024
1111
|
}
|
|
1025
1112
|
await emitter.emit("watch", {
|
|
1026
|
-
type: "watch",
|
|
1027
|
-
payload: {
|
|
1028
|
-
currentStep: {
|
|
1029
|
-
id: step.id,
|
|
1030
|
-
status: "success",
|
|
1031
|
-
output: result?.result
|
|
1032
|
-
},
|
|
1033
|
-
workflowState: {
|
|
1034
|
-
status: "running",
|
|
1035
|
-
steps: stepResults,
|
|
1036
|
-
result: null,
|
|
1037
|
-
error: null
|
|
1038
|
-
}
|
|
1039
|
-
},
|
|
1040
|
-
eventTimestamp: Date.now()
|
|
1041
|
-
});
|
|
1042
|
-
await emitter.emit("watch-v2", {
|
|
1043
1113
|
type: "workflow-step-result",
|
|
1044
1114
|
payload: {
|
|
1045
1115
|
id: step.id,
|
|
@@ -1047,7 +1117,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1047
1117
|
output: result?.result
|
|
1048
1118
|
}
|
|
1049
1119
|
});
|
|
1050
|
-
await emitter.emit("watch
|
|
1120
|
+
await emitter.emit("watch", {
|
|
1051
1121
|
type: "workflow-step-finish",
|
|
1052
1122
|
payload: {
|
|
1053
1123
|
id: step.id,
|
|
@@ -1058,159 +1128,196 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1058
1128
|
}
|
|
1059
1129
|
);
|
|
1060
1130
|
Object.assign(executionContext, res.executionContext);
|
|
1061
|
-
return
|
|
1131
|
+
return {
|
|
1132
|
+
...res.result,
|
|
1133
|
+
startedAt,
|
|
1134
|
+
endedAt: Date.now(),
|
|
1135
|
+
payload: inputData,
|
|
1136
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1137
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1138
|
+
};
|
|
1062
1139
|
}
|
|
1063
|
-
const
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1140
|
+
const stepCallId = randomUUID();
|
|
1141
|
+
let stepRes;
|
|
1142
|
+
try {
|
|
1143
|
+
stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
1144
|
+
let execResults;
|
|
1145
|
+
let suspended;
|
|
1146
|
+
let bailed;
|
|
1147
|
+
try {
|
|
1148
|
+
if (validationError) {
|
|
1149
|
+
throw validationError;
|
|
1150
|
+
}
|
|
1151
|
+
const result = await step.execute({
|
|
1152
|
+
runId: executionContext.runId,
|
|
1153
|
+
mastra: this.mastra,
|
|
1154
|
+
requestContext,
|
|
1155
|
+
writer: new ToolStream(
|
|
1156
|
+
{
|
|
1157
|
+
prefix: "workflow-step",
|
|
1158
|
+
callId: stepCallId,
|
|
1159
|
+
name: step.id,
|
|
1160
|
+
runId: executionContext.runId
|
|
1161
|
+
},
|
|
1162
|
+
writableStream
|
|
1163
|
+
),
|
|
1164
|
+
state: executionContext?.state ?? {},
|
|
1165
|
+
setState: (state) => {
|
|
1166
|
+
executionContext.state = state;
|
|
1167
|
+
},
|
|
1168
|
+
inputData,
|
|
1169
|
+
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
|
|
1170
|
+
tracingContext: {
|
|
1171
|
+
currentSpan: stepSpan
|
|
1172
|
+
},
|
|
1173
|
+
getInitData: () => stepResults?.input,
|
|
1174
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
1175
|
+
suspend: async (suspendPayload, suspendOptions) => {
|
|
1176
|
+
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1177
|
+
if (suspendOptions?.resumeLabel) {
|
|
1178
|
+
const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
|
|
1179
|
+
for (const label of resumeLabel) {
|
|
1180
|
+
executionContext.resumeLabels[label] = {
|
|
1181
|
+
stepId: step.id,
|
|
1182
|
+
foreachIndex: executionContext.foreachIndex
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
suspended = { payload: suspendPayload };
|
|
1187
|
+
},
|
|
1188
|
+
bail: (result2) => {
|
|
1189
|
+
bailed = { payload: result2 };
|
|
1190
|
+
},
|
|
1191
|
+
resume: {
|
|
1192
|
+
steps: resume?.steps?.slice(1) || [],
|
|
1193
|
+
resumePayload: resume?.resumePayload,
|
|
1194
|
+
// @ts-ignore
|
|
1195
|
+
runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
|
|
1196
|
+
},
|
|
1197
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1198
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1199
|
+
engine: {
|
|
1200
|
+
step: this.inngestStep
|
|
1201
|
+
},
|
|
1202
|
+
abortSignal: abortController.signal
|
|
1203
|
+
});
|
|
1204
|
+
const endedAt = Date.now();
|
|
1205
|
+
execResults = {
|
|
1206
|
+
status: "success",
|
|
1207
|
+
output: result,
|
|
1208
|
+
startedAt,
|
|
1209
|
+
endedAt,
|
|
1210
|
+
payload: inputData,
|
|
1211
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1212
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1213
|
+
};
|
|
1214
|
+
} catch (e) {
|
|
1215
|
+
const stepFailure = {
|
|
1216
|
+
status: "failed",
|
|
1217
|
+
payload: inputData,
|
|
1218
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1219
|
+
endedAt: Date.now(),
|
|
1220
|
+
startedAt,
|
|
1221
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1222
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1223
|
+
};
|
|
1224
|
+
execResults = stepFailure;
|
|
1225
|
+
const fallbackErrorMessage = `Step ${step.id} failed`;
|
|
1226
|
+
stepSpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
|
|
1227
|
+
throw new RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
|
|
1228
|
+
cause: execResults
|
|
1229
|
+
});
|
|
1230
|
+
}
|
|
1231
|
+
if (suspended) {
|
|
1232
|
+
execResults = {
|
|
1233
|
+
status: "suspended",
|
|
1234
|
+
suspendPayload: suspended.payload,
|
|
1235
|
+
payload: inputData,
|
|
1236
|
+
suspendedAt: Date.now(),
|
|
1237
|
+
startedAt,
|
|
1238
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1239
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1240
|
+
};
|
|
1241
|
+
} else if (bailed) {
|
|
1242
|
+
execResults = {
|
|
1243
|
+
status: "bailed",
|
|
1244
|
+
output: bailed.payload,
|
|
1245
|
+
payload: inputData,
|
|
1246
|
+
endedAt: Date.now(),
|
|
1247
|
+
startedAt
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
if (execResults.status === "suspended") {
|
|
1251
|
+
await emitter.emit("watch", {
|
|
1252
|
+
type: "workflow-step-suspended",
|
|
1253
|
+
payload: {
|
|
1254
|
+
id: step.id,
|
|
1255
|
+
...execResults
|
|
1083
1256
|
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
engine: {
|
|
1101
|
-
step: this.inngestStep
|
|
1102
|
-
},
|
|
1103
|
-
abortSignal: abortController.signal
|
|
1104
|
-
});
|
|
1105
|
-
const endedAt = Date.now();
|
|
1106
|
-
execResults = {
|
|
1107
|
-
status: "success",
|
|
1108
|
-
output: result,
|
|
1109
|
-
startedAt,
|
|
1110
|
-
endedAt,
|
|
1111
|
-
payload: prevOutput,
|
|
1112
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1113
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1114
|
-
};
|
|
1115
|
-
} catch (e) {
|
|
1116
|
-
execResults = {
|
|
1117
|
-
status: "failed",
|
|
1118
|
-
payload: prevOutput,
|
|
1119
|
-
error: e instanceof Error ? e.message : String(e),
|
|
1120
|
-
endedAt: Date.now(),
|
|
1121
|
-
startedAt,
|
|
1122
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1123
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1124
|
-
};
|
|
1125
|
-
}
|
|
1126
|
-
if (suspended) {
|
|
1127
|
-
execResults = {
|
|
1128
|
-
status: "suspended",
|
|
1129
|
-
suspendedPayload: suspended.payload,
|
|
1130
|
-
payload: prevOutput,
|
|
1131
|
-
suspendedAt: Date.now(),
|
|
1132
|
-
startedAt,
|
|
1133
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1134
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1135
|
-
};
|
|
1136
|
-
} else if (bailed) {
|
|
1137
|
-
execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
1138
|
-
}
|
|
1139
|
-
if (execResults.status === "failed") {
|
|
1140
|
-
if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
|
|
1141
|
-
const error = new Error(execResults.error);
|
|
1142
|
-
stepAISpan?.error({ error });
|
|
1143
|
-
throw error;
|
|
1257
|
+
});
|
|
1258
|
+
} else {
|
|
1259
|
+
await emitter.emit("watch", {
|
|
1260
|
+
type: "workflow-step-result",
|
|
1261
|
+
payload: {
|
|
1262
|
+
id: step.id,
|
|
1263
|
+
...execResults
|
|
1264
|
+
}
|
|
1265
|
+
});
|
|
1266
|
+
await emitter.emit("watch", {
|
|
1267
|
+
type: "workflow-step-finish",
|
|
1268
|
+
payload: {
|
|
1269
|
+
id: step.id,
|
|
1270
|
+
metadata: {}
|
|
1271
|
+
}
|
|
1272
|
+
});
|
|
1144
1273
|
}
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
type: "watch",
|
|
1148
|
-
payload: {
|
|
1149
|
-
currentStep: {
|
|
1150
|
-
id: step.id,
|
|
1151
|
-
...execResults
|
|
1152
|
-
},
|
|
1153
|
-
workflowState: {
|
|
1154
|
-
status: "running",
|
|
1155
|
-
steps: { ...stepResults, [step.id]: execResults },
|
|
1156
|
-
result: null,
|
|
1157
|
-
error: null
|
|
1158
|
-
}
|
|
1159
|
-
},
|
|
1160
|
-
eventTimestamp: Date.now()
|
|
1274
|
+
stepSpan?.end({ output: execResults });
|
|
1275
|
+
return { result: execResults, executionContext, stepResults };
|
|
1161
1276
|
});
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
payload: {
|
|
1181
|
-
id: step.id,
|
|
1182
|
-
metadata: {}
|
|
1183
|
-
}
|
|
1184
|
-
});
|
|
1185
|
-
}
|
|
1186
|
-
stepAISpan?.end({ output: execResults });
|
|
1187
|
-
return { result: execResults, executionContext, stepResults };
|
|
1188
|
-
});
|
|
1189
|
-
if (disableScorers !== false) {
|
|
1277
|
+
} catch (e) {
|
|
1278
|
+
const stepFailure = e instanceof Error ? e?.cause : {
|
|
1279
|
+
status: "failed",
|
|
1280
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1281
|
+
payload: inputData,
|
|
1282
|
+
startedAt,
|
|
1283
|
+
endedAt: Date.now()
|
|
1284
|
+
};
|
|
1285
|
+
stepRes = {
|
|
1286
|
+
result: stepFailure,
|
|
1287
|
+
executionContext,
|
|
1288
|
+
stepResults: {
|
|
1289
|
+
...stepResults,
|
|
1290
|
+
[step.id]: stepFailure
|
|
1291
|
+
}
|
|
1292
|
+
};
|
|
1293
|
+
}
|
|
1294
|
+
if (disableScorers !== false && stepRes.result.status === "success") {
|
|
1190
1295
|
await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
|
|
1191
1296
|
if (step.scorers) {
|
|
1192
1297
|
await this.runScorers({
|
|
1193
1298
|
scorers: step.scorers,
|
|
1194
1299
|
runId: executionContext.runId,
|
|
1195
|
-
input:
|
|
1300
|
+
input: inputData,
|
|
1196
1301
|
output: stepRes.result,
|
|
1197
1302
|
workflowId: executionContext.workflowId,
|
|
1198
1303
|
stepId: step.id,
|
|
1199
|
-
|
|
1304
|
+
requestContext,
|
|
1200
1305
|
disableScorers,
|
|
1201
|
-
tracingContext: { currentSpan:
|
|
1306
|
+
tracingContext: { currentSpan: stepSpan }
|
|
1202
1307
|
});
|
|
1203
1308
|
}
|
|
1204
1309
|
});
|
|
1205
1310
|
}
|
|
1206
1311
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
1207
1312
|
Object.assign(stepResults, stepRes.stepResults);
|
|
1313
|
+
executionContext.state = stepRes.executionContext.state;
|
|
1208
1314
|
return stepRes.result;
|
|
1209
1315
|
}
|
|
1210
1316
|
async persistStepUpdate({
|
|
1211
1317
|
workflowId,
|
|
1212
1318
|
runId,
|
|
1213
1319
|
stepResults,
|
|
1320
|
+
resourceId,
|
|
1214
1321
|
executionContext,
|
|
1215
1322
|
serializedStepGraph,
|
|
1216
1323
|
workflowStatus,
|
|
@@ -1220,15 +1327,21 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1220
1327
|
await this.inngestStep.run(
|
|
1221
1328
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
1222
1329
|
async () => {
|
|
1330
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({ stepResults, workflowStatus });
|
|
1331
|
+
if (!shouldPersistSnapshot) {
|
|
1332
|
+
return;
|
|
1333
|
+
}
|
|
1223
1334
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
1224
1335
|
workflowName: workflowId,
|
|
1225
1336
|
runId,
|
|
1337
|
+
resourceId,
|
|
1226
1338
|
snapshot: {
|
|
1227
1339
|
runId,
|
|
1228
|
-
value:
|
|
1340
|
+
value: executionContext.state,
|
|
1229
1341
|
context: stepResults,
|
|
1230
1342
|
activePaths: [],
|
|
1231
1343
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1344
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1232
1345
|
waitingPaths: {},
|
|
1233
1346
|
serializedStepGraph,
|
|
1234
1347
|
status: workflowStatus,
|
|
@@ -1246,85 +1359,88 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1246
1359
|
runId,
|
|
1247
1360
|
entry,
|
|
1248
1361
|
prevOutput,
|
|
1249
|
-
prevStep,
|
|
1250
1362
|
stepResults,
|
|
1251
|
-
serializedStepGraph,
|
|
1252
1363
|
resume,
|
|
1253
1364
|
executionContext,
|
|
1254
1365
|
emitter,
|
|
1255
1366
|
abortController,
|
|
1256
|
-
|
|
1367
|
+
requestContext,
|
|
1257
1368
|
writableStream,
|
|
1258
1369
|
disableScorers,
|
|
1259
1370
|
tracingContext
|
|
1260
1371
|
}) {
|
|
1261
1372
|
const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1262
|
-
type:
|
|
1373
|
+
type: SpanType.WORKFLOW_CONDITIONAL,
|
|
1263
1374
|
name: `conditional: '${entry.conditions.length} conditions'`,
|
|
1264
1375
|
input: prevOutput,
|
|
1265
1376
|
attributes: {
|
|
1266
1377
|
conditionCount: entry.conditions.length
|
|
1267
|
-
}
|
|
1378
|
+
},
|
|
1379
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1268
1380
|
});
|
|
1269
1381
|
let execResults;
|
|
1270
1382
|
const truthyIndexes = (await Promise.all(
|
|
1271
1383
|
entry.conditions.map(
|
|
1272
1384
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1273
1385
|
const evalSpan = conditionalSpan?.createChildSpan({
|
|
1274
|
-
type:
|
|
1386
|
+
type: SpanType.WORKFLOW_CONDITIONAL_EVAL,
|
|
1275
1387
|
name: `condition: '${index}'`,
|
|
1276
1388
|
input: prevOutput,
|
|
1277
1389
|
attributes: {
|
|
1278
1390
|
conditionIndex: index
|
|
1279
|
-
}
|
|
1391
|
+
},
|
|
1392
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1280
1393
|
});
|
|
1281
1394
|
try {
|
|
1282
|
-
const result = await cond(
|
|
1283
|
-
|
|
1284
|
-
workflowId,
|
|
1285
|
-
mastra: this.mastra,
|
|
1286
|
-
runtimeContext,
|
|
1287
|
-
runCount: -1,
|
|
1288
|
-
inputData: prevOutput,
|
|
1289
|
-
tracingContext: {
|
|
1290
|
-
currentSpan: evalSpan
|
|
1291
|
-
},
|
|
1292
|
-
getInitData: () => stepResults?.input,
|
|
1293
|
-
getStepResult: (step) => {
|
|
1294
|
-
if (!step?.id) {
|
|
1295
|
-
return null;
|
|
1296
|
-
}
|
|
1297
|
-
const result2 = stepResults[step.id];
|
|
1298
|
-
if (result2?.status === "success") {
|
|
1299
|
-
return result2.output;
|
|
1300
|
-
}
|
|
1301
|
-
return null;
|
|
1302
|
-
},
|
|
1303
|
-
// TODO: this function shouldn't have suspend probably?
|
|
1304
|
-
suspend: async (_suspendPayload) => {
|
|
1305
|
-
},
|
|
1306
|
-
bail: () => {
|
|
1307
|
-
},
|
|
1308
|
-
abort: () => {
|
|
1309
|
-
abortController.abort();
|
|
1310
|
-
},
|
|
1311
|
-
[EMITTER_SYMBOL]: emitter,
|
|
1312
|
-
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1313
|
-
// TODO: add streamVNext support
|
|
1314
|
-
engine: {
|
|
1315
|
-
step: this.inngestStep
|
|
1316
|
-
},
|
|
1317
|
-
abortSignal: abortController.signal,
|
|
1318
|
-
writer: new ToolStream(
|
|
1395
|
+
const result = await cond(
|
|
1396
|
+
createDeprecationProxy(
|
|
1319
1397
|
{
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1398
|
+
runId,
|
|
1399
|
+
workflowId,
|
|
1400
|
+
mastra: this.mastra,
|
|
1401
|
+
requestContext,
|
|
1402
|
+
retryCount: -1,
|
|
1403
|
+
inputData: prevOutput,
|
|
1404
|
+
state: executionContext.state,
|
|
1405
|
+
setState: (state) => {
|
|
1406
|
+
executionContext.state = state;
|
|
1407
|
+
},
|
|
1408
|
+
tracingContext: {
|
|
1409
|
+
currentSpan: evalSpan
|
|
1410
|
+
},
|
|
1411
|
+
getInitData: () => stepResults?.input,
|
|
1412
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
1413
|
+
// TODO: this function shouldn't have suspend probably?
|
|
1414
|
+
suspend: async (_suspendPayload) => {
|
|
1415
|
+
},
|
|
1416
|
+
bail: () => {
|
|
1417
|
+
},
|
|
1418
|
+
abort: () => {
|
|
1419
|
+
abortController.abort();
|
|
1420
|
+
},
|
|
1421
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1422
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1423
|
+
engine: {
|
|
1424
|
+
step: this.inngestStep
|
|
1425
|
+
},
|
|
1426
|
+
abortSignal: abortController.signal,
|
|
1427
|
+
writer: new ToolStream(
|
|
1428
|
+
{
|
|
1429
|
+
prefix: "workflow-step",
|
|
1430
|
+
callId: randomUUID(),
|
|
1431
|
+
name: "conditional",
|
|
1432
|
+
runId
|
|
1433
|
+
},
|
|
1434
|
+
writableStream
|
|
1435
|
+
)
|
|
1324
1436
|
},
|
|
1325
|
-
|
|
1437
|
+
{
|
|
1438
|
+
paramName: "runCount",
|
|
1439
|
+
deprecationMessage: runCountDeprecationMessage,
|
|
1440
|
+
logger: this.logger
|
|
1441
|
+
}
|
|
1326
1442
|
)
|
|
1327
|
-
|
|
1443
|
+
);
|
|
1328
1444
|
evalSpan?.end({
|
|
1329
1445
|
output: result,
|
|
1330
1446
|
attributes: {
|
|
@@ -1352,13 +1468,14 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1352
1468
|
}
|
|
1353
1469
|
});
|
|
1354
1470
|
const results = await Promise.all(
|
|
1355
|
-
stepsToRun.map(
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1471
|
+
stepsToRun.map(async (step, index) => {
|
|
1472
|
+
const currStepResult = stepResults[step.step.id];
|
|
1473
|
+
if (currStepResult && currStepResult.status === "success") {
|
|
1474
|
+
return currStepResult;
|
|
1475
|
+
}
|
|
1476
|
+
const result = await this.executeStep({
|
|
1477
|
+
step: step.step,
|
|
1478
|
+
prevOutput,
|
|
1362
1479
|
stepResults,
|
|
1363
1480
|
resume,
|
|
1364
1481
|
executionContext: {
|
|
@@ -1366,31 +1483,34 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1366
1483
|
runId,
|
|
1367
1484
|
executionPath: [...executionContext.executionPath, index],
|
|
1368
1485
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1486
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1369
1487
|
retryConfig: executionContext.retryConfig,
|
|
1370
|
-
|
|
1488
|
+
state: executionContext.state
|
|
1371
1489
|
},
|
|
1372
1490
|
emitter,
|
|
1373
1491
|
abortController,
|
|
1374
|
-
|
|
1492
|
+
requestContext,
|
|
1375
1493
|
writableStream,
|
|
1376
1494
|
disableScorers,
|
|
1377
1495
|
tracingContext: {
|
|
1378
1496
|
currentSpan: conditionalSpan
|
|
1379
1497
|
}
|
|
1380
|
-
})
|
|
1381
|
-
|
|
1498
|
+
});
|
|
1499
|
+
stepResults[step.step.id] = result;
|
|
1500
|
+
return result;
|
|
1501
|
+
})
|
|
1382
1502
|
);
|
|
1383
|
-
const hasFailed = results.find((result) => result.
|
|
1384
|
-
const hasSuspended = results.find((result) => result.
|
|
1503
|
+
const hasFailed = results.find((result) => result.status === "failed");
|
|
1504
|
+
const hasSuspended = results.find((result) => result.status === "suspended");
|
|
1385
1505
|
if (hasFailed) {
|
|
1386
|
-
execResults = { status: "failed", error: hasFailed.
|
|
1506
|
+
execResults = { status: "failed", error: hasFailed.error };
|
|
1387
1507
|
} else if (hasSuspended) {
|
|
1388
|
-
execResults = { status: "suspended",
|
|
1508
|
+
execResults = { status: "suspended", suspendPayload: hasSuspended.suspendPayload };
|
|
1389
1509
|
} else {
|
|
1390
1510
|
execResults = {
|
|
1391
1511
|
status: "success",
|
|
1392
1512
|
output: results.reduce((acc, result, index) => {
|
|
1393
|
-
if (result.
|
|
1513
|
+
if (result.status === "success") {
|
|
1394
1514
|
acc[stepsToRun[index].step.id] = result.output;
|
|
1395
1515
|
}
|
|
1396
1516
|
return acc;
|