@mastra/inngest 0.0.0-scorers-api-v2-20250801171841 → 0.0.0-scorers-logs-20251208093427
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 +1070 -3
- package/dist/execution-engine.d.ts +85 -0
- package/dist/execution-engine.d.ts.map +1 -0
- package/dist/index.cjs +837 -909
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +28 -271
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +813 -886
- package/dist/index.js.map +1 -1
- 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 +38 -19
- 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.build.json +0 -9
- package/tsconfig.json +0 -5
- package/tsup.config.ts +0 -22
- package/vitest.config.ts +0 -14
package/dist/index.cjs
CHANGED
|
@@ -1,33 +1,302 @@
|
|
|
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
|
+
}
|
|
271
|
+
await emitter.emit("watch", {
|
|
272
|
+
type: "workflow-step-result",
|
|
273
|
+
payload: {
|
|
274
|
+
id: step.id,
|
|
275
|
+
status: "success",
|
|
276
|
+
output: result?.result
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
await emitter.emit("watch", {
|
|
280
|
+
type: "workflow-step-finish",
|
|
281
|
+
payload: {
|
|
282
|
+
id: step.id,
|
|
283
|
+
metadata: {}
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
return { executionContext, result: { status: "success", output: result?.result } };
|
|
287
|
+
}
|
|
288
|
+
);
|
|
289
|
+
Object.assign(executionContext, res.executionContext);
|
|
290
|
+
return {
|
|
291
|
+
...res.result,
|
|
292
|
+
startedAt,
|
|
293
|
+
endedAt: Date.now(),
|
|
294
|
+
payload: inputData,
|
|
295
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
296
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
};
|
|
31
300
|
var InngestRun = class extends workflows.Run {
|
|
32
301
|
inngest;
|
|
33
302
|
serializedStepGraph;
|
|
@@ -49,14 +318,21 @@ var InngestRun = class extends workflows.Run {
|
|
|
49
318
|
}
|
|
50
319
|
async getRunOutput(eventId) {
|
|
51
320
|
let runs = await this.getRuns(eventId);
|
|
321
|
+
const storage = this.#mastra?.getStorage();
|
|
52
322
|
while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
|
|
53
323
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
54
324
|
runs = await this.getRuns(eventId);
|
|
55
325
|
if (runs?.[0]?.status === "Failed") {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
326
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
327
|
+
workflowName: this.workflowId,
|
|
328
|
+
runId: this.runId
|
|
329
|
+
});
|
|
330
|
+
return {
|
|
331
|
+
output: { result: { steps: snapshot?.context, status: "failed", error: runs?.[0]?.output?.message } }
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
if (runs?.[0]?.status === "Cancelled") {
|
|
335
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
60
336
|
workflowName: this.workflowId,
|
|
61
337
|
runId: this.runId
|
|
62
338
|
});
|
|
@@ -65,56 +341,73 @@ var InngestRun = class extends workflows.Run {
|
|
|
65
341
|
}
|
|
66
342
|
return runs?.[0];
|
|
67
343
|
}
|
|
68
|
-
async sendEvent(event, data) {
|
|
69
|
-
await this.inngest.send({
|
|
70
|
-
name: `user-event-${event}`,
|
|
71
|
-
data
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
344
|
async cancel() {
|
|
345
|
+
const storage = this.#mastra?.getStorage();
|
|
75
346
|
await this.inngest.send({
|
|
76
347
|
name: `cancel.workflow.${this.workflowId}`,
|
|
77
348
|
data: {
|
|
78
349
|
runId: this.runId
|
|
79
350
|
}
|
|
80
351
|
});
|
|
81
|
-
const snapshot = await
|
|
352
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
82
353
|
workflowName: this.workflowId,
|
|
83
354
|
runId: this.runId
|
|
84
355
|
});
|
|
85
356
|
if (snapshot) {
|
|
86
|
-
await
|
|
357
|
+
await storage?.persistWorkflowSnapshot({
|
|
87
358
|
workflowName: this.workflowId,
|
|
88
359
|
runId: this.runId,
|
|
360
|
+
resourceId: this.resourceId,
|
|
89
361
|
snapshot: {
|
|
90
362
|
...snapshot,
|
|
91
|
-
status: "canceled"
|
|
363
|
+
status: "canceled",
|
|
364
|
+
value: snapshot.value
|
|
92
365
|
}
|
|
93
366
|
});
|
|
94
367
|
}
|
|
95
368
|
}
|
|
96
|
-
async start({
|
|
97
|
-
|
|
369
|
+
async start(params) {
|
|
370
|
+
return this._start(params);
|
|
371
|
+
}
|
|
372
|
+
async _start({
|
|
373
|
+
inputData,
|
|
374
|
+
initialState,
|
|
375
|
+
outputOptions,
|
|
376
|
+
tracingOptions,
|
|
377
|
+
format,
|
|
378
|
+
requestContext
|
|
98
379
|
}) {
|
|
99
380
|
await this.#mastra.getStorage()?.persistWorkflowSnapshot({
|
|
100
381
|
workflowName: this.workflowId,
|
|
101
382
|
runId: this.runId,
|
|
383
|
+
resourceId: this.resourceId,
|
|
102
384
|
snapshot: {
|
|
103
385
|
runId: this.runId,
|
|
104
386
|
serializedStepGraph: this.serializedStepGraph,
|
|
387
|
+
status: "running",
|
|
105
388
|
value: {},
|
|
106
389
|
context: {},
|
|
107
390
|
activePaths: [],
|
|
108
391
|
suspendedPaths: {},
|
|
109
|
-
|
|
110
|
-
|
|
392
|
+
activeStepsPath: {},
|
|
393
|
+
resumeLabels: {},
|
|
394
|
+
waitingPaths: {},
|
|
395
|
+
timestamp: Date.now()
|
|
111
396
|
}
|
|
112
397
|
});
|
|
398
|
+
const inputDataToUse = await this._validateInput(inputData);
|
|
399
|
+
const initialStateToUse = await this._validateInitialState(initialState ?? {});
|
|
113
400
|
const eventOutput = await this.inngest.send({
|
|
114
401
|
name: `workflow.${this.workflowId}`,
|
|
115
402
|
data: {
|
|
116
|
-
inputData,
|
|
117
|
-
|
|
403
|
+
inputData: inputDataToUse,
|
|
404
|
+
initialState: initialStateToUse,
|
|
405
|
+
runId: this.runId,
|
|
406
|
+
resourceId: this.resourceId,
|
|
407
|
+
outputOptions,
|
|
408
|
+
tracingOptions,
|
|
409
|
+
format,
|
|
410
|
+
requestContext: requestContext ? Object.fromEntries(requestContext.entries()) : {}
|
|
118
411
|
}
|
|
119
412
|
});
|
|
120
413
|
const eventId = eventOutput.ids[0];
|
|
@@ -143,27 +436,131 @@ var InngestRun = class extends workflows.Run {
|
|
|
143
436
|
return p;
|
|
144
437
|
}
|
|
145
438
|
async _resume(params) {
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
)
|
|
149
|
-
|
|
439
|
+
const storage = this.#mastra?.getStorage();
|
|
440
|
+
let steps = [];
|
|
441
|
+
if (typeof params.step === "string") {
|
|
442
|
+
steps = params.step.split(".");
|
|
443
|
+
} else {
|
|
444
|
+
steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
445
|
+
(step) => typeof step === "string" ? step : step?.id
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
150
449
|
workflowName: this.workflowId,
|
|
151
450
|
runId: this.runId
|
|
152
451
|
});
|
|
452
|
+
const suspendedStep = this.workflowSteps[steps?.[0] ?? ""];
|
|
453
|
+
const resumeDataToUse = await this._validateResumeData(params.resumeData, suspendedStep);
|
|
454
|
+
const persistedRequestContext = snapshot?.requestContext ?? {};
|
|
455
|
+
const newRequestContext = params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {};
|
|
456
|
+
const mergedRequestContext = { ...persistedRequestContext, ...newRequestContext };
|
|
153
457
|
const eventOutput = await this.inngest.send({
|
|
154
458
|
name: `workflow.${this.workflowId}`,
|
|
155
459
|
data: {
|
|
156
|
-
inputData:
|
|
460
|
+
inputData: resumeDataToUse,
|
|
461
|
+
initialState: snapshot?.value ?? {},
|
|
157
462
|
runId: this.runId,
|
|
158
463
|
workflowId: this.workflowId,
|
|
159
464
|
stepResults: snapshot?.context,
|
|
160
465
|
resume: {
|
|
161
466
|
steps,
|
|
162
467
|
stepResults: snapshot?.context,
|
|
163
|
-
resumePayload:
|
|
164
|
-
|
|
165
|
-
|
|
468
|
+
resumePayload: resumeDataToUse,
|
|
469
|
+
resumePath: steps?.[0] ? snapshot?.suspendedPaths?.[steps?.[0]] : void 0
|
|
470
|
+
},
|
|
471
|
+
requestContext: mergedRequestContext
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
const eventId = eventOutput.ids[0];
|
|
475
|
+
if (!eventId) {
|
|
476
|
+
throw new Error("Event ID is not set");
|
|
477
|
+
}
|
|
478
|
+
const runOutput = await this.getRunOutput(eventId);
|
|
479
|
+
const result = runOutput?.output?.result;
|
|
480
|
+
if (result.status === "failed") {
|
|
481
|
+
result.error = new Error(result.error);
|
|
482
|
+
}
|
|
483
|
+
return result;
|
|
484
|
+
}
|
|
485
|
+
async timeTravel(params) {
|
|
486
|
+
const p = this._timeTravel(params).then((result) => {
|
|
487
|
+
if (result.status !== "suspended") {
|
|
488
|
+
this.closeStreamAction?.().catch(() => {
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
return result;
|
|
492
|
+
});
|
|
493
|
+
this.executionResults = p;
|
|
494
|
+
return p;
|
|
495
|
+
}
|
|
496
|
+
async _timeTravel(params) {
|
|
497
|
+
if (!params.step || Array.isArray(params.step) && params.step?.length === 0) {
|
|
498
|
+
throw new Error("Step is required and must be a valid step or array of steps");
|
|
499
|
+
}
|
|
500
|
+
let steps = [];
|
|
501
|
+
if (typeof params.step === "string") {
|
|
502
|
+
steps = params.step.split(".");
|
|
503
|
+
} else {
|
|
504
|
+
steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
505
|
+
(step) => typeof step === "string" ? step : step?.id
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
if (steps.length === 0) {
|
|
509
|
+
throw new Error("No steps provided to timeTravel");
|
|
510
|
+
}
|
|
511
|
+
const storage = this.#mastra?.getStorage();
|
|
512
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
513
|
+
workflowName: this.workflowId,
|
|
514
|
+
runId: this.runId
|
|
515
|
+
});
|
|
516
|
+
if (!snapshot) {
|
|
517
|
+
await storage?.persistWorkflowSnapshot({
|
|
518
|
+
workflowName: this.workflowId,
|
|
519
|
+
runId: this.runId,
|
|
520
|
+
resourceId: this.resourceId,
|
|
521
|
+
snapshot: {
|
|
522
|
+
runId: this.runId,
|
|
523
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
524
|
+
status: "pending",
|
|
525
|
+
value: {},
|
|
526
|
+
context: {},
|
|
527
|
+
activePaths: [],
|
|
528
|
+
suspendedPaths: {},
|
|
529
|
+
activeStepsPath: {},
|
|
530
|
+
resumeLabels: {},
|
|
531
|
+
waitingPaths: {},
|
|
532
|
+
timestamp: Date.now()
|
|
166
533
|
}
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
if (snapshot?.status === "running") {
|
|
537
|
+
throw new Error("This workflow run is still running, cannot time travel");
|
|
538
|
+
}
|
|
539
|
+
let inputDataToUse = params.inputData;
|
|
540
|
+
if (inputDataToUse && steps.length === 1) {
|
|
541
|
+
inputDataToUse = await this._validateTimetravelInputData(params.inputData, this.workflowSteps[steps[0]]);
|
|
542
|
+
}
|
|
543
|
+
const timeTravelData = workflows.createTimeTravelExecutionParams({
|
|
544
|
+
steps,
|
|
545
|
+
inputData: inputDataToUse,
|
|
546
|
+
resumeData: params.resumeData,
|
|
547
|
+
context: params.context,
|
|
548
|
+
nestedStepsContext: params.nestedStepsContext,
|
|
549
|
+
snapshot: snapshot ?? { context: {} },
|
|
550
|
+
graph: this.executionGraph,
|
|
551
|
+
initialState: params.initialState
|
|
552
|
+
});
|
|
553
|
+
const eventOutput = await this.inngest.send({
|
|
554
|
+
name: `workflow.${this.workflowId}`,
|
|
555
|
+
data: {
|
|
556
|
+
initialState: timeTravelData.state,
|
|
557
|
+
runId: this.runId,
|
|
558
|
+
workflowId: this.workflowId,
|
|
559
|
+
stepResults: timeTravelData.stepResults,
|
|
560
|
+
timeTravel: timeTravelData,
|
|
561
|
+
tracingOptions: params.tracingOptions,
|
|
562
|
+
outputOptions: params.outputOptions,
|
|
563
|
+
requestContext: params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {}
|
|
167
564
|
}
|
|
168
565
|
});
|
|
169
566
|
const eventId = eventOutput.ids[0];
|
|
@@ -177,12 +574,12 @@ var InngestRun = class extends workflows.Run {
|
|
|
177
574
|
}
|
|
178
575
|
return result;
|
|
179
576
|
}
|
|
180
|
-
watch(cb
|
|
577
|
+
watch(cb) {
|
|
181
578
|
let active = true;
|
|
182
579
|
const streamPromise = realtime.subscribe(
|
|
183
580
|
{
|
|
184
581
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
185
|
-
topics: [
|
|
582
|
+
topics: ["watch"],
|
|
186
583
|
app: this.inngest
|
|
187
584
|
},
|
|
188
585
|
(message) => {
|
|
@@ -200,16 +597,35 @@ var InngestRun = class extends workflows.Run {
|
|
|
200
597
|
});
|
|
201
598
|
};
|
|
202
599
|
}
|
|
203
|
-
|
|
600
|
+
streamLegacy({ inputData, requestContext } = {}) {
|
|
204
601
|
const { readable, writable } = new TransformStream();
|
|
205
602
|
const writer = writable.getWriter();
|
|
603
|
+
void writer.write({
|
|
604
|
+
// @ts-ignore
|
|
605
|
+
type: "start",
|
|
606
|
+
// @ts-ignore
|
|
607
|
+
payload: { runId: this.runId }
|
|
608
|
+
});
|
|
206
609
|
const unwatch = this.watch(async (event) => {
|
|
207
610
|
try {
|
|
208
|
-
|
|
611
|
+
const e = {
|
|
612
|
+
...event,
|
|
613
|
+
type: event.type.replace("workflow-", "")
|
|
614
|
+
};
|
|
615
|
+
if (e.type === "step-output") {
|
|
616
|
+
e.type = e.payload.output.type;
|
|
617
|
+
e.payload = e.payload.output.payload;
|
|
618
|
+
}
|
|
619
|
+
await writer.write(e);
|
|
209
620
|
} catch {
|
|
210
621
|
}
|
|
211
|
-
}
|
|
622
|
+
});
|
|
212
623
|
this.closeStreamAction = async () => {
|
|
624
|
+
await writer.write({
|
|
625
|
+
type: "finish",
|
|
626
|
+
// @ts-ignore
|
|
627
|
+
payload: { runId: this.runId }
|
|
628
|
+
});
|
|
213
629
|
unwatch();
|
|
214
630
|
try {
|
|
215
631
|
await writer.close();
|
|
@@ -219,7 +635,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
219
635
|
writer.releaseLock();
|
|
220
636
|
}
|
|
221
637
|
};
|
|
222
|
-
this.executionResults = this.
|
|
638
|
+
this.executionResults = this._start({ inputData, requestContext, format: "legacy" }).then((result) => {
|
|
223
639
|
if (result.status !== "suspended") {
|
|
224
640
|
this.closeStreamAction?.().catch(() => {
|
|
225
641
|
});
|
|
@@ -231,57 +647,190 @@ var InngestRun = class extends workflows.Run {
|
|
|
231
647
|
getWorkflowState: () => this.executionResults
|
|
232
648
|
};
|
|
233
649
|
}
|
|
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;
|
|
650
|
+
stream({
|
|
651
|
+
inputData,
|
|
652
|
+
requestContext,
|
|
653
|
+
tracingOptions,
|
|
654
|
+
closeOnSuspend = true,
|
|
655
|
+
initialState,
|
|
656
|
+
outputOptions
|
|
657
|
+
} = {}) {
|
|
658
|
+
if (this.closeStreamAction && this.streamOutput) {
|
|
659
|
+
return this.streamOutput;
|
|
270
660
|
}
|
|
271
|
-
|
|
272
|
-
return null;
|
|
273
|
-
}
|
|
274
|
-
return {
|
|
275
|
-
status: run.snapshot.status,
|
|
276
|
-
result: run.snapshot.result,
|
|
277
|
-
error: run.snapshot.error,
|
|
278
|
-
payload: run.snapshot.context?.input,
|
|
279
|
-
steps: run.snapshot.context
|
|
661
|
+
this.closeStreamAction = async () => {
|
|
280
662
|
};
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
663
|
+
const self = this;
|
|
664
|
+
const stream$1 = new web.ReadableStream({
|
|
665
|
+
async start(controller) {
|
|
666
|
+
const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
|
|
667
|
+
controller.enqueue({
|
|
668
|
+
type,
|
|
669
|
+
runId: self.runId,
|
|
670
|
+
from,
|
|
671
|
+
payload: {
|
|
672
|
+
stepName: payload?.id,
|
|
673
|
+
...payload
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
});
|
|
677
|
+
self.closeStreamAction = async () => {
|
|
678
|
+
unwatch();
|
|
679
|
+
try {
|
|
680
|
+
await controller.close();
|
|
681
|
+
} catch (err) {
|
|
682
|
+
console.error("Error closing stream:", err);
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
const executionResultsPromise = self._start({
|
|
686
|
+
inputData,
|
|
687
|
+
requestContext,
|
|
688
|
+
// tracingContext, // We are not able to pass a reference to a span here, what to do?
|
|
689
|
+
initialState,
|
|
690
|
+
tracingOptions,
|
|
691
|
+
outputOptions,
|
|
692
|
+
format: "vnext"
|
|
693
|
+
});
|
|
694
|
+
let executionResults;
|
|
695
|
+
try {
|
|
696
|
+
executionResults = await executionResultsPromise;
|
|
697
|
+
if (closeOnSuspend) {
|
|
698
|
+
self.closeStreamAction?.().catch(() => {
|
|
699
|
+
});
|
|
700
|
+
} else if (executionResults.status !== "suspended") {
|
|
701
|
+
self.closeStreamAction?.().catch(() => {
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
if (self.streamOutput) {
|
|
705
|
+
self.streamOutput.updateResults(
|
|
706
|
+
executionResults
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
} catch (err) {
|
|
710
|
+
self.streamOutput?.rejectResults(err);
|
|
711
|
+
self.closeStreamAction?.().catch(() => {
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
});
|
|
716
|
+
this.streamOutput = new stream.WorkflowRunOutput({
|
|
717
|
+
runId: this.runId,
|
|
718
|
+
workflowId: this.workflowId,
|
|
719
|
+
stream: stream$1
|
|
720
|
+
});
|
|
721
|
+
return this.streamOutput;
|
|
722
|
+
}
|
|
723
|
+
streamVNext(args = {}) {
|
|
724
|
+
return this.stream(args);
|
|
725
|
+
}
|
|
726
|
+
timeTravelStream({
|
|
727
|
+
inputData,
|
|
728
|
+
resumeData,
|
|
729
|
+
initialState,
|
|
730
|
+
step,
|
|
731
|
+
context,
|
|
732
|
+
nestedStepsContext,
|
|
733
|
+
requestContext,
|
|
734
|
+
tracingOptions,
|
|
735
|
+
outputOptions
|
|
736
|
+
}) {
|
|
737
|
+
this.closeStreamAction = async () => {
|
|
738
|
+
};
|
|
739
|
+
const self = this;
|
|
740
|
+
const stream$1 = new web.ReadableStream({
|
|
741
|
+
async start(controller) {
|
|
742
|
+
const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
|
|
743
|
+
controller.enqueue({
|
|
744
|
+
type,
|
|
745
|
+
runId: self.runId,
|
|
746
|
+
from,
|
|
747
|
+
payload: {
|
|
748
|
+
stepName: payload?.id,
|
|
749
|
+
...payload
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
});
|
|
753
|
+
self.closeStreamAction = async () => {
|
|
754
|
+
unwatch();
|
|
755
|
+
try {
|
|
756
|
+
controller.close();
|
|
757
|
+
} catch (err) {
|
|
758
|
+
console.error("Error closing stream:", err);
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
const executionResultsPromise = self._timeTravel({
|
|
762
|
+
inputData,
|
|
763
|
+
step,
|
|
764
|
+
context,
|
|
765
|
+
nestedStepsContext,
|
|
766
|
+
resumeData,
|
|
767
|
+
initialState,
|
|
768
|
+
requestContext,
|
|
769
|
+
tracingOptions,
|
|
770
|
+
outputOptions
|
|
771
|
+
});
|
|
772
|
+
self.executionResults = executionResultsPromise;
|
|
773
|
+
let executionResults;
|
|
774
|
+
try {
|
|
775
|
+
executionResults = await executionResultsPromise;
|
|
776
|
+
self.closeStreamAction?.().catch(() => {
|
|
777
|
+
});
|
|
778
|
+
if (self.streamOutput) {
|
|
779
|
+
self.streamOutput.updateResults(executionResults);
|
|
780
|
+
}
|
|
781
|
+
} catch (err) {
|
|
782
|
+
self.streamOutput?.rejectResults(err);
|
|
783
|
+
self.closeStreamAction?.().catch(() => {
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
});
|
|
788
|
+
this.streamOutput = new stream.WorkflowRunOutput({
|
|
789
|
+
runId: this.runId,
|
|
790
|
+
workflowId: this.workflowId,
|
|
791
|
+
stream: stream$1
|
|
792
|
+
});
|
|
793
|
+
return this.streamOutput;
|
|
794
|
+
}
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
// src/workflow.ts
|
|
798
|
+
var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
799
|
+
#mastra;
|
|
800
|
+
inngest;
|
|
801
|
+
function;
|
|
802
|
+
flowControlConfig;
|
|
803
|
+
constructor(params, inngest) {
|
|
804
|
+
const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
|
|
805
|
+
super(workflowParams);
|
|
806
|
+
this.engineType = "inngest";
|
|
807
|
+
const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
|
|
808
|
+
([_, value]) => value !== void 0
|
|
809
|
+
);
|
|
810
|
+
this.flowControlConfig = flowControlEntries.length > 0 ? Object.fromEntries(flowControlEntries) : void 0;
|
|
811
|
+
this.#mastra = params.mastra;
|
|
812
|
+
this.inngest = inngest;
|
|
813
|
+
}
|
|
814
|
+
async listWorkflowRuns(args) {
|
|
815
|
+
const storage = this.#mastra?.getStorage();
|
|
816
|
+
if (!storage) {
|
|
817
|
+
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
818
|
+
return { runs: [], total: 0 };
|
|
819
|
+
}
|
|
820
|
+
return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
|
|
821
|
+
}
|
|
822
|
+
async getWorkflowRunById(runId) {
|
|
823
|
+
const storage = this.#mastra?.getStorage();
|
|
824
|
+
if (!storage) {
|
|
825
|
+
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
826
|
+
return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
|
|
827
|
+
}
|
|
828
|
+
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
829
|
+
return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
|
|
830
|
+
}
|
|
831
|
+
__registerMastra(mastra) {
|
|
832
|
+
this.#mastra = mastra;
|
|
833
|
+
this.executionEngine.__registerMastra(mastra);
|
|
285
834
|
const updateNested = (step) => {
|
|
286
835
|
if ((step.type === "step" || step.type === "loop" || step.type === "foreach") && step.step instanceof _InngestWorkflow) {
|
|
287
836
|
step.step.__registerMastra(mastra);
|
|
@@ -297,56 +846,49 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
297
846
|
}
|
|
298
847
|
}
|
|
299
848
|
}
|
|
300
|
-
createRun(options) {
|
|
849
|
+
async createRun(options) {
|
|
301
850
|
const runIdToUse = options?.runId || crypto.randomUUID();
|
|
302
851
|
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
303
852
|
{
|
|
304
853
|
workflowId: this.id,
|
|
305
854
|
runId: runIdToUse,
|
|
855
|
+
resourceId: options?.resourceId,
|
|
306
856
|
executionEngine: this.executionEngine,
|
|
307
857
|
executionGraph: this.executionGraph,
|
|
308
858
|
serializedStepGraph: this.serializedStepGraph,
|
|
309
859
|
mastra: this.#mastra,
|
|
310
860
|
retryConfig: this.retryConfig,
|
|
311
|
-
cleanup: () => this.runs.delete(runIdToUse)
|
|
861
|
+
cleanup: () => this.runs.delete(runIdToUse),
|
|
862
|
+
workflowSteps: this.steps,
|
|
863
|
+
workflowEngineType: this.engineType,
|
|
864
|
+
validateInputs: this.options.validateInputs
|
|
312
865
|
},
|
|
313
866
|
this.inngest
|
|
314
867
|
);
|
|
315
868
|
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) {
|
|
869
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
|
|
870
|
+
workflowStatus: run.workflowRunStatus,
|
|
871
|
+
stepResults: {}
|
|
872
|
+
});
|
|
873
|
+
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
|
|
874
|
+
if (!workflowSnapshotInStorage && shouldPersistSnapshot) {
|
|
336
875
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
337
876
|
workflowName: this.id,
|
|
338
877
|
runId: runIdToUse,
|
|
878
|
+
resourceId: options?.resourceId,
|
|
339
879
|
snapshot: {
|
|
340
880
|
runId: runIdToUse,
|
|
341
881
|
status: "pending",
|
|
342
882
|
value: {},
|
|
343
883
|
context: {},
|
|
344
884
|
activePaths: [],
|
|
885
|
+
activeStepsPath: {},
|
|
886
|
+
waitingPaths: {},
|
|
345
887
|
serializedStepGraph: this.serializedStepGraph,
|
|
346
888
|
suspendedPaths: {},
|
|
889
|
+
resumeLabels: {},
|
|
347
890
|
result: void 0,
|
|
348
891
|
error: void 0,
|
|
349
|
-
// @ts-ignore
|
|
350
892
|
timestamp: Date.now()
|
|
351
893
|
}
|
|
352
894
|
});
|
|
@@ -360,13 +902,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
360
902
|
this.function = this.inngest.createFunction(
|
|
361
903
|
{
|
|
362
904
|
id: `workflow.${this.id}`,
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
905
|
+
retries: Math.min(this.retryConfig?.attempts ?? 0, 20),
|
|
906
|
+
cancelOn: [{ event: `cancel.workflow.${this.id}` }],
|
|
907
|
+
// Spread flow control configuration
|
|
908
|
+
...this.flowControlConfig
|
|
366
909
|
},
|
|
367
910
|
{ event: `workflow.${this.id}` },
|
|
368
911
|
async ({ event, step, attempt, publish }) => {
|
|
369
|
-
let { inputData, runId, resume } = event.data;
|
|
912
|
+
let { inputData, initialState, runId, resourceId, resume, outputOptions, format, timeTravel } = event.data;
|
|
370
913
|
if (!runId) {
|
|
371
914
|
runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
|
|
372
915
|
return crypto.randomUUID();
|
|
@@ -394,19 +937,38 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
394
937
|
once: (_event, _callback) => {
|
|
395
938
|
}
|
|
396
939
|
};
|
|
397
|
-
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
940
|
+
const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
|
|
398
941
|
const result = await engine.execute({
|
|
399
942
|
workflowId: this.id,
|
|
400
943
|
runId,
|
|
944
|
+
resourceId,
|
|
401
945
|
graph: this.executionGraph,
|
|
402
946
|
serializedStepGraph: this.serializedStepGraph,
|
|
403
947
|
input: inputData,
|
|
948
|
+
initialState,
|
|
404
949
|
emitter,
|
|
405
950
|
retryConfig: this.retryConfig,
|
|
406
|
-
|
|
407
|
-
// TODO
|
|
951
|
+
requestContext: new di.RequestContext(Object.entries(event.data.requestContext ?? {})),
|
|
408
952
|
resume,
|
|
409
|
-
|
|
953
|
+
timeTravel,
|
|
954
|
+
format,
|
|
955
|
+
abortController: new AbortController(),
|
|
956
|
+
// currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
|
|
957
|
+
outputOptions,
|
|
958
|
+
writableStream: new web.WritableStream({
|
|
959
|
+
write(chunk) {
|
|
960
|
+
void emitter.emit("watch", chunk).catch(() => {
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
})
|
|
964
|
+
});
|
|
965
|
+
await step.run(`workflow.${this.id}.finalize`, async () => {
|
|
966
|
+
if (result.status === "failed") {
|
|
967
|
+
throw new inngest.NonRetriableError(`Workflow failed`, {
|
|
968
|
+
cause: result
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
return result;
|
|
410
972
|
});
|
|
411
973
|
return { result, runId };
|
|
412
974
|
}
|
|
@@ -430,27 +992,70 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
430
992
|
return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
|
|
431
993
|
}
|
|
432
994
|
};
|
|
995
|
+
function serve({
|
|
996
|
+
mastra,
|
|
997
|
+
inngest,
|
|
998
|
+
functions: userFunctions = [],
|
|
999
|
+
registerOptions
|
|
1000
|
+
}) {
|
|
1001
|
+
const wfs = mastra.listWorkflows();
|
|
1002
|
+
const workflowFunctions = Array.from(
|
|
1003
|
+
new Set(
|
|
1004
|
+
Object.values(wfs).flatMap((wf) => {
|
|
1005
|
+
if (wf instanceof InngestWorkflow) {
|
|
1006
|
+
wf.__registerMastra(mastra);
|
|
1007
|
+
return wf.getFunctions();
|
|
1008
|
+
}
|
|
1009
|
+
return [];
|
|
1010
|
+
})
|
|
1011
|
+
)
|
|
1012
|
+
);
|
|
1013
|
+
return hono.serve({
|
|
1014
|
+
...registerOptions,
|
|
1015
|
+
client: inngest,
|
|
1016
|
+
functions: [...workflowFunctions, ...userFunctions]
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
// src/types.ts
|
|
1021
|
+
var _compatibilityCheck = true;
|
|
1022
|
+
|
|
1023
|
+
// src/index.ts
|
|
433
1024
|
function isAgent(params) {
|
|
434
1025
|
return params?.component === "AGENT";
|
|
435
1026
|
}
|
|
436
1027
|
function isTool(params) {
|
|
437
1028
|
return params instanceof tools.Tool;
|
|
438
1029
|
}
|
|
439
|
-
function
|
|
1030
|
+
function isInngestWorkflow(params) {
|
|
1031
|
+
return params instanceof InngestWorkflow;
|
|
1032
|
+
}
|
|
1033
|
+
function createStep(params, agentOptions) {
|
|
1034
|
+
if (isInngestWorkflow(params)) {
|
|
1035
|
+
return params;
|
|
1036
|
+
}
|
|
440
1037
|
if (isAgent(params)) {
|
|
441
1038
|
return {
|
|
442
1039
|
id: params.name,
|
|
443
|
-
|
|
1040
|
+
description: params.getDescription(),
|
|
444
1041
|
inputSchema: zod.z.object({
|
|
445
1042
|
prompt: zod.z.string()
|
|
446
1043
|
// resourceId: z.string().optional(),
|
|
447
1044
|
// threadId: z.string().optional(),
|
|
448
1045
|
}),
|
|
449
|
-
// @ts-ignore
|
|
450
1046
|
outputSchema: zod.z.object({
|
|
451
1047
|
text: zod.z.string()
|
|
452
1048
|
}),
|
|
453
|
-
execute: async ({
|
|
1049
|
+
execute: async ({
|
|
1050
|
+
inputData,
|
|
1051
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1052
|
+
[_constants.STREAM_FORMAT_SYMBOL]: streamFormat,
|
|
1053
|
+
requestContext,
|
|
1054
|
+
tracingContext,
|
|
1055
|
+
abortSignal,
|
|
1056
|
+
abort,
|
|
1057
|
+
writer
|
|
1058
|
+
}) => {
|
|
454
1059
|
let streamPromise = {};
|
|
455
1060
|
streamPromise.promise = new Promise((resolve, reject) => {
|
|
456
1061
|
streamPromise.resolve = resolve;
|
|
@@ -460,50 +1065,65 @@ function createStep(params) {
|
|
|
460
1065
|
name: params.name,
|
|
461
1066
|
args: inputData
|
|
462
1067
|
};
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
1068
|
+
let stream;
|
|
1069
|
+
if ((await params.getModel()).specificationVersion === "v1") {
|
|
1070
|
+
const { fullStream } = await params.streamLegacy(inputData.prompt, {
|
|
1071
|
+
...agentOptions ?? {},
|
|
1072
|
+
// resourceId: inputData.resourceId,
|
|
1073
|
+
// threadId: inputData.threadId,
|
|
1074
|
+
requestContext,
|
|
1075
|
+
tracingContext,
|
|
1076
|
+
onFinish: (result) => {
|
|
1077
|
+
streamPromise.resolve(result.text);
|
|
1078
|
+
void agentOptions?.onFinish?.(result);
|
|
1079
|
+
},
|
|
1080
|
+
abortSignal
|
|
1081
|
+
});
|
|
1082
|
+
stream = fullStream;
|
|
1083
|
+
} else {
|
|
1084
|
+
const modelOutput = await params.stream(inputData.prompt, {
|
|
1085
|
+
...agentOptions ?? {},
|
|
1086
|
+
requestContext,
|
|
1087
|
+
tracingContext,
|
|
1088
|
+
onFinish: (result) => {
|
|
1089
|
+
streamPromise.resolve(result.text);
|
|
1090
|
+
void agentOptions?.onFinish?.(result);
|
|
1091
|
+
},
|
|
1092
|
+
abortSignal
|
|
1093
|
+
});
|
|
1094
|
+
stream = modelOutput.fullStream;
|
|
478
1095
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
1096
|
+
if (streamFormat === "legacy") {
|
|
1097
|
+
await emitter.emit("watch", {
|
|
1098
|
+
type: "tool-call-streaming-start",
|
|
1099
|
+
...toolData ?? {}
|
|
1100
|
+
});
|
|
1101
|
+
for await (const chunk of stream) {
|
|
1102
|
+
if (chunk.type === "text-delta") {
|
|
1103
|
+
await emitter.emit("watch", {
|
|
483
1104
|
type: "tool-call-delta",
|
|
484
|
-
...toolData,
|
|
1105
|
+
...toolData ?? {},
|
|
485
1106
|
argsTextDelta: chunk.textDelta
|
|
486
1107
|
});
|
|
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;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
await emitter.emit("watch", {
|
|
1111
|
+
type: "tool-call-streaming-finish",
|
|
1112
|
+
...toolData ?? {}
|
|
1113
|
+
});
|
|
1114
|
+
} else {
|
|
1115
|
+
for await (const chunk of stream) {
|
|
1116
|
+
await writer.write(chunk);
|
|
501
1117
|
}
|
|
502
1118
|
}
|
|
1119
|
+
if (abortSignal.aborted) {
|
|
1120
|
+
return abort();
|
|
1121
|
+
}
|
|
503
1122
|
return {
|
|
504
1123
|
text: await streamPromise.promise
|
|
505
1124
|
};
|
|
506
|
-
}
|
|
1125
|
+
},
|
|
1126
|
+
component: params.component
|
|
507
1127
|
};
|
|
508
1128
|
}
|
|
509
1129
|
if (isTool(params)) {
|
|
@@ -512,17 +1132,40 @@ function createStep(params) {
|
|
|
512
1132
|
}
|
|
513
1133
|
return {
|
|
514
1134
|
// TODO: tool probably should have strong id type
|
|
515
|
-
// @ts-ignore
|
|
516
1135
|
id: params.id,
|
|
1136
|
+
description: params.description,
|
|
517
1137
|
inputSchema: params.inputSchema,
|
|
518
1138
|
outputSchema: params.outputSchema,
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
1139
|
+
suspendSchema: params.suspendSchema,
|
|
1140
|
+
resumeSchema: params.resumeSchema,
|
|
1141
|
+
execute: async ({
|
|
1142
|
+
inputData,
|
|
1143
|
+
mastra,
|
|
1144
|
+
requestContext,
|
|
1145
|
+
tracingContext,
|
|
1146
|
+
suspend,
|
|
1147
|
+
resumeData,
|
|
1148
|
+
runId,
|
|
1149
|
+
workflowId,
|
|
1150
|
+
state,
|
|
1151
|
+
setState
|
|
1152
|
+
}) => {
|
|
1153
|
+
const toolContext = {
|
|
522
1154
|
mastra,
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
1155
|
+
requestContext,
|
|
1156
|
+
tracingContext,
|
|
1157
|
+
workflow: {
|
|
1158
|
+
runId,
|
|
1159
|
+
resumeData,
|
|
1160
|
+
suspend,
|
|
1161
|
+
workflowId,
|
|
1162
|
+
state,
|
|
1163
|
+
setState
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
return params.execute(inputData, toolContext);
|
|
1167
|
+
},
|
|
1168
|
+
component: "TOOL"
|
|
526
1169
|
};
|
|
527
1170
|
}
|
|
528
1171
|
return {
|
|
@@ -538,7 +1181,10 @@ function createStep(params) {
|
|
|
538
1181
|
function init(inngest) {
|
|
539
1182
|
return {
|
|
540
1183
|
createWorkflow(params) {
|
|
541
|
-
return new InngestWorkflow(
|
|
1184
|
+
return new InngestWorkflow(
|
|
1185
|
+
params,
|
|
1186
|
+
inngest
|
|
1187
|
+
);
|
|
542
1188
|
},
|
|
543
1189
|
createStep,
|
|
544
1190
|
cloneStep(step, opts) {
|
|
@@ -547,7 +1193,13 @@ function init(inngest) {
|
|
|
547
1193
|
description: step.description,
|
|
548
1194
|
inputSchema: step.inputSchema,
|
|
549
1195
|
outputSchema: step.outputSchema,
|
|
550
|
-
|
|
1196
|
+
resumeSchema: step.resumeSchema,
|
|
1197
|
+
suspendSchema: step.suspendSchema,
|
|
1198
|
+
stateSchema: step.stateSchema,
|
|
1199
|
+
execute: step.execute,
|
|
1200
|
+
retries: step.retries,
|
|
1201
|
+
scorers: step.scorers,
|
|
1202
|
+
component: step.component
|
|
551
1203
|
};
|
|
552
1204
|
},
|
|
553
1205
|
cloneWorkflow(workflow, opts) {
|
|
@@ -556,7 +1208,8 @@ function init(inngest) {
|
|
|
556
1208
|
inputSchema: workflow.inputSchema,
|
|
557
1209
|
outputSchema: workflow.outputSchema,
|
|
558
1210
|
steps: workflow.stepDefs,
|
|
559
|
-
mastra: workflow.mastra
|
|
1211
|
+
mastra: workflow.mastra,
|
|
1212
|
+
options: workflow.options
|
|
560
1213
|
});
|
|
561
1214
|
wf.setStepFlow(workflow.stepGraph);
|
|
562
1215
|
wf.commit();
|
|
@@ -564,736 +1217,11 @@ function init(inngest) {
|
|
|
564
1217
|
}
|
|
565
1218
|
};
|
|
566
1219
|
}
|
|
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
1220
|
|
|
1294
1221
|
exports.InngestExecutionEngine = InngestExecutionEngine;
|
|
1295
1222
|
exports.InngestRun = InngestRun;
|
|
1296
1223
|
exports.InngestWorkflow = InngestWorkflow;
|
|
1224
|
+
exports._compatibilityCheck = _compatibilityCheck;
|
|
1297
1225
|
exports.createStep = createStep;
|
|
1298
1226
|
exports.init = init;
|
|
1299
1227
|
exports.serve = serve;
|