@mastra/inngest 0.0.0-feat-tool-input-validation-20250731232758 → 0.0.0-feat-improve-processors-20251205191721
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 +1067 -3
- package/dist/execution-engine.d.ts +85 -0
- package/dist/execution-engine.d.ts.map +1 -0
- package/dist/index.cjs +855 -905
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +39 -7
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +860 -911
- package/dist/index.js.map +1 -0
- package/dist/run.d.ts +144 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/serve.d.ts +13 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/workflow.d.ts +51 -0
- package/dist/workflow.d.ts.map +1 -0
- package/package.json +39 -20
- package/dist/_tsup-dts-rollup.d.cts +0 -316
- package/dist/_tsup-dts-rollup.d.ts +0 -316
- package/dist/index.d.cts +0 -7
- package/docker-compose.yaml +0 -10
- package/eslint.config.js +0 -6
- package/src/index.test.ts +0 -7815
- package/src/index.ts +0 -1784
- package/tsconfig.json +0 -5
- package/vitest.config.ts +0 -14
package/dist/index.cjs
CHANGED
|
@@ -1,33 +1,322 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var crypto = require('crypto');
|
|
4
|
-
var realtime = require('@inngest/realtime');
|
|
5
|
-
var di = require('@mastra/core/di');
|
|
6
3
|
var tools = require('@mastra/core/tools');
|
|
7
4
|
var workflows = require('@mastra/core/workflows');
|
|
8
5
|
var _constants = require('@mastra/core/workflows/_constants');
|
|
9
|
-
var hono = require('inngest/hono');
|
|
10
6
|
var zod = require('zod');
|
|
7
|
+
var crypto = require('crypto');
|
|
8
|
+
var web = require('stream/web');
|
|
9
|
+
var di = require('@mastra/core/di');
|
|
10
|
+
var inngest = require('inngest');
|
|
11
|
+
var realtime = require('@inngest/realtime');
|
|
12
|
+
var stream = require('@mastra/core/stream');
|
|
13
|
+
var hono = require('inngest/hono');
|
|
11
14
|
|
|
12
15
|
// src/index.ts
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
17
|
+
inngestStep;
|
|
18
|
+
inngestAttempts;
|
|
19
|
+
constructor(mastra, inngestStep, inngestAttempts = 0, options) {
|
|
20
|
+
super({ mastra, options });
|
|
21
|
+
this.inngestStep = inngestStep;
|
|
22
|
+
this.inngestAttempts = inngestAttempts;
|
|
23
|
+
}
|
|
24
|
+
// =============================================================================
|
|
25
|
+
// Hook Overrides
|
|
26
|
+
// =============================================================================
|
|
27
|
+
/**
|
|
28
|
+
* Format errors with stack traces for better debugging in Inngest
|
|
29
|
+
*/
|
|
30
|
+
formatResultError(error, lastOutput) {
|
|
31
|
+
if (error instanceof Error) {
|
|
32
|
+
return error.stack ?? error.message;
|
|
33
|
+
}
|
|
34
|
+
const outputError = lastOutput?.error;
|
|
35
|
+
if (outputError instanceof Error) {
|
|
36
|
+
return outputError.message;
|
|
37
|
+
}
|
|
38
|
+
return outputError ?? error ?? "Unknown error";
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Detect InngestWorkflow instances for special nested workflow handling
|
|
42
|
+
*/
|
|
43
|
+
isNestedWorkflowStep(step) {
|
|
44
|
+
return step instanceof InngestWorkflow;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Inngest requires requestContext serialization for memoization.
|
|
48
|
+
* When steps are replayed, the original function doesn't re-execute,
|
|
49
|
+
* so requestContext modifications must be captured and restored.
|
|
50
|
+
*/
|
|
51
|
+
requiresDurableContextSerialization() {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Execute a step with retry logic for Inngest.
|
|
56
|
+
* Retries are handled via step-level retry (RetryAfterError thrown INSIDE step.run()).
|
|
57
|
+
* After retries exhausted, error propagates here and we return a failed result.
|
|
58
|
+
*/
|
|
59
|
+
async executeStepWithRetry(stepId, runStep, params) {
|
|
60
|
+
try {
|
|
61
|
+
const result = await this.wrapDurableOperation(stepId, runStep, { delay: params.delay });
|
|
62
|
+
return { ok: true, result };
|
|
63
|
+
} catch (e) {
|
|
64
|
+
const cause = e?.cause;
|
|
65
|
+
if (cause?.status === "failed") {
|
|
66
|
+
params.stepSpan?.error({
|
|
67
|
+
error: e,
|
|
68
|
+
attributes: { status: "failed" }
|
|
69
|
+
});
|
|
70
|
+
return { ok: false, error: cause };
|
|
71
|
+
}
|
|
72
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
73
|
+
params.stepSpan?.error({
|
|
74
|
+
error: e,
|
|
75
|
+
attributes: { status: "failed" }
|
|
76
|
+
});
|
|
77
|
+
return {
|
|
78
|
+
ok: false,
|
|
79
|
+
error: {
|
|
80
|
+
status: "failed",
|
|
81
|
+
error: `Error: ${errorMessage}`,
|
|
82
|
+
endedAt: Date.now()
|
|
21
83
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Use Inngest's sleep primitive for durability
|
|
89
|
+
*/
|
|
90
|
+
async executeSleepDuration(duration, sleepId, workflowId) {
|
|
91
|
+
await this.inngestStep.sleep(`workflow.${workflowId}.sleep.${sleepId}`, duration < 0 ? 0 : duration);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Use Inngest's sleepUntil primitive for durability
|
|
95
|
+
*/
|
|
96
|
+
async executeSleepUntilDate(date, sleepUntilId, workflowId) {
|
|
97
|
+
await this.inngestStep.sleepUntil(`workflow.${workflowId}.sleepUntil.${sleepUntilId}`, date);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Wrap durable operations in Inngest step.run() for durability.
|
|
101
|
+
* If retryConfig is provided, throws RetryAfterError INSIDE step.run() to trigger
|
|
102
|
+
* Inngest's step-level retry mechanism (not function-level retry).
|
|
103
|
+
*/
|
|
104
|
+
async wrapDurableOperation(operationId, operationFn, retryConfig) {
|
|
105
|
+
return this.inngestStep.run(operationId, async () => {
|
|
106
|
+
try {
|
|
107
|
+
return await operationFn();
|
|
108
|
+
} catch (e) {
|
|
109
|
+
if (retryConfig) {
|
|
110
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
111
|
+
throw new inngest.RetryAfterError(errorMessage, retryConfig.delay, {
|
|
112
|
+
cause: {
|
|
113
|
+
status: "failed",
|
|
114
|
+
error: `Error: ${errorMessage}`,
|
|
115
|
+
endedAt: Date.now()
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
throw e;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Provide Inngest step primitive in engine context
|
|
125
|
+
*/
|
|
126
|
+
getEngineContext() {
|
|
127
|
+
return { step: this.inngestStep };
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Execute nested InngestWorkflow using inngestStep.invoke() for durability.
|
|
131
|
+
* This MUST be called directly (not inside step.run()) due to Inngest constraints.
|
|
132
|
+
*/
|
|
133
|
+
async executeWorkflowStep(params) {
|
|
134
|
+
if (!(params.step instanceof InngestWorkflow)) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
const { step, stepResults, executionContext, resume, timeTravel, prevOutput, inputData, emitter, startedAt } = params;
|
|
138
|
+
const isResume = !!resume?.steps?.length;
|
|
139
|
+
let result;
|
|
140
|
+
let runId;
|
|
141
|
+
const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
|
|
142
|
+
try {
|
|
143
|
+
if (isResume) {
|
|
144
|
+
runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
145
|
+
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
146
|
+
workflowName: step.id,
|
|
147
|
+
runId
|
|
148
|
+
});
|
|
149
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
150
|
+
function: step.getFunction(),
|
|
151
|
+
data: {
|
|
152
|
+
inputData,
|
|
153
|
+
initialState: executionContext.state ?? snapshot?.value ?? {},
|
|
154
|
+
runId,
|
|
155
|
+
resume: {
|
|
156
|
+
runId,
|
|
157
|
+
steps: resume.steps.slice(1),
|
|
158
|
+
stepResults: snapshot?.context,
|
|
159
|
+
resumePayload: resume.resumePayload,
|
|
160
|
+
resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
|
|
161
|
+
},
|
|
162
|
+
outputOptions: { includeState: true }
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
result = invokeResp.result;
|
|
166
|
+
runId = invokeResp.runId;
|
|
167
|
+
executionContext.state = invokeResp.result.state;
|
|
168
|
+
} else if (isTimeTravel) {
|
|
169
|
+
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
170
|
+
workflowName: step.id,
|
|
171
|
+
runId: executionContext.runId
|
|
172
|
+
}) ?? { context: {} };
|
|
173
|
+
const timeTravelParams = workflows.createTimeTravelExecutionParams({
|
|
174
|
+
steps: timeTravel.steps.slice(1),
|
|
175
|
+
inputData: timeTravel.inputData,
|
|
176
|
+
resumeData: timeTravel.resumeData,
|
|
177
|
+
context: timeTravel.nestedStepResults?.[step.id] ?? {},
|
|
178
|
+
nestedStepsContext: timeTravel.nestedStepResults ?? {},
|
|
179
|
+
snapshot,
|
|
180
|
+
graph: step.buildExecutionGraph()
|
|
181
|
+
});
|
|
182
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
183
|
+
function: step.getFunction(),
|
|
184
|
+
data: {
|
|
185
|
+
timeTravel: timeTravelParams,
|
|
186
|
+
initialState: executionContext.state ?? {},
|
|
187
|
+
runId: executionContext.runId,
|
|
188
|
+
outputOptions: { includeState: true }
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
result = invokeResp.result;
|
|
192
|
+
runId = invokeResp.runId;
|
|
193
|
+
executionContext.state = invokeResp.result.state;
|
|
194
|
+
} else {
|
|
195
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
196
|
+
function: step.getFunction(),
|
|
197
|
+
data: {
|
|
198
|
+
inputData,
|
|
199
|
+
initialState: executionContext.state ?? {},
|
|
200
|
+
outputOptions: { includeState: true }
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
result = invokeResp.result;
|
|
204
|
+
runId = invokeResp.runId;
|
|
205
|
+
executionContext.state = invokeResp.result.state;
|
|
206
|
+
}
|
|
207
|
+
} catch (e) {
|
|
208
|
+
const errorCause = e?.cause;
|
|
209
|
+
if (errorCause && typeof errorCause === "object") {
|
|
210
|
+
result = errorCause;
|
|
211
|
+
runId = errorCause.runId || crypto.randomUUID();
|
|
212
|
+
} else {
|
|
213
|
+
runId = crypto.randomUUID();
|
|
214
|
+
result = {
|
|
215
|
+
status: "failed",
|
|
216
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
217
|
+
steps: {},
|
|
218
|
+
input: inputData
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const res = await this.inngestStep.run(
|
|
223
|
+
`workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
|
|
224
|
+
async () => {
|
|
225
|
+
if (result.status === "failed") {
|
|
226
|
+
await emitter.emit("watch", {
|
|
227
|
+
type: "workflow-step-result",
|
|
228
|
+
payload: {
|
|
229
|
+
id: step.id,
|
|
230
|
+
status: "failed",
|
|
231
|
+
error: result?.error,
|
|
232
|
+
payload: prevOutput
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
236
|
+
} else if (result.status === "suspended") {
|
|
237
|
+
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
238
|
+
const stepRes = stepResult;
|
|
239
|
+
return stepRes?.status === "suspended";
|
|
240
|
+
});
|
|
241
|
+
for (const [stepName, stepResult] of suspendedSteps) {
|
|
242
|
+
const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
|
|
243
|
+
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
244
|
+
await emitter.emit("watch", {
|
|
245
|
+
type: "workflow-step-suspended",
|
|
246
|
+
payload: {
|
|
247
|
+
id: step.id,
|
|
248
|
+
status: "suspended"
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
return {
|
|
252
|
+
executionContext,
|
|
253
|
+
result: {
|
|
254
|
+
status: "suspended",
|
|
255
|
+
payload: stepResult.payload,
|
|
256
|
+
suspendPayload: {
|
|
257
|
+
...stepResult?.suspendPayload,
|
|
258
|
+
__workflow_meta: { runId, path: suspendPath }
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
executionContext,
|
|
265
|
+
result: {
|
|
266
|
+
status: "suspended",
|
|
267
|
+
payload: {}
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
} else if (result.status === "tripwire") {
|
|
271
|
+
await emitter.emit("watch", {
|
|
272
|
+
type: "workflow-step-result",
|
|
273
|
+
payload: {
|
|
274
|
+
id: step.id,
|
|
275
|
+
status: "tripwire",
|
|
276
|
+
error: result?.reason,
|
|
277
|
+
payload: prevOutput
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
return {
|
|
281
|
+
executionContext,
|
|
282
|
+
result: {
|
|
283
|
+
status: "tripwire",
|
|
284
|
+
reason: result?.reason,
|
|
285
|
+
retry: result?.retry,
|
|
286
|
+
metadata: result?.metadata,
|
|
287
|
+
processorId: result?.processorId
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
await emitter.emit("watch", {
|
|
292
|
+
type: "workflow-step-result",
|
|
293
|
+
payload: {
|
|
294
|
+
id: step.id,
|
|
295
|
+
status: "success",
|
|
296
|
+
output: result?.result
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
await emitter.emit("watch", {
|
|
300
|
+
type: "workflow-step-finish",
|
|
301
|
+
payload: {
|
|
302
|
+
id: step.id,
|
|
303
|
+
metadata: {}
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
return { executionContext, result: { status: "success", output: result?.result } };
|
|
307
|
+
}
|
|
308
|
+
);
|
|
309
|
+
Object.assign(executionContext, res.executionContext);
|
|
310
|
+
return {
|
|
311
|
+
...res.result,
|
|
312
|
+
startedAt,
|
|
313
|
+
endedAt: Date.now(),
|
|
314
|
+
payload: inputData,
|
|
315
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
316
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
};
|
|
31
320
|
var InngestRun = class extends workflows.Run {
|
|
32
321
|
inngest;
|
|
33
322
|
serializedStepGraph;
|
|
@@ -49,14 +338,21 @@ var InngestRun = class extends workflows.Run {
|
|
|
49
338
|
}
|
|
50
339
|
async getRunOutput(eventId) {
|
|
51
340
|
let runs = await this.getRuns(eventId);
|
|
341
|
+
const storage = this.#mastra?.getStorage();
|
|
52
342
|
while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
|
|
53
343
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
54
344
|
runs = await this.getRuns(eventId);
|
|
55
345
|
if (runs?.[0]?.status === "Failed") {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
346
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
347
|
+
workflowName: this.workflowId,
|
|
348
|
+
runId: this.runId
|
|
349
|
+
});
|
|
350
|
+
return {
|
|
351
|
+
output: { result: { steps: snapshot?.context, status: "failed", error: runs?.[0]?.output?.message } }
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
if (runs?.[0]?.status === "Cancelled") {
|
|
355
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
60
356
|
workflowName: this.workflowId,
|
|
61
357
|
runId: this.runId
|
|
62
358
|
});
|
|
@@ -65,56 +361,73 @@ var InngestRun = class extends workflows.Run {
|
|
|
65
361
|
}
|
|
66
362
|
return runs?.[0];
|
|
67
363
|
}
|
|
68
|
-
async sendEvent(event, data) {
|
|
69
|
-
await this.inngest.send({
|
|
70
|
-
name: `user-event-${event}`,
|
|
71
|
-
data
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
364
|
async cancel() {
|
|
365
|
+
const storage = this.#mastra?.getStorage();
|
|
75
366
|
await this.inngest.send({
|
|
76
367
|
name: `cancel.workflow.${this.workflowId}`,
|
|
77
368
|
data: {
|
|
78
369
|
runId: this.runId
|
|
79
370
|
}
|
|
80
371
|
});
|
|
81
|
-
const snapshot = await
|
|
372
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
82
373
|
workflowName: this.workflowId,
|
|
83
374
|
runId: this.runId
|
|
84
375
|
});
|
|
85
376
|
if (snapshot) {
|
|
86
|
-
await
|
|
377
|
+
await storage?.persistWorkflowSnapshot({
|
|
87
378
|
workflowName: this.workflowId,
|
|
88
379
|
runId: this.runId,
|
|
380
|
+
resourceId: this.resourceId,
|
|
89
381
|
snapshot: {
|
|
90
382
|
...snapshot,
|
|
91
|
-
status: "canceled"
|
|
383
|
+
status: "canceled",
|
|
384
|
+
value: snapshot.value
|
|
92
385
|
}
|
|
93
386
|
});
|
|
94
387
|
}
|
|
95
388
|
}
|
|
96
|
-
async start({
|
|
97
|
-
|
|
389
|
+
async start(params) {
|
|
390
|
+
return this._start(params);
|
|
391
|
+
}
|
|
392
|
+
async _start({
|
|
393
|
+
inputData,
|
|
394
|
+
initialState,
|
|
395
|
+
outputOptions,
|
|
396
|
+
tracingOptions,
|
|
397
|
+
format,
|
|
398
|
+
requestContext
|
|
98
399
|
}) {
|
|
99
400
|
await this.#mastra.getStorage()?.persistWorkflowSnapshot({
|
|
100
401
|
workflowName: this.workflowId,
|
|
101
402
|
runId: this.runId,
|
|
403
|
+
resourceId: this.resourceId,
|
|
102
404
|
snapshot: {
|
|
103
405
|
runId: this.runId,
|
|
104
406
|
serializedStepGraph: this.serializedStepGraph,
|
|
407
|
+
status: "running",
|
|
105
408
|
value: {},
|
|
106
409
|
context: {},
|
|
107
410
|
activePaths: [],
|
|
108
411
|
suspendedPaths: {},
|
|
109
|
-
|
|
110
|
-
|
|
412
|
+
activeStepsPath: {},
|
|
413
|
+
resumeLabels: {},
|
|
414
|
+
waitingPaths: {},
|
|
415
|
+
timestamp: Date.now()
|
|
111
416
|
}
|
|
112
417
|
});
|
|
418
|
+
const inputDataToUse = await this._validateInput(inputData);
|
|
419
|
+
const initialStateToUse = await this._validateInitialState(initialState ?? {});
|
|
113
420
|
const eventOutput = await this.inngest.send({
|
|
114
421
|
name: `workflow.${this.workflowId}`,
|
|
115
422
|
data: {
|
|
116
|
-
inputData,
|
|
117
|
-
|
|
423
|
+
inputData: inputDataToUse,
|
|
424
|
+
initialState: initialStateToUse,
|
|
425
|
+
runId: this.runId,
|
|
426
|
+
resourceId: this.resourceId,
|
|
427
|
+
outputOptions,
|
|
428
|
+
tracingOptions,
|
|
429
|
+
format,
|
|
430
|
+
requestContext: requestContext ? Object.fromEntries(requestContext.entries()) : {}
|
|
118
431
|
}
|
|
119
432
|
});
|
|
120
433
|
const eventId = eventOutput.ids[0];
|
|
@@ -143,27 +456,131 @@ var InngestRun = class extends workflows.Run {
|
|
|
143
456
|
return p;
|
|
144
457
|
}
|
|
145
458
|
async _resume(params) {
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
)
|
|
149
|
-
|
|
459
|
+
const storage = this.#mastra?.getStorage();
|
|
460
|
+
let steps = [];
|
|
461
|
+
if (typeof params.step === "string") {
|
|
462
|
+
steps = params.step.split(".");
|
|
463
|
+
} else {
|
|
464
|
+
steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
465
|
+
(step) => typeof step === "string" ? step : step?.id
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
150
469
|
workflowName: this.workflowId,
|
|
151
470
|
runId: this.runId
|
|
152
471
|
});
|
|
472
|
+
const suspendedStep = this.workflowSteps[steps?.[0] ?? ""];
|
|
473
|
+
const resumeDataToUse = await this._validateResumeData(params.resumeData, suspendedStep);
|
|
474
|
+
const persistedRequestContext = snapshot?.requestContext ?? {};
|
|
475
|
+
const newRequestContext = params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {};
|
|
476
|
+
const mergedRequestContext = { ...persistedRequestContext, ...newRequestContext };
|
|
153
477
|
const eventOutput = await this.inngest.send({
|
|
154
478
|
name: `workflow.${this.workflowId}`,
|
|
155
479
|
data: {
|
|
156
|
-
inputData:
|
|
480
|
+
inputData: resumeDataToUse,
|
|
481
|
+
initialState: snapshot?.value ?? {},
|
|
157
482
|
runId: this.runId,
|
|
158
483
|
workflowId: this.workflowId,
|
|
159
484
|
stepResults: snapshot?.context,
|
|
160
485
|
resume: {
|
|
161
486
|
steps,
|
|
162
487
|
stepResults: snapshot?.context,
|
|
163
|
-
resumePayload:
|
|
164
|
-
|
|
165
|
-
|
|
488
|
+
resumePayload: resumeDataToUse,
|
|
489
|
+
resumePath: steps?.[0] ? snapshot?.suspendedPaths?.[steps?.[0]] : void 0
|
|
490
|
+
},
|
|
491
|
+
requestContext: mergedRequestContext
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
const eventId = eventOutput.ids[0];
|
|
495
|
+
if (!eventId) {
|
|
496
|
+
throw new Error("Event ID is not set");
|
|
497
|
+
}
|
|
498
|
+
const runOutput = await this.getRunOutput(eventId);
|
|
499
|
+
const result = runOutput?.output?.result;
|
|
500
|
+
if (result.status === "failed") {
|
|
501
|
+
result.error = new Error(result.error);
|
|
502
|
+
}
|
|
503
|
+
return result;
|
|
504
|
+
}
|
|
505
|
+
async timeTravel(params) {
|
|
506
|
+
const p = this._timeTravel(params).then((result) => {
|
|
507
|
+
if (result.status !== "suspended") {
|
|
508
|
+
this.closeStreamAction?.().catch(() => {
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
return result;
|
|
512
|
+
});
|
|
513
|
+
this.executionResults = p;
|
|
514
|
+
return p;
|
|
515
|
+
}
|
|
516
|
+
async _timeTravel(params) {
|
|
517
|
+
if (!params.step || Array.isArray(params.step) && params.step?.length === 0) {
|
|
518
|
+
throw new Error("Step is required and must be a valid step or array of steps");
|
|
519
|
+
}
|
|
520
|
+
let steps = [];
|
|
521
|
+
if (typeof params.step === "string") {
|
|
522
|
+
steps = params.step.split(".");
|
|
523
|
+
} else {
|
|
524
|
+
steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
525
|
+
(step) => typeof step === "string" ? step : step?.id
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
if (steps.length === 0) {
|
|
529
|
+
throw new Error("No steps provided to timeTravel");
|
|
530
|
+
}
|
|
531
|
+
const storage = this.#mastra?.getStorage();
|
|
532
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
533
|
+
workflowName: this.workflowId,
|
|
534
|
+
runId: this.runId
|
|
535
|
+
});
|
|
536
|
+
if (!snapshot) {
|
|
537
|
+
await storage?.persistWorkflowSnapshot({
|
|
538
|
+
workflowName: this.workflowId,
|
|
539
|
+
runId: this.runId,
|
|
540
|
+
resourceId: this.resourceId,
|
|
541
|
+
snapshot: {
|
|
542
|
+
runId: this.runId,
|
|
543
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
544
|
+
status: "pending",
|
|
545
|
+
value: {},
|
|
546
|
+
context: {},
|
|
547
|
+
activePaths: [],
|
|
548
|
+
suspendedPaths: {},
|
|
549
|
+
activeStepsPath: {},
|
|
550
|
+
resumeLabels: {},
|
|
551
|
+
waitingPaths: {},
|
|
552
|
+
timestamp: Date.now()
|
|
166
553
|
}
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
if (snapshot?.status === "running") {
|
|
557
|
+
throw new Error("This workflow run is still running, cannot time travel");
|
|
558
|
+
}
|
|
559
|
+
let inputDataToUse = params.inputData;
|
|
560
|
+
if (inputDataToUse && steps.length === 1) {
|
|
561
|
+
inputDataToUse = await this._validateTimetravelInputData(params.inputData, this.workflowSteps[steps[0]]);
|
|
562
|
+
}
|
|
563
|
+
const timeTravelData = workflows.createTimeTravelExecutionParams({
|
|
564
|
+
steps,
|
|
565
|
+
inputData: inputDataToUse,
|
|
566
|
+
resumeData: params.resumeData,
|
|
567
|
+
context: params.context,
|
|
568
|
+
nestedStepsContext: params.nestedStepsContext,
|
|
569
|
+
snapshot: snapshot ?? { context: {} },
|
|
570
|
+
graph: this.executionGraph,
|
|
571
|
+
initialState: params.initialState
|
|
572
|
+
});
|
|
573
|
+
const eventOutput = await this.inngest.send({
|
|
574
|
+
name: `workflow.${this.workflowId}`,
|
|
575
|
+
data: {
|
|
576
|
+
initialState: timeTravelData.state,
|
|
577
|
+
runId: this.runId,
|
|
578
|
+
workflowId: this.workflowId,
|
|
579
|
+
stepResults: timeTravelData.stepResults,
|
|
580
|
+
timeTravel: timeTravelData,
|
|
581
|
+
tracingOptions: params.tracingOptions,
|
|
582
|
+
outputOptions: params.outputOptions,
|
|
583
|
+
requestContext: params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {}
|
|
167
584
|
}
|
|
168
585
|
});
|
|
169
586
|
const eventId = eventOutput.ids[0];
|
|
@@ -177,12 +594,12 @@ var InngestRun = class extends workflows.Run {
|
|
|
177
594
|
}
|
|
178
595
|
return result;
|
|
179
596
|
}
|
|
180
|
-
watch(cb
|
|
597
|
+
watch(cb) {
|
|
181
598
|
let active = true;
|
|
182
599
|
const streamPromise = realtime.subscribe(
|
|
183
600
|
{
|
|
184
601
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
185
|
-
topics: [
|
|
602
|
+
topics: ["watch"],
|
|
186
603
|
app: this.inngest
|
|
187
604
|
},
|
|
188
605
|
(message) => {
|
|
@@ -200,16 +617,35 @@ var InngestRun = class extends workflows.Run {
|
|
|
200
617
|
});
|
|
201
618
|
};
|
|
202
619
|
}
|
|
203
|
-
|
|
620
|
+
streamLegacy({ inputData, requestContext } = {}) {
|
|
204
621
|
const { readable, writable } = new TransformStream();
|
|
205
622
|
const writer = writable.getWriter();
|
|
623
|
+
void writer.write({
|
|
624
|
+
// @ts-ignore
|
|
625
|
+
type: "start",
|
|
626
|
+
// @ts-ignore
|
|
627
|
+
payload: { runId: this.runId }
|
|
628
|
+
});
|
|
206
629
|
const unwatch = this.watch(async (event) => {
|
|
207
630
|
try {
|
|
208
|
-
|
|
631
|
+
const e = {
|
|
632
|
+
...event,
|
|
633
|
+
type: event.type.replace("workflow-", "")
|
|
634
|
+
};
|
|
635
|
+
if (e.type === "step-output") {
|
|
636
|
+
e.type = e.payload.output.type;
|
|
637
|
+
e.payload = e.payload.output.payload;
|
|
638
|
+
}
|
|
639
|
+
await writer.write(e);
|
|
209
640
|
} catch {
|
|
210
641
|
}
|
|
211
|
-
}
|
|
642
|
+
});
|
|
212
643
|
this.closeStreamAction = async () => {
|
|
644
|
+
await writer.write({
|
|
645
|
+
type: "finish",
|
|
646
|
+
// @ts-ignore
|
|
647
|
+
payload: { runId: this.runId }
|
|
648
|
+
});
|
|
213
649
|
unwatch();
|
|
214
650
|
try {
|
|
215
651
|
await writer.close();
|
|
@@ -219,7 +655,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
219
655
|
writer.releaseLock();
|
|
220
656
|
}
|
|
221
657
|
};
|
|
222
|
-
this.executionResults = this.
|
|
658
|
+
this.executionResults = this._start({ inputData, requestContext, format: "legacy" }).then((result) => {
|
|
223
659
|
if (result.status !== "suspended") {
|
|
224
660
|
this.closeStreamAction?.().catch(() => {
|
|
225
661
|
});
|
|
@@ -231,53 +667,186 @@ var InngestRun = class extends workflows.Run {
|
|
|
231
667
|
getWorkflowState: () => this.executionResults
|
|
232
668
|
};
|
|
233
669
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
this.
|
|
243
|
-
|
|
244
|
-
async getWorkflowRuns(args) {
|
|
245
|
-
const storage = this.#mastra?.getStorage();
|
|
246
|
-
if (!storage) {
|
|
247
|
-
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
248
|
-
return { runs: [], total: 0 };
|
|
249
|
-
}
|
|
250
|
-
return storage.getWorkflowRuns({ workflowName: this.id, ...args ?? {} });
|
|
251
|
-
}
|
|
252
|
-
async getWorkflowRunById(runId) {
|
|
253
|
-
const storage = this.#mastra?.getStorage();
|
|
254
|
-
if (!storage) {
|
|
255
|
-
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
256
|
-
return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
|
|
257
|
-
}
|
|
258
|
-
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
259
|
-
return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
|
|
260
|
-
}
|
|
261
|
-
async getWorkflowRunExecutionResult(runId) {
|
|
262
|
-
const storage = this.#mastra?.getStorage();
|
|
263
|
-
if (!storage) {
|
|
264
|
-
this.logger.debug("Cannot get workflow run execution result. Mastra storage is not initialized");
|
|
265
|
-
return null;
|
|
266
|
-
}
|
|
267
|
-
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
268
|
-
if (!run?.snapshot) {
|
|
269
|
-
return null;
|
|
270
|
-
}
|
|
271
|
-
if (typeof run.snapshot === "string") {
|
|
272
|
-
return null;
|
|
670
|
+
stream({
|
|
671
|
+
inputData,
|
|
672
|
+
requestContext,
|
|
673
|
+
tracingOptions,
|
|
674
|
+
closeOnSuspend = true,
|
|
675
|
+
initialState,
|
|
676
|
+
outputOptions
|
|
677
|
+
} = {}) {
|
|
678
|
+
if (this.closeStreamAction && this.streamOutput) {
|
|
679
|
+
return this.streamOutput;
|
|
273
680
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
681
|
+
this.closeStreamAction = async () => {
|
|
682
|
+
};
|
|
683
|
+
const self = this;
|
|
684
|
+
const stream$1 = new web.ReadableStream({
|
|
685
|
+
async start(controller) {
|
|
686
|
+
const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
|
|
687
|
+
controller.enqueue({
|
|
688
|
+
type,
|
|
689
|
+
runId: self.runId,
|
|
690
|
+
from,
|
|
691
|
+
payload: {
|
|
692
|
+
stepName: payload?.id,
|
|
693
|
+
...payload
|
|
694
|
+
}
|
|
695
|
+
});
|
|
696
|
+
});
|
|
697
|
+
self.closeStreamAction = async () => {
|
|
698
|
+
unwatch();
|
|
699
|
+
try {
|
|
700
|
+
await controller.close();
|
|
701
|
+
} catch (err) {
|
|
702
|
+
console.error("Error closing stream:", err);
|
|
703
|
+
}
|
|
704
|
+
};
|
|
705
|
+
const executionResultsPromise = self._start({
|
|
706
|
+
inputData,
|
|
707
|
+
requestContext,
|
|
708
|
+
// tracingContext, // We are not able to pass a reference to a span here, what to do?
|
|
709
|
+
initialState,
|
|
710
|
+
tracingOptions,
|
|
711
|
+
outputOptions,
|
|
712
|
+
format: "vnext"
|
|
713
|
+
});
|
|
714
|
+
let executionResults;
|
|
715
|
+
try {
|
|
716
|
+
executionResults = await executionResultsPromise;
|
|
717
|
+
if (closeOnSuspend) {
|
|
718
|
+
self.closeStreamAction?.().catch(() => {
|
|
719
|
+
});
|
|
720
|
+
} else if (executionResults.status !== "suspended") {
|
|
721
|
+
self.closeStreamAction?.().catch(() => {
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
if (self.streamOutput) {
|
|
725
|
+
self.streamOutput.updateResults(
|
|
726
|
+
executionResults
|
|
727
|
+
);
|
|
728
|
+
}
|
|
729
|
+
} catch (err) {
|
|
730
|
+
self.streamOutput?.rejectResults(err);
|
|
731
|
+
self.closeStreamAction?.().catch(() => {
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
});
|
|
736
|
+
this.streamOutput = new stream.WorkflowRunOutput({
|
|
737
|
+
runId: this.runId,
|
|
738
|
+
workflowId: this.workflowId,
|
|
739
|
+
stream: stream$1
|
|
740
|
+
});
|
|
741
|
+
return this.streamOutput;
|
|
742
|
+
}
|
|
743
|
+
streamVNext(args = {}) {
|
|
744
|
+
return this.stream(args);
|
|
745
|
+
}
|
|
746
|
+
timeTravelStream({
|
|
747
|
+
inputData,
|
|
748
|
+
resumeData,
|
|
749
|
+
initialState,
|
|
750
|
+
step,
|
|
751
|
+
context,
|
|
752
|
+
nestedStepsContext,
|
|
753
|
+
requestContext,
|
|
754
|
+
tracingOptions,
|
|
755
|
+
outputOptions
|
|
756
|
+
}) {
|
|
757
|
+
this.closeStreamAction = async () => {
|
|
280
758
|
};
|
|
759
|
+
const self = this;
|
|
760
|
+
const stream$1 = new web.ReadableStream({
|
|
761
|
+
async start(controller) {
|
|
762
|
+
const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
|
|
763
|
+
controller.enqueue({
|
|
764
|
+
type,
|
|
765
|
+
runId: self.runId,
|
|
766
|
+
from,
|
|
767
|
+
payload: {
|
|
768
|
+
stepName: payload?.id,
|
|
769
|
+
...payload
|
|
770
|
+
}
|
|
771
|
+
});
|
|
772
|
+
});
|
|
773
|
+
self.closeStreamAction = async () => {
|
|
774
|
+
unwatch();
|
|
775
|
+
try {
|
|
776
|
+
controller.close();
|
|
777
|
+
} catch (err) {
|
|
778
|
+
console.error("Error closing stream:", err);
|
|
779
|
+
}
|
|
780
|
+
};
|
|
781
|
+
const executionResultsPromise = self._timeTravel({
|
|
782
|
+
inputData,
|
|
783
|
+
step,
|
|
784
|
+
context,
|
|
785
|
+
nestedStepsContext,
|
|
786
|
+
resumeData,
|
|
787
|
+
initialState,
|
|
788
|
+
requestContext,
|
|
789
|
+
tracingOptions,
|
|
790
|
+
outputOptions
|
|
791
|
+
});
|
|
792
|
+
self.executionResults = executionResultsPromise;
|
|
793
|
+
let executionResults;
|
|
794
|
+
try {
|
|
795
|
+
executionResults = await executionResultsPromise;
|
|
796
|
+
self.closeStreamAction?.().catch(() => {
|
|
797
|
+
});
|
|
798
|
+
if (self.streamOutput) {
|
|
799
|
+
self.streamOutput.updateResults(executionResults);
|
|
800
|
+
}
|
|
801
|
+
} catch (err) {
|
|
802
|
+
self.streamOutput?.rejectResults(err);
|
|
803
|
+
self.closeStreamAction?.().catch(() => {
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
});
|
|
808
|
+
this.streamOutput = new stream.WorkflowRunOutput({
|
|
809
|
+
runId: this.runId,
|
|
810
|
+
workflowId: this.workflowId,
|
|
811
|
+
stream: stream$1
|
|
812
|
+
});
|
|
813
|
+
return this.streamOutput;
|
|
814
|
+
}
|
|
815
|
+
};
|
|
816
|
+
|
|
817
|
+
// src/workflow.ts
|
|
818
|
+
var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
819
|
+
#mastra;
|
|
820
|
+
inngest;
|
|
821
|
+
function;
|
|
822
|
+
flowControlConfig;
|
|
823
|
+
constructor(params, inngest) {
|
|
824
|
+
const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
|
|
825
|
+
super(workflowParams);
|
|
826
|
+
this.engineType = "inngest";
|
|
827
|
+
const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
|
|
828
|
+
([_, value]) => value !== void 0
|
|
829
|
+
);
|
|
830
|
+
this.flowControlConfig = flowControlEntries.length > 0 ? Object.fromEntries(flowControlEntries) : void 0;
|
|
831
|
+
this.#mastra = params.mastra;
|
|
832
|
+
this.inngest = inngest;
|
|
833
|
+
}
|
|
834
|
+
async listWorkflowRuns(args) {
|
|
835
|
+
const storage = this.#mastra?.getStorage();
|
|
836
|
+
if (!storage) {
|
|
837
|
+
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
838
|
+
return { runs: [], total: 0 };
|
|
839
|
+
}
|
|
840
|
+
return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
|
|
841
|
+
}
|
|
842
|
+
async getWorkflowRunById(runId) {
|
|
843
|
+
const storage = this.#mastra?.getStorage();
|
|
844
|
+
if (!storage) {
|
|
845
|
+
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
846
|
+
return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
|
|
847
|
+
}
|
|
848
|
+
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
849
|
+
return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
|
|
281
850
|
}
|
|
282
851
|
__registerMastra(mastra) {
|
|
283
852
|
this.#mastra = mastra;
|
|
@@ -297,56 +866,49 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
297
866
|
}
|
|
298
867
|
}
|
|
299
868
|
}
|
|
300
|
-
createRun(options) {
|
|
869
|
+
async createRun(options) {
|
|
301
870
|
const runIdToUse = options?.runId || crypto.randomUUID();
|
|
302
871
|
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
303
872
|
{
|
|
304
873
|
workflowId: this.id,
|
|
305
874
|
runId: runIdToUse,
|
|
875
|
+
resourceId: options?.resourceId,
|
|
306
876
|
executionEngine: this.executionEngine,
|
|
307
877
|
executionGraph: this.executionGraph,
|
|
308
878
|
serializedStepGraph: this.serializedStepGraph,
|
|
309
879
|
mastra: this.#mastra,
|
|
310
880
|
retryConfig: this.retryConfig,
|
|
311
|
-
cleanup: () => this.runs.delete(runIdToUse)
|
|
881
|
+
cleanup: () => this.runs.delete(runIdToUse),
|
|
882
|
+
workflowSteps: this.steps,
|
|
883
|
+
workflowEngineType: this.engineType,
|
|
884
|
+
validateInputs: this.options.validateInputs
|
|
312
885
|
},
|
|
313
886
|
this.inngest
|
|
314
887
|
);
|
|
315
888
|
this.runs.set(runIdToUse, run);
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
workflowId: this.id,
|
|
323
|
-
runId: runIdToUse,
|
|
324
|
-
executionEngine: this.executionEngine,
|
|
325
|
-
executionGraph: this.executionGraph,
|
|
326
|
-
serializedStepGraph: this.serializedStepGraph,
|
|
327
|
-
mastra: this.#mastra,
|
|
328
|
-
retryConfig: this.retryConfig,
|
|
329
|
-
cleanup: () => this.runs.delete(runIdToUse)
|
|
330
|
-
},
|
|
331
|
-
this.inngest
|
|
332
|
-
);
|
|
333
|
-
this.runs.set(runIdToUse, run);
|
|
334
|
-
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse);
|
|
335
|
-
if (!workflowSnapshotInStorage) {
|
|
889
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
|
|
890
|
+
workflowStatus: run.workflowRunStatus,
|
|
891
|
+
stepResults: {}
|
|
892
|
+
});
|
|
893
|
+
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
|
|
894
|
+
if (!workflowSnapshotInStorage && shouldPersistSnapshot) {
|
|
336
895
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
337
896
|
workflowName: this.id,
|
|
338
897
|
runId: runIdToUse,
|
|
898
|
+
resourceId: options?.resourceId,
|
|
339
899
|
snapshot: {
|
|
340
900
|
runId: runIdToUse,
|
|
341
901
|
status: "pending",
|
|
342
902
|
value: {},
|
|
343
903
|
context: {},
|
|
344
904
|
activePaths: [],
|
|
905
|
+
activeStepsPath: {},
|
|
906
|
+
waitingPaths: {},
|
|
345
907
|
serializedStepGraph: this.serializedStepGraph,
|
|
346
908
|
suspendedPaths: {},
|
|
909
|
+
resumeLabels: {},
|
|
347
910
|
result: void 0,
|
|
348
911
|
error: void 0,
|
|
349
|
-
// @ts-ignore
|
|
350
912
|
timestamp: Date.now()
|
|
351
913
|
}
|
|
352
914
|
});
|
|
@@ -360,13 +922,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
360
922
|
this.function = this.inngest.createFunction(
|
|
361
923
|
{
|
|
362
924
|
id: `workflow.${this.id}`,
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
925
|
+
retries: Math.min(this.retryConfig?.attempts ?? 0, 20),
|
|
926
|
+
cancelOn: [{ event: `cancel.workflow.${this.id}` }],
|
|
927
|
+
// Spread flow control configuration
|
|
928
|
+
...this.flowControlConfig
|
|
366
929
|
},
|
|
367
930
|
{ event: `workflow.${this.id}` },
|
|
368
931
|
async ({ event, step, attempt, publish }) => {
|
|
369
|
-
let { inputData, runId, resume } = event.data;
|
|
932
|
+
let { inputData, initialState, runId, resourceId, resume, outputOptions, format, timeTravel } = event.data;
|
|
370
933
|
if (!runId) {
|
|
371
934
|
runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
|
|
372
935
|
return crypto.randomUUID();
|
|
@@ -394,19 +957,38 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
394
957
|
once: (_event, _callback) => {
|
|
395
958
|
}
|
|
396
959
|
};
|
|
397
|
-
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
960
|
+
const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
|
|
398
961
|
const result = await engine.execute({
|
|
399
962
|
workflowId: this.id,
|
|
400
963
|
runId,
|
|
964
|
+
resourceId,
|
|
401
965
|
graph: this.executionGraph,
|
|
402
966
|
serializedStepGraph: this.serializedStepGraph,
|
|
403
967
|
input: inputData,
|
|
968
|
+
initialState,
|
|
404
969
|
emitter,
|
|
405
970
|
retryConfig: this.retryConfig,
|
|
406
|
-
|
|
407
|
-
// TODO
|
|
971
|
+
requestContext: new di.RequestContext(Object.entries(event.data.requestContext ?? {})),
|
|
408
972
|
resume,
|
|
409
|
-
|
|
973
|
+
timeTravel,
|
|
974
|
+
format,
|
|
975
|
+
abortController: new AbortController(),
|
|
976
|
+
// currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
|
|
977
|
+
outputOptions,
|
|
978
|
+
writableStream: new web.WritableStream({
|
|
979
|
+
write(chunk) {
|
|
980
|
+
void emitter.emit("watch", chunk).catch(() => {
|
|
981
|
+
});
|
|
982
|
+
}
|
|
983
|
+
})
|
|
984
|
+
});
|
|
985
|
+
await step.run(`workflow.${this.id}.finalize`, async () => {
|
|
986
|
+
if (result.status === "failed") {
|
|
987
|
+
throw new inngest.NonRetriableError(`Workflow failed`, {
|
|
988
|
+
cause: result
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
return result;
|
|
410
992
|
});
|
|
411
993
|
return { result, runId };
|
|
412
994
|
}
|
|
@@ -430,27 +1012,70 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
430
1012
|
return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
|
|
431
1013
|
}
|
|
432
1014
|
};
|
|
1015
|
+
function serve({
|
|
1016
|
+
mastra,
|
|
1017
|
+
inngest,
|
|
1018
|
+
functions: userFunctions = [],
|
|
1019
|
+
registerOptions
|
|
1020
|
+
}) {
|
|
1021
|
+
const wfs = mastra.listWorkflows();
|
|
1022
|
+
const workflowFunctions = Array.from(
|
|
1023
|
+
new Set(
|
|
1024
|
+
Object.values(wfs).flatMap((wf) => {
|
|
1025
|
+
if (wf instanceof InngestWorkflow) {
|
|
1026
|
+
wf.__registerMastra(mastra);
|
|
1027
|
+
return wf.getFunctions();
|
|
1028
|
+
}
|
|
1029
|
+
return [];
|
|
1030
|
+
})
|
|
1031
|
+
)
|
|
1032
|
+
);
|
|
1033
|
+
return hono.serve({
|
|
1034
|
+
...registerOptions,
|
|
1035
|
+
client: inngest,
|
|
1036
|
+
functions: [...workflowFunctions, ...userFunctions]
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
// src/types.ts
|
|
1041
|
+
var _compatibilityCheck = true;
|
|
1042
|
+
|
|
1043
|
+
// src/index.ts
|
|
433
1044
|
function isAgent(params) {
|
|
434
1045
|
return params?.component === "AGENT";
|
|
435
1046
|
}
|
|
436
1047
|
function isTool(params) {
|
|
437
1048
|
return params instanceof tools.Tool;
|
|
438
1049
|
}
|
|
439
|
-
function
|
|
1050
|
+
function isInngestWorkflow(params) {
|
|
1051
|
+
return params instanceof InngestWorkflow;
|
|
1052
|
+
}
|
|
1053
|
+
function createStep(params, agentOptions) {
|
|
1054
|
+
if (isInngestWorkflow(params)) {
|
|
1055
|
+
return params;
|
|
1056
|
+
}
|
|
440
1057
|
if (isAgent(params)) {
|
|
441
1058
|
return {
|
|
442
1059
|
id: params.name,
|
|
443
|
-
|
|
1060
|
+
description: params.getDescription(),
|
|
444
1061
|
inputSchema: zod.z.object({
|
|
445
1062
|
prompt: zod.z.string()
|
|
446
1063
|
// resourceId: z.string().optional(),
|
|
447
1064
|
// threadId: z.string().optional(),
|
|
448
1065
|
}),
|
|
449
|
-
// @ts-ignore
|
|
450
1066
|
outputSchema: zod.z.object({
|
|
451
1067
|
text: zod.z.string()
|
|
452
1068
|
}),
|
|
453
|
-
execute: async ({
|
|
1069
|
+
execute: async ({
|
|
1070
|
+
inputData,
|
|
1071
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1072
|
+
[_constants.STREAM_FORMAT_SYMBOL]: streamFormat,
|
|
1073
|
+
requestContext,
|
|
1074
|
+
tracingContext,
|
|
1075
|
+
abortSignal,
|
|
1076
|
+
abort,
|
|
1077
|
+
writer
|
|
1078
|
+
}) => {
|
|
454
1079
|
let streamPromise = {};
|
|
455
1080
|
streamPromise.promise = new Promise((resolve, reject) => {
|
|
456
1081
|
streamPromise.resolve = resolve;
|
|
@@ -460,50 +1085,65 @@ function createStep(params) {
|
|
|
460
1085
|
name: params.name,
|
|
461
1086
|
args: inputData
|
|
462
1087
|
};
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
1088
|
+
let stream;
|
|
1089
|
+
if ((await params.getModel()).specificationVersion === "v1") {
|
|
1090
|
+
const { fullStream } = await params.streamLegacy(inputData.prompt, {
|
|
1091
|
+
...agentOptions ?? {},
|
|
1092
|
+
// resourceId: inputData.resourceId,
|
|
1093
|
+
// threadId: inputData.threadId,
|
|
1094
|
+
requestContext,
|
|
1095
|
+
tracingContext,
|
|
1096
|
+
onFinish: (result) => {
|
|
1097
|
+
streamPromise.resolve(result.text);
|
|
1098
|
+
void agentOptions?.onFinish?.(result);
|
|
1099
|
+
},
|
|
1100
|
+
abortSignal
|
|
1101
|
+
});
|
|
1102
|
+
stream = fullStream;
|
|
1103
|
+
} else {
|
|
1104
|
+
const modelOutput = await params.stream(inputData.prompt, {
|
|
1105
|
+
...agentOptions ?? {},
|
|
1106
|
+
requestContext,
|
|
1107
|
+
tracingContext,
|
|
1108
|
+
onFinish: (result) => {
|
|
1109
|
+
streamPromise.resolve(result.text);
|
|
1110
|
+
void agentOptions?.onFinish?.(result);
|
|
1111
|
+
},
|
|
1112
|
+
abortSignal
|
|
1113
|
+
});
|
|
1114
|
+
stream = modelOutput.fullStream;
|
|
478
1115
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
1116
|
+
if (streamFormat === "legacy") {
|
|
1117
|
+
await emitter.emit("watch", {
|
|
1118
|
+
type: "tool-call-streaming-start",
|
|
1119
|
+
...toolData ?? {}
|
|
1120
|
+
});
|
|
1121
|
+
for await (const chunk of stream) {
|
|
1122
|
+
if (chunk.type === "text-delta") {
|
|
1123
|
+
await emitter.emit("watch", {
|
|
483
1124
|
type: "tool-call-delta",
|
|
484
|
-
...toolData,
|
|
1125
|
+
...toolData ?? {},
|
|
485
1126
|
argsTextDelta: chunk.textDelta
|
|
486
1127
|
});
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
case "source":
|
|
497
|
-
case "file":
|
|
498
|
-
default:
|
|
499
|
-
await emitter.emit("watch-v2", chunk);
|
|
500
|
-
break;
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
await emitter.emit("watch", {
|
|
1131
|
+
type: "tool-call-streaming-finish",
|
|
1132
|
+
...toolData ?? {}
|
|
1133
|
+
});
|
|
1134
|
+
} else {
|
|
1135
|
+
for await (const chunk of stream) {
|
|
1136
|
+
await writer.write(chunk);
|
|
501
1137
|
}
|
|
502
1138
|
}
|
|
1139
|
+
if (abortSignal.aborted) {
|
|
1140
|
+
return abort();
|
|
1141
|
+
}
|
|
503
1142
|
return {
|
|
504
1143
|
text: await streamPromise.promise
|
|
505
1144
|
};
|
|
506
|
-
}
|
|
1145
|
+
},
|
|
1146
|
+
component: params.component
|
|
507
1147
|
};
|
|
508
1148
|
}
|
|
509
1149
|
if (isTool(params)) {
|
|
@@ -512,17 +1152,40 @@ function createStep(params) {
|
|
|
512
1152
|
}
|
|
513
1153
|
return {
|
|
514
1154
|
// TODO: tool probably should have strong id type
|
|
515
|
-
// @ts-ignore
|
|
516
1155
|
id: params.id,
|
|
1156
|
+
description: params.description,
|
|
517
1157
|
inputSchema: params.inputSchema,
|
|
518
1158
|
outputSchema: params.outputSchema,
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
1159
|
+
suspendSchema: params.suspendSchema,
|
|
1160
|
+
resumeSchema: params.resumeSchema,
|
|
1161
|
+
execute: async ({
|
|
1162
|
+
inputData,
|
|
1163
|
+
mastra,
|
|
1164
|
+
requestContext,
|
|
1165
|
+
tracingContext,
|
|
1166
|
+
suspend,
|
|
1167
|
+
resumeData,
|
|
1168
|
+
runId,
|
|
1169
|
+
workflowId,
|
|
1170
|
+
state,
|
|
1171
|
+
setState
|
|
1172
|
+
}) => {
|
|
1173
|
+
const toolContext = {
|
|
522
1174
|
mastra,
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
1175
|
+
requestContext,
|
|
1176
|
+
tracingContext,
|
|
1177
|
+
workflow: {
|
|
1178
|
+
runId,
|
|
1179
|
+
resumeData,
|
|
1180
|
+
suspend,
|
|
1181
|
+
workflowId,
|
|
1182
|
+
state,
|
|
1183
|
+
setState
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
return params.execute(inputData, toolContext);
|
|
1187
|
+
},
|
|
1188
|
+
component: "TOOL"
|
|
526
1189
|
};
|
|
527
1190
|
}
|
|
528
1191
|
return {
|
|
@@ -538,7 +1201,10 @@ function createStep(params) {
|
|
|
538
1201
|
function init(inngest) {
|
|
539
1202
|
return {
|
|
540
1203
|
createWorkflow(params) {
|
|
541
|
-
return new InngestWorkflow(
|
|
1204
|
+
return new InngestWorkflow(
|
|
1205
|
+
params,
|
|
1206
|
+
inngest
|
|
1207
|
+
);
|
|
542
1208
|
},
|
|
543
1209
|
createStep,
|
|
544
1210
|
cloneStep(step, opts) {
|
|
@@ -547,7 +1213,13 @@ function init(inngest) {
|
|
|
547
1213
|
description: step.description,
|
|
548
1214
|
inputSchema: step.inputSchema,
|
|
549
1215
|
outputSchema: step.outputSchema,
|
|
550
|
-
|
|
1216
|
+
resumeSchema: step.resumeSchema,
|
|
1217
|
+
suspendSchema: step.suspendSchema,
|
|
1218
|
+
stateSchema: step.stateSchema,
|
|
1219
|
+
execute: step.execute,
|
|
1220
|
+
retries: step.retries,
|
|
1221
|
+
scorers: step.scorers,
|
|
1222
|
+
component: step.component
|
|
551
1223
|
};
|
|
552
1224
|
},
|
|
553
1225
|
cloneWorkflow(workflow, opts) {
|
|
@@ -556,7 +1228,8 @@ function init(inngest) {
|
|
|
556
1228
|
inputSchema: workflow.inputSchema,
|
|
557
1229
|
outputSchema: workflow.outputSchema,
|
|
558
1230
|
steps: workflow.stepDefs,
|
|
559
|
-
mastra: workflow.mastra
|
|
1231
|
+
mastra: workflow.mastra,
|
|
1232
|
+
options: workflow.options
|
|
560
1233
|
});
|
|
561
1234
|
wf.setStepFlow(workflow.stepGraph);
|
|
562
1235
|
wf.commit();
|
|
@@ -564,736 +1237,13 @@ function init(inngest) {
|
|
|
564
1237
|
}
|
|
565
1238
|
};
|
|
566
1239
|
}
|
|
567
|
-
var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
568
|
-
inngestStep;
|
|
569
|
-
inngestAttempts;
|
|
570
|
-
constructor(mastra, inngestStep, inngestAttempts = 0) {
|
|
571
|
-
super({ mastra });
|
|
572
|
-
this.inngestStep = inngestStep;
|
|
573
|
-
this.inngestAttempts = inngestAttempts;
|
|
574
|
-
}
|
|
575
|
-
async execute(params) {
|
|
576
|
-
await params.emitter.emit("watch-v2", {
|
|
577
|
-
type: "start",
|
|
578
|
-
payload: { runId: params.runId }
|
|
579
|
-
});
|
|
580
|
-
const result = await super.execute(params);
|
|
581
|
-
await params.emitter.emit("watch-v2", {
|
|
582
|
-
type: "finish",
|
|
583
|
-
payload: { runId: params.runId }
|
|
584
|
-
});
|
|
585
|
-
return result;
|
|
586
|
-
}
|
|
587
|
-
async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
|
|
588
|
-
const base = {
|
|
589
|
-
status: lastOutput.status,
|
|
590
|
-
steps: stepResults
|
|
591
|
-
};
|
|
592
|
-
if (lastOutput.status === "success") {
|
|
593
|
-
await emitter.emit("watch", {
|
|
594
|
-
type: "watch",
|
|
595
|
-
payload: {
|
|
596
|
-
workflowState: {
|
|
597
|
-
status: lastOutput.status,
|
|
598
|
-
steps: stepResults,
|
|
599
|
-
result: lastOutput.output
|
|
600
|
-
}
|
|
601
|
-
},
|
|
602
|
-
eventTimestamp: Date.now()
|
|
603
|
-
});
|
|
604
|
-
base.result = lastOutput.output;
|
|
605
|
-
} else if (lastOutput.status === "failed") {
|
|
606
|
-
base.error = error instanceof Error ? error?.stack ?? error.message : lastOutput?.error instanceof Error ? lastOutput.error.message : lastOutput.error ?? error ?? "Unknown error";
|
|
607
|
-
await emitter.emit("watch", {
|
|
608
|
-
type: "watch",
|
|
609
|
-
payload: {
|
|
610
|
-
workflowState: {
|
|
611
|
-
status: lastOutput.status,
|
|
612
|
-
steps: stepResults,
|
|
613
|
-
result: null,
|
|
614
|
-
error: base.error
|
|
615
|
-
}
|
|
616
|
-
},
|
|
617
|
-
eventTimestamp: Date.now()
|
|
618
|
-
});
|
|
619
|
-
} else if (lastOutput.status === "suspended") {
|
|
620
|
-
await emitter.emit("watch", {
|
|
621
|
-
type: "watch",
|
|
622
|
-
payload: {
|
|
623
|
-
workflowState: {
|
|
624
|
-
status: lastOutput.status,
|
|
625
|
-
steps: stepResults,
|
|
626
|
-
result: null,
|
|
627
|
-
error: null
|
|
628
|
-
}
|
|
629
|
-
},
|
|
630
|
-
eventTimestamp: Date.now()
|
|
631
|
-
});
|
|
632
|
-
const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
|
|
633
|
-
if (stepResult?.status === "suspended") {
|
|
634
|
-
const nestedPath = stepResult?.payload?.__workflow_meta?.path;
|
|
635
|
-
return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
|
|
636
|
-
}
|
|
637
|
-
return [];
|
|
638
|
-
});
|
|
639
|
-
base.suspended = suspendedStepIds;
|
|
640
|
-
}
|
|
641
|
-
executionSpan?.end();
|
|
642
|
-
return base;
|
|
643
|
-
}
|
|
644
|
-
async superExecuteStep({
|
|
645
|
-
workflowId,
|
|
646
|
-
runId,
|
|
647
|
-
step,
|
|
648
|
-
stepResults,
|
|
649
|
-
executionContext,
|
|
650
|
-
resume,
|
|
651
|
-
prevOutput,
|
|
652
|
-
emitter,
|
|
653
|
-
abortController,
|
|
654
|
-
runtimeContext,
|
|
655
|
-
writableStream
|
|
656
|
-
}) {
|
|
657
|
-
return super.executeStep({
|
|
658
|
-
workflowId,
|
|
659
|
-
runId,
|
|
660
|
-
step,
|
|
661
|
-
stepResults,
|
|
662
|
-
executionContext,
|
|
663
|
-
resume,
|
|
664
|
-
prevOutput,
|
|
665
|
-
emitter,
|
|
666
|
-
abortController,
|
|
667
|
-
runtimeContext,
|
|
668
|
-
writableStream
|
|
669
|
-
});
|
|
670
|
-
}
|
|
671
|
-
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
672
|
-
// await this.inngestStep.sleep(id, duration);
|
|
673
|
-
// }
|
|
674
|
-
async executeSleep({
|
|
675
|
-
workflowId,
|
|
676
|
-
runId,
|
|
677
|
-
entry,
|
|
678
|
-
prevOutput,
|
|
679
|
-
stepResults,
|
|
680
|
-
emitter,
|
|
681
|
-
abortController,
|
|
682
|
-
runtimeContext,
|
|
683
|
-
writableStream
|
|
684
|
-
}) {
|
|
685
|
-
let { duration, fn } = entry;
|
|
686
|
-
if (fn) {
|
|
687
|
-
const stepCallId = crypto.randomUUID();
|
|
688
|
-
duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
|
|
689
|
-
return await fn({
|
|
690
|
-
runId,
|
|
691
|
-
workflowId,
|
|
692
|
-
mastra: this.mastra,
|
|
693
|
-
runtimeContext,
|
|
694
|
-
inputData: prevOutput,
|
|
695
|
-
runCount: -1,
|
|
696
|
-
getInitData: () => stepResults?.input,
|
|
697
|
-
getStepResult: (step) => {
|
|
698
|
-
if (!step?.id) {
|
|
699
|
-
return null;
|
|
700
|
-
}
|
|
701
|
-
const result = stepResults[step.id];
|
|
702
|
-
if (result?.status === "success") {
|
|
703
|
-
return result.output;
|
|
704
|
-
}
|
|
705
|
-
return null;
|
|
706
|
-
},
|
|
707
|
-
// TODO: this function shouldn't have suspend probably?
|
|
708
|
-
suspend: async (_suspendPayload) => {
|
|
709
|
-
},
|
|
710
|
-
bail: () => {
|
|
711
|
-
},
|
|
712
|
-
abort: () => {
|
|
713
|
-
abortController?.abort();
|
|
714
|
-
},
|
|
715
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
716
|
-
engine: { step: this.inngestStep },
|
|
717
|
-
abortSignal: abortController?.signal,
|
|
718
|
-
writer: new tools.ToolStream(
|
|
719
|
-
{
|
|
720
|
-
prefix: "step",
|
|
721
|
-
callId: stepCallId,
|
|
722
|
-
name: "sleep",
|
|
723
|
-
runId
|
|
724
|
-
},
|
|
725
|
-
writableStream
|
|
726
|
-
)
|
|
727
|
-
});
|
|
728
|
-
});
|
|
729
|
-
}
|
|
730
|
-
await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
|
|
731
|
-
}
|
|
732
|
-
async executeSleepUntil({
|
|
733
|
-
workflowId,
|
|
734
|
-
runId,
|
|
735
|
-
entry,
|
|
736
|
-
prevOutput,
|
|
737
|
-
stepResults,
|
|
738
|
-
emitter,
|
|
739
|
-
abortController,
|
|
740
|
-
runtimeContext,
|
|
741
|
-
writableStream
|
|
742
|
-
}) {
|
|
743
|
-
let { date, fn } = entry;
|
|
744
|
-
if (fn) {
|
|
745
|
-
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
746
|
-
const stepCallId = crypto.randomUUID();
|
|
747
|
-
return await fn({
|
|
748
|
-
runId,
|
|
749
|
-
workflowId,
|
|
750
|
-
mastra: this.mastra,
|
|
751
|
-
runtimeContext,
|
|
752
|
-
inputData: prevOutput,
|
|
753
|
-
runCount: -1,
|
|
754
|
-
getInitData: () => stepResults?.input,
|
|
755
|
-
getStepResult: (step) => {
|
|
756
|
-
if (!step?.id) {
|
|
757
|
-
return null;
|
|
758
|
-
}
|
|
759
|
-
const result = stepResults[step.id];
|
|
760
|
-
if (result?.status === "success") {
|
|
761
|
-
return result.output;
|
|
762
|
-
}
|
|
763
|
-
return null;
|
|
764
|
-
},
|
|
765
|
-
// TODO: this function shouldn't have suspend probably?
|
|
766
|
-
suspend: async (_suspendPayload) => {
|
|
767
|
-
},
|
|
768
|
-
bail: () => {
|
|
769
|
-
},
|
|
770
|
-
abort: () => {
|
|
771
|
-
abortController?.abort();
|
|
772
|
-
},
|
|
773
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
774
|
-
engine: { step: this.inngestStep },
|
|
775
|
-
abortSignal: abortController?.signal,
|
|
776
|
-
writer: new tools.ToolStream(
|
|
777
|
-
{
|
|
778
|
-
prefix: "step",
|
|
779
|
-
callId: stepCallId,
|
|
780
|
-
name: "sleep",
|
|
781
|
-
runId
|
|
782
|
-
},
|
|
783
|
-
writableStream
|
|
784
|
-
)
|
|
785
|
-
});
|
|
786
|
-
});
|
|
787
|
-
}
|
|
788
|
-
if (!(date instanceof Date)) {
|
|
789
|
-
return;
|
|
790
|
-
}
|
|
791
|
-
await this.inngestStep.sleepUntil(entry.id, date);
|
|
792
|
-
}
|
|
793
|
-
async executeWaitForEvent({ event, timeout }) {
|
|
794
|
-
const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
|
|
795
|
-
event: `user-event-${event}`,
|
|
796
|
-
timeout: timeout ?? 5e3
|
|
797
|
-
});
|
|
798
|
-
if (eventData === null) {
|
|
799
|
-
throw "Timeout waiting for event";
|
|
800
|
-
}
|
|
801
|
-
return eventData?.data;
|
|
802
|
-
}
|
|
803
|
-
async executeStep({
|
|
804
|
-
step,
|
|
805
|
-
stepResults,
|
|
806
|
-
executionContext,
|
|
807
|
-
resume,
|
|
808
|
-
prevOutput,
|
|
809
|
-
emitter,
|
|
810
|
-
abortController,
|
|
811
|
-
runtimeContext,
|
|
812
|
-
writableStream
|
|
813
|
-
}) {
|
|
814
|
-
const startedAt = await this.inngestStep.run(
|
|
815
|
-
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
816
|
-
async () => {
|
|
817
|
-
const startedAt2 = Date.now();
|
|
818
|
-
await emitter.emit("watch", {
|
|
819
|
-
type: "watch",
|
|
820
|
-
payload: {
|
|
821
|
-
currentStep: {
|
|
822
|
-
id: step.id,
|
|
823
|
-
status: "running"
|
|
824
|
-
},
|
|
825
|
-
workflowState: {
|
|
826
|
-
status: "running",
|
|
827
|
-
steps: {
|
|
828
|
-
...stepResults,
|
|
829
|
-
[step.id]: {
|
|
830
|
-
status: "running"
|
|
831
|
-
}
|
|
832
|
-
},
|
|
833
|
-
result: null,
|
|
834
|
-
error: null
|
|
835
|
-
}
|
|
836
|
-
},
|
|
837
|
-
eventTimestamp: Date.now()
|
|
838
|
-
});
|
|
839
|
-
await emitter.emit("watch-v2", {
|
|
840
|
-
type: "step-start",
|
|
841
|
-
payload: {
|
|
842
|
-
id: step.id,
|
|
843
|
-
status: "running",
|
|
844
|
-
payload: prevOutput,
|
|
845
|
-
startedAt: startedAt2
|
|
846
|
-
}
|
|
847
|
-
});
|
|
848
|
-
return startedAt2;
|
|
849
|
-
}
|
|
850
|
-
);
|
|
851
|
-
if (step instanceof InngestWorkflow) {
|
|
852
|
-
const isResume = !!resume?.steps?.length;
|
|
853
|
-
let result;
|
|
854
|
-
let runId;
|
|
855
|
-
if (isResume) {
|
|
856
|
-
runId = stepResults[resume?.steps?.[0]]?.payload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
857
|
-
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
858
|
-
workflowName: step.id,
|
|
859
|
-
runId
|
|
860
|
-
});
|
|
861
|
-
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
862
|
-
function: step.getFunction(),
|
|
863
|
-
data: {
|
|
864
|
-
inputData: prevOutput,
|
|
865
|
-
runId,
|
|
866
|
-
resume: {
|
|
867
|
-
runId,
|
|
868
|
-
steps: resume.steps.slice(1),
|
|
869
|
-
stepResults: snapshot?.context,
|
|
870
|
-
resumePayload: resume.resumePayload,
|
|
871
|
-
// @ts-ignore
|
|
872
|
-
resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
});
|
|
876
|
-
result = invokeResp.result;
|
|
877
|
-
runId = invokeResp.runId;
|
|
878
|
-
} else {
|
|
879
|
-
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
880
|
-
function: step.getFunction(),
|
|
881
|
-
data: {
|
|
882
|
-
inputData: prevOutput
|
|
883
|
-
}
|
|
884
|
-
});
|
|
885
|
-
result = invokeResp.result;
|
|
886
|
-
runId = invokeResp.runId;
|
|
887
|
-
}
|
|
888
|
-
const res = await this.inngestStep.run(
|
|
889
|
-
`workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
|
|
890
|
-
async () => {
|
|
891
|
-
if (result.status === "failed") {
|
|
892
|
-
await emitter.emit("watch", {
|
|
893
|
-
type: "watch",
|
|
894
|
-
payload: {
|
|
895
|
-
currentStep: {
|
|
896
|
-
id: step.id,
|
|
897
|
-
status: "failed",
|
|
898
|
-
error: result?.error
|
|
899
|
-
},
|
|
900
|
-
workflowState: {
|
|
901
|
-
status: "running",
|
|
902
|
-
steps: stepResults,
|
|
903
|
-
result: null,
|
|
904
|
-
error: null
|
|
905
|
-
}
|
|
906
|
-
},
|
|
907
|
-
eventTimestamp: Date.now()
|
|
908
|
-
});
|
|
909
|
-
await emitter.emit("watch-v2", {
|
|
910
|
-
type: "step-result",
|
|
911
|
-
payload: {
|
|
912
|
-
id: step.id,
|
|
913
|
-
status: "failed",
|
|
914
|
-
error: result?.error,
|
|
915
|
-
payload: prevOutput
|
|
916
|
-
}
|
|
917
|
-
});
|
|
918
|
-
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
919
|
-
} else if (result.status === "suspended") {
|
|
920
|
-
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
921
|
-
const stepRes2 = stepResult;
|
|
922
|
-
return stepRes2?.status === "suspended";
|
|
923
|
-
});
|
|
924
|
-
for (const [stepName, stepResult] of suspendedSteps) {
|
|
925
|
-
const suspendPath = [stepName, ...stepResult?.payload?.__workflow_meta?.path ?? []];
|
|
926
|
-
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
927
|
-
await emitter.emit("watch", {
|
|
928
|
-
type: "watch",
|
|
929
|
-
payload: {
|
|
930
|
-
currentStep: {
|
|
931
|
-
id: step.id,
|
|
932
|
-
status: "suspended",
|
|
933
|
-
payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
|
|
934
|
-
},
|
|
935
|
-
workflowState: {
|
|
936
|
-
status: "running",
|
|
937
|
-
steps: stepResults,
|
|
938
|
-
result: null,
|
|
939
|
-
error: null
|
|
940
|
-
}
|
|
941
|
-
},
|
|
942
|
-
eventTimestamp: Date.now()
|
|
943
|
-
});
|
|
944
|
-
await emitter.emit("watch-v2", {
|
|
945
|
-
type: "step-suspended",
|
|
946
|
-
payload: {
|
|
947
|
-
id: step.id,
|
|
948
|
-
status: "suspended"
|
|
949
|
-
}
|
|
950
|
-
});
|
|
951
|
-
return {
|
|
952
|
-
executionContext,
|
|
953
|
-
result: {
|
|
954
|
-
status: "suspended",
|
|
955
|
-
payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
|
|
956
|
-
}
|
|
957
|
-
};
|
|
958
|
-
}
|
|
959
|
-
await emitter.emit("watch", {
|
|
960
|
-
type: "watch",
|
|
961
|
-
payload: {
|
|
962
|
-
currentStep: {
|
|
963
|
-
id: step.id,
|
|
964
|
-
status: "suspended",
|
|
965
|
-
payload: {}
|
|
966
|
-
},
|
|
967
|
-
workflowState: {
|
|
968
|
-
status: "running",
|
|
969
|
-
steps: stepResults,
|
|
970
|
-
result: null,
|
|
971
|
-
error: null
|
|
972
|
-
}
|
|
973
|
-
},
|
|
974
|
-
eventTimestamp: Date.now()
|
|
975
|
-
});
|
|
976
|
-
return {
|
|
977
|
-
executionContext,
|
|
978
|
-
result: {
|
|
979
|
-
status: "suspended",
|
|
980
|
-
payload: {}
|
|
981
|
-
}
|
|
982
|
-
};
|
|
983
|
-
}
|
|
984
|
-
await emitter.emit("watch", {
|
|
985
|
-
type: "watch",
|
|
986
|
-
payload: {
|
|
987
|
-
currentStep: {
|
|
988
|
-
id: step.id,
|
|
989
|
-
status: "success",
|
|
990
|
-
output: result?.result
|
|
991
|
-
},
|
|
992
|
-
workflowState: {
|
|
993
|
-
status: "running",
|
|
994
|
-
steps: stepResults,
|
|
995
|
-
result: null,
|
|
996
|
-
error: null
|
|
997
|
-
}
|
|
998
|
-
},
|
|
999
|
-
eventTimestamp: Date.now()
|
|
1000
|
-
});
|
|
1001
|
-
await emitter.emit("watch-v2", {
|
|
1002
|
-
type: "step-result",
|
|
1003
|
-
payload: {
|
|
1004
|
-
id: step.id,
|
|
1005
|
-
status: "success",
|
|
1006
|
-
output: result?.result
|
|
1007
|
-
}
|
|
1008
|
-
});
|
|
1009
|
-
await emitter.emit("watch-v2", {
|
|
1010
|
-
type: "step-finish",
|
|
1011
|
-
payload: {
|
|
1012
|
-
id: step.id,
|
|
1013
|
-
metadata: {}
|
|
1014
|
-
}
|
|
1015
|
-
});
|
|
1016
|
-
return { executionContext, result: { status: "success", output: result?.result } };
|
|
1017
|
-
}
|
|
1018
|
-
);
|
|
1019
|
-
Object.assign(executionContext, res.executionContext);
|
|
1020
|
-
return res.result;
|
|
1021
|
-
}
|
|
1022
|
-
const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
1023
|
-
let execResults;
|
|
1024
|
-
let suspended;
|
|
1025
|
-
let bailed;
|
|
1026
|
-
try {
|
|
1027
|
-
const result = await step.execute({
|
|
1028
|
-
runId: executionContext.runId,
|
|
1029
|
-
mastra: this.mastra,
|
|
1030
|
-
runtimeContext,
|
|
1031
|
-
writableStream,
|
|
1032
|
-
inputData: prevOutput,
|
|
1033
|
-
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
|
|
1034
|
-
getInitData: () => stepResults?.input,
|
|
1035
|
-
getStepResult: (step2) => {
|
|
1036
|
-
const result2 = stepResults[step2.id];
|
|
1037
|
-
if (result2?.status === "success") {
|
|
1038
|
-
return result2.output;
|
|
1039
|
-
}
|
|
1040
|
-
return null;
|
|
1041
|
-
},
|
|
1042
|
-
suspend: async (suspendPayload) => {
|
|
1043
|
-
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1044
|
-
suspended = { payload: suspendPayload };
|
|
1045
|
-
},
|
|
1046
|
-
bail: (result2) => {
|
|
1047
|
-
bailed = { payload: result2 };
|
|
1048
|
-
},
|
|
1049
|
-
resume: {
|
|
1050
|
-
steps: resume?.steps?.slice(1) || [],
|
|
1051
|
-
resumePayload: resume?.resumePayload,
|
|
1052
|
-
// @ts-ignore
|
|
1053
|
-
runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
|
|
1054
|
-
},
|
|
1055
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1056
|
-
engine: {
|
|
1057
|
-
step: this.inngestStep
|
|
1058
|
-
},
|
|
1059
|
-
abortSignal: abortController.signal
|
|
1060
|
-
});
|
|
1061
|
-
const endedAt = Date.now();
|
|
1062
|
-
execResults = {
|
|
1063
|
-
status: "success",
|
|
1064
|
-
output: result,
|
|
1065
|
-
startedAt,
|
|
1066
|
-
endedAt,
|
|
1067
|
-
payload: prevOutput,
|
|
1068
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1069
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1070
|
-
};
|
|
1071
|
-
} catch (e) {
|
|
1072
|
-
execResults = {
|
|
1073
|
-
status: "failed",
|
|
1074
|
-
payload: prevOutput,
|
|
1075
|
-
error: e instanceof Error ? e.message : String(e),
|
|
1076
|
-
endedAt: Date.now(),
|
|
1077
|
-
startedAt,
|
|
1078
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1079
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1080
|
-
};
|
|
1081
|
-
}
|
|
1082
|
-
if (suspended) {
|
|
1083
|
-
execResults = {
|
|
1084
|
-
status: "suspended",
|
|
1085
|
-
suspendedPayload: suspended.payload,
|
|
1086
|
-
payload: prevOutput,
|
|
1087
|
-
suspendedAt: Date.now(),
|
|
1088
|
-
startedAt,
|
|
1089
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1090
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1091
|
-
};
|
|
1092
|
-
} else if (bailed) {
|
|
1093
|
-
execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
1094
|
-
}
|
|
1095
|
-
if (execResults.status === "failed") {
|
|
1096
|
-
if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
|
|
1097
|
-
throw execResults.error;
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
await emitter.emit("watch", {
|
|
1101
|
-
type: "watch",
|
|
1102
|
-
payload: {
|
|
1103
|
-
currentStep: {
|
|
1104
|
-
id: step.id,
|
|
1105
|
-
...execResults
|
|
1106
|
-
},
|
|
1107
|
-
workflowState: {
|
|
1108
|
-
status: "running",
|
|
1109
|
-
steps: { ...stepResults, [step.id]: execResults },
|
|
1110
|
-
result: null,
|
|
1111
|
-
error: null
|
|
1112
|
-
}
|
|
1113
|
-
},
|
|
1114
|
-
eventTimestamp: Date.now()
|
|
1115
|
-
});
|
|
1116
|
-
if (execResults.status === "suspended") {
|
|
1117
|
-
await emitter.emit("watch-v2", {
|
|
1118
|
-
type: "step-suspended",
|
|
1119
|
-
payload: {
|
|
1120
|
-
id: step.id,
|
|
1121
|
-
...execResults
|
|
1122
|
-
}
|
|
1123
|
-
});
|
|
1124
|
-
} else {
|
|
1125
|
-
await emitter.emit("watch-v2", {
|
|
1126
|
-
type: "step-result",
|
|
1127
|
-
payload: {
|
|
1128
|
-
id: step.id,
|
|
1129
|
-
...execResults
|
|
1130
|
-
}
|
|
1131
|
-
});
|
|
1132
|
-
await emitter.emit("watch-v2", {
|
|
1133
|
-
type: "step-finish",
|
|
1134
|
-
payload: {
|
|
1135
|
-
id: step.id,
|
|
1136
|
-
metadata: {}
|
|
1137
|
-
}
|
|
1138
|
-
});
|
|
1139
|
-
}
|
|
1140
|
-
return { result: execResults, executionContext, stepResults };
|
|
1141
|
-
});
|
|
1142
|
-
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
1143
|
-
Object.assign(stepResults, stepRes.stepResults);
|
|
1144
|
-
return stepRes.result;
|
|
1145
|
-
}
|
|
1146
|
-
async persistStepUpdate({
|
|
1147
|
-
workflowId,
|
|
1148
|
-
runId,
|
|
1149
|
-
stepResults,
|
|
1150
|
-
executionContext,
|
|
1151
|
-
serializedStepGraph,
|
|
1152
|
-
workflowStatus,
|
|
1153
|
-
result,
|
|
1154
|
-
error
|
|
1155
|
-
}) {
|
|
1156
|
-
await this.inngestStep.run(
|
|
1157
|
-
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
1158
|
-
async () => {
|
|
1159
|
-
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
1160
|
-
workflowName: workflowId,
|
|
1161
|
-
runId,
|
|
1162
|
-
snapshot: {
|
|
1163
|
-
runId,
|
|
1164
|
-
value: {},
|
|
1165
|
-
context: stepResults,
|
|
1166
|
-
activePaths: [],
|
|
1167
|
-
suspendedPaths: executionContext.suspendedPaths,
|
|
1168
|
-
serializedStepGraph,
|
|
1169
|
-
status: workflowStatus,
|
|
1170
|
-
result,
|
|
1171
|
-
error,
|
|
1172
|
-
// @ts-ignore
|
|
1173
|
-
timestamp: Date.now()
|
|
1174
|
-
}
|
|
1175
|
-
});
|
|
1176
|
-
}
|
|
1177
|
-
);
|
|
1178
|
-
}
|
|
1179
|
-
async executeConditional({
|
|
1180
|
-
workflowId,
|
|
1181
|
-
runId,
|
|
1182
|
-
entry,
|
|
1183
|
-
prevOutput,
|
|
1184
|
-
prevStep,
|
|
1185
|
-
stepResults,
|
|
1186
|
-
serializedStepGraph,
|
|
1187
|
-
resume,
|
|
1188
|
-
executionContext,
|
|
1189
|
-
emitter,
|
|
1190
|
-
abortController,
|
|
1191
|
-
runtimeContext,
|
|
1192
|
-
writableStream
|
|
1193
|
-
}) {
|
|
1194
|
-
let execResults;
|
|
1195
|
-
const truthyIndexes = (await Promise.all(
|
|
1196
|
-
entry.conditions.map(
|
|
1197
|
-
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1198
|
-
try {
|
|
1199
|
-
const result = await cond({
|
|
1200
|
-
runId,
|
|
1201
|
-
workflowId,
|
|
1202
|
-
mastra: this.mastra,
|
|
1203
|
-
runtimeContext,
|
|
1204
|
-
runCount: -1,
|
|
1205
|
-
inputData: prevOutput,
|
|
1206
|
-
getInitData: () => stepResults?.input,
|
|
1207
|
-
getStepResult: (step) => {
|
|
1208
|
-
if (!step?.id) {
|
|
1209
|
-
return null;
|
|
1210
|
-
}
|
|
1211
|
-
const result2 = stepResults[step.id];
|
|
1212
|
-
if (result2?.status === "success") {
|
|
1213
|
-
return result2.output;
|
|
1214
|
-
}
|
|
1215
|
-
return null;
|
|
1216
|
-
},
|
|
1217
|
-
// TODO: this function shouldn't have suspend probably?
|
|
1218
|
-
suspend: async (_suspendPayload) => {
|
|
1219
|
-
},
|
|
1220
|
-
bail: () => {
|
|
1221
|
-
},
|
|
1222
|
-
abort: () => {
|
|
1223
|
-
abortController.abort();
|
|
1224
|
-
},
|
|
1225
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1226
|
-
engine: {
|
|
1227
|
-
step: this.inngestStep
|
|
1228
|
-
},
|
|
1229
|
-
abortSignal: abortController.signal,
|
|
1230
|
-
writer: new tools.ToolStream(
|
|
1231
|
-
{
|
|
1232
|
-
prefix: "step",
|
|
1233
|
-
callId: crypto.randomUUID(),
|
|
1234
|
-
name: "conditional",
|
|
1235
|
-
runId
|
|
1236
|
-
},
|
|
1237
|
-
writableStream
|
|
1238
|
-
)
|
|
1239
|
-
});
|
|
1240
|
-
return result ? index : null;
|
|
1241
|
-
} catch (e) {
|
|
1242
|
-
return null;
|
|
1243
|
-
}
|
|
1244
|
-
})
|
|
1245
|
-
)
|
|
1246
|
-
)).filter((index) => index !== null);
|
|
1247
|
-
const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
|
|
1248
|
-
const results = await Promise.all(
|
|
1249
|
-
stepsToRun.map(
|
|
1250
|
-
(step, index) => this.executeEntry({
|
|
1251
|
-
workflowId,
|
|
1252
|
-
runId,
|
|
1253
|
-
entry: step,
|
|
1254
|
-
prevStep,
|
|
1255
|
-
stepResults,
|
|
1256
|
-
resume,
|
|
1257
|
-
serializedStepGraph,
|
|
1258
|
-
executionContext: {
|
|
1259
|
-
workflowId,
|
|
1260
|
-
runId,
|
|
1261
|
-
executionPath: [...executionContext.executionPath, index],
|
|
1262
|
-
suspendedPaths: executionContext.suspendedPaths,
|
|
1263
|
-
retryConfig: executionContext.retryConfig,
|
|
1264
|
-
executionSpan: executionContext.executionSpan
|
|
1265
|
-
},
|
|
1266
|
-
emitter,
|
|
1267
|
-
abortController,
|
|
1268
|
-
runtimeContext,
|
|
1269
|
-
writableStream
|
|
1270
|
-
})
|
|
1271
|
-
)
|
|
1272
|
-
);
|
|
1273
|
-
const hasFailed = results.find((result) => result.result.status === "failed");
|
|
1274
|
-
const hasSuspended = results.find((result) => result.result.status === "suspended");
|
|
1275
|
-
if (hasFailed) {
|
|
1276
|
-
execResults = { status: "failed", error: hasFailed.result.error };
|
|
1277
|
-
} else if (hasSuspended) {
|
|
1278
|
-
execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
|
|
1279
|
-
} else {
|
|
1280
|
-
execResults = {
|
|
1281
|
-
status: "success",
|
|
1282
|
-
output: results.reduce((acc, result, index) => {
|
|
1283
|
-
if (result.result.status === "success") {
|
|
1284
|
-
acc[stepsToRun[index].step.id] = result.output;
|
|
1285
|
-
}
|
|
1286
|
-
return acc;
|
|
1287
|
-
}, {})
|
|
1288
|
-
};
|
|
1289
|
-
}
|
|
1290
|
-
return execResults;
|
|
1291
|
-
}
|
|
1292
|
-
};
|
|
1293
1240
|
|
|
1294
1241
|
exports.InngestExecutionEngine = InngestExecutionEngine;
|
|
1295
1242
|
exports.InngestRun = InngestRun;
|
|
1296
1243
|
exports.InngestWorkflow = InngestWorkflow;
|
|
1244
|
+
exports._compatibilityCheck = _compatibilityCheck;
|
|
1297
1245
|
exports.createStep = createStep;
|
|
1298
1246
|
exports.init = init;
|
|
1299
1247
|
exports.serve = serve;
|
|
1248
|
+
//# sourceMappingURL=index.cjs.map
|
|
1249
|
+
//# sourceMappingURL=index.cjs.map
|