@mastra/core 0.10.12 → 0.10.13

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.
Files changed (235) hide show
  1. package/package.json +1 -1
  2. package/a2a.d.ts +0 -1
  3. package/agent.d.ts +0 -1
  4. package/base.d.ts +0 -1
  5. package/bundler.d.ts +0 -1
  6. package/deployer.d.ts +0 -1
  7. package/di.d.ts +0 -1
  8. package/dist/a2a/index.cjs +0 -79
  9. package/dist/a2a/index.d.cts +0 -780
  10. package/dist/a2a/index.d.ts +0 -780
  11. package/dist/a2a/index.js +0 -68
  12. package/dist/agent/index.cjs +0 -15
  13. package/dist/agent/index.d.cts +0 -29
  14. package/dist/agent/index.d.ts +0 -29
  15. package/dist/agent/index.js +0 -2
  16. package/dist/base-B_y9sMg0.d.cts +0 -162
  17. package/dist/base-CS5eSXbL.d.cts +0 -4117
  18. package/dist/base-ClrXcCRx.d.ts +0 -162
  19. package/dist/base-DBhKcre4.d.ts +0 -4117
  20. package/dist/base.cjs +0 -10
  21. package/dist/base.d.cts +0 -6
  22. package/dist/base.d.ts +0 -6
  23. package/dist/base.js +0 -1
  24. package/dist/bundler/index.cjs +0 -10
  25. package/dist/bundler/index.d.cts +0 -30
  26. package/dist/bundler/index.d.ts +0 -30
  27. package/dist/bundler/index.js +0 -1
  28. package/dist/chunk-2GRYVZ2O.cjs +0 -244
  29. package/dist/chunk-2HDFKWFU.js +0 -2249
  30. package/dist/chunk-32C7JDIZ.js +0 -1
  31. package/dist/chunk-4UBOJFSL.js +0 -989
  32. package/dist/chunk-4UWPFBC6.js +0 -88
  33. package/dist/chunk-4Z3OU5RY.cjs +0 -31
  34. package/dist/chunk-5HTMDAXP.js +0 -359
  35. package/dist/chunk-5IEKR756.js +0 -53
  36. package/dist/chunk-5YDTZN2X.js +0 -114
  37. package/dist/chunk-6UNGH46J.js +0 -75
  38. package/dist/chunk-6Y4UL5Z6.cjs +0 -94
  39. package/dist/chunk-7F6BQXE2.cjs +0 -425
  40. package/dist/chunk-7H2GET5Z.cjs +0 -668
  41. package/dist/chunk-7HZ6NIAF.cjs +0 -2
  42. package/dist/chunk-7MZNOW6W.cjs +0 -2263
  43. package/dist/chunk-7XQIPES3.js +0 -668
  44. package/dist/chunk-AKYTYALY.js +0 -70
  45. package/dist/chunk-ATXBSEFT.js +0 -22
  46. package/dist/chunk-B6TOBUS6.cjs +0 -80
  47. package/dist/chunk-B7SQOKEC.cjs +0 -91
  48. package/dist/chunk-BB4KXGBU.js +0 -83
  49. package/dist/chunk-BB6DPGIV.cjs +0 -6
  50. package/dist/chunk-C4LMN2IR.js +0 -27
  51. package/dist/chunk-DFFVEKIG.js +0 -407
  52. package/dist/chunk-E7AX3U6M.cjs +0 -659
  53. package/dist/chunk-EWCOOO3H.js +0 -5007
  54. package/dist/chunk-F2WMR75C.cjs +0 -183
  55. package/dist/chunk-FBKJ3652.cjs +0 -5034
  56. package/dist/chunk-FEYYOBBG.cjs +0 -24
  57. package/dist/chunk-FL5SZ2XU.js +0 -181
  58. package/dist/chunk-GH2KM66J.js +0 -37
  59. package/dist/chunk-GWFS5DAR.cjs +0 -37
  60. package/dist/chunk-HNEE7IF4.js +0 -60
  61. package/dist/chunk-HSVOEWAM.cjs +0 -2
  62. package/dist/chunk-J52TXHZV.cjs +0 -73
  63. package/dist/chunk-JNMQKJH4.js +0 -10
  64. package/dist/chunk-JQOMTERC.js +0 -89
  65. package/dist/chunk-LABUWBKX.cjs +0 -71
  66. package/dist/chunk-LXFZUKP3.cjs +0 -34
  67. package/dist/chunk-MP2QBLUJ.cjs +0 -70
  68. package/dist/chunk-MUNFCOMB.cjs +0 -62
  69. package/dist/chunk-NH5WJNNS.js +0 -1
  70. package/dist/chunk-P3Q73CAW.cjs +0 -55
  71. package/dist/chunk-PA2YIVIT.js +0 -61
  72. package/dist/chunk-QFTBW7ZZ.cjs +0 -2
  73. package/dist/chunk-QQ5K5TZE.cjs +0 -619
  74. package/dist/chunk-QUSEDVYI.cjs +0 -991
  75. package/dist/chunk-R4V75T7J.js +0 -1
  76. package/dist/chunk-SGGPJWRQ.js +0 -69
  77. package/dist/chunk-ST5RMVLG.cjs +0 -87
  78. package/dist/chunk-TC2SCOTE.js +0 -605
  79. package/dist/chunk-U64IJDC5.cjs +0 -109
  80. package/dist/chunk-UX3B6S2I.cjs +0 -65
  81. package/dist/chunk-V5D2LIF5.js +0 -68
  82. package/dist/chunk-VG4OPO2R.js +0 -240
  83. package/dist/chunk-WQNOATKB.js +0 -103
  84. package/dist/chunk-Y7D2JLKS.js +0 -4
  85. package/dist/chunk-YJEHXYK5.js +0 -657
  86. package/dist/chunk-YOQP5T77.js +0 -32
  87. package/dist/chunk-ZIZ3CVHN.cjs +0 -120
  88. package/dist/chunk-ZPOUMTTH.cjs +0 -362
  89. package/dist/chunk-ZZLBNB3U.cjs +0 -12
  90. package/dist/deployer/index.cjs +0 -10
  91. package/dist/deployer/index.d.cts +0 -19
  92. package/dist/deployer/index.d.ts +0 -19
  93. package/dist/deployer/index.js +0 -1
  94. package/dist/di/index.cjs +0 -10
  95. package/dist/di/index.d.cts +0 -1
  96. package/dist/di/index.d.ts +0 -1
  97. package/dist/di/index.js +0 -1
  98. package/dist/error/index.cjs +0 -22
  99. package/dist/error/index.d.cts +0 -86
  100. package/dist/error/index.d.ts +0 -86
  101. package/dist/error/index.js +0 -1
  102. package/dist/eval/index.cjs +0 -14
  103. package/dist/eval/index.d.cts +0 -43
  104. package/dist/eval/index.d.ts +0 -43
  105. package/dist/eval/index.js +0 -1
  106. package/dist/hooks/index.cjs +0 -18
  107. package/dist/hooks/index.d.cts +0 -33
  108. package/dist/hooks/index.d.ts +0 -33
  109. package/dist/hooks/index.js +0 -1
  110. package/dist/index.cjs +0 -281
  111. package/dist/index.d.cts +0 -92
  112. package/dist/index.d.ts +0 -92
  113. package/dist/index.js +0 -112
  114. package/dist/integration/index.cjs +0 -14
  115. package/dist/integration/index.d.cts +0 -65
  116. package/dist/integration/index.d.ts +0 -65
  117. package/dist/integration/index.js +0 -1
  118. package/dist/llm/index.cjs +0 -10
  119. package/dist/llm/index.d.cts +0 -29
  120. package/dist/llm/index.d.ts +0 -29
  121. package/dist/llm/index.js +0 -1
  122. package/dist/logger/index.cjs +0 -43
  123. package/dist/logger/index.d.cts +0 -96
  124. package/dist/logger/index.d.ts +0 -96
  125. package/dist/logger/index.js +0 -2
  126. package/dist/logger-B8XXh6ya.d.cts +0 -159
  127. package/dist/logger-Bpa2oLL4.d.ts +0 -159
  128. package/dist/mastra/index.cjs +0 -10
  129. package/dist/mastra/index.d.cts +0 -29
  130. package/dist/mastra/index.d.ts +0 -29
  131. package/dist/mastra/index.js +0 -1
  132. package/dist/mcp/index.cjs +0 -106
  133. package/dist/mcp/index.d.cts +0 -29
  134. package/dist/mcp/index.d.ts +0 -29
  135. package/dist/mcp/index.js +0 -100
  136. package/dist/memory/index.cjs +0 -18
  137. package/dist/memory/index.d.cts +0 -29
  138. package/dist/memory/index.d.ts +0 -29
  139. package/dist/memory/index.js +0 -1
  140. package/dist/network/index.cjs +0 -311
  141. package/dist/network/index.d.cts +0 -29
  142. package/dist/network/index.d.ts +0 -29
  143. package/dist/network/index.js +0 -309
  144. package/dist/network/vNext/index.cjs +0 -873
  145. package/dist/network/vNext/index.d.cts +0 -29
  146. package/dist/network/vNext/index.d.ts +0 -29
  147. package/dist/network/vNext/index.js +0 -871
  148. package/dist/relevance/index.cjs +0 -18
  149. package/dist/relevance/index.d.cts +0 -49
  150. package/dist/relevance/index.d.ts +0 -49
  151. package/dist/relevance/index.js +0 -1
  152. package/dist/runtime-context/index.cjs +0 -10
  153. package/dist/runtime-context/index.d.cts +0 -52
  154. package/dist/runtime-context/index.d.ts +0 -52
  155. package/dist/runtime-context/index.js +0 -1
  156. package/dist/server/index.cjs +0 -62
  157. package/dist/server/index.d.cts +0 -52
  158. package/dist/server/index.d.ts +0 -52
  159. package/dist/server/index.js +0 -59
  160. package/dist/storage/index.cjs +0 -336
  161. package/dist/storage/index.d.cts +0 -149
  162. package/dist/storage/index.d.ts +0 -149
  163. package/dist/storage/index.js +0 -303
  164. package/dist/telemetry/index.cjs +0 -30
  165. package/dist/telemetry/index.d.cts +0 -75
  166. package/dist/telemetry/index.d.ts +0 -75
  167. package/dist/telemetry/index.js +0 -1
  168. package/dist/telemetry/otel-vendor.cjs +0 -103
  169. package/dist/telemetry/otel-vendor.d.cts +0 -20
  170. package/dist/telemetry/otel-vendor.d.ts +0 -20
  171. package/dist/telemetry/otel-vendor.js +0 -57
  172. package/dist/tools/index.cjs +0 -18
  173. package/dist/tools/index.d.cts +0 -41
  174. package/dist/tools/index.d.ts +0 -41
  175. package/dist/tools/index.js +0 -1
  176. package/dist/tts/index.cjs +0 -10
  177. package/dist/tts/index.d.cts +0 -28
  178. package/dist/tts/index.d.ts +0 -28
  179. package/dist/tts/index.js +0 -1
  180. package/dist/types-Bo1uigWx.d.cts +0 -17
  181. package/dist/types-Bo1uigWx.d.ts +0 -17
  182. package/dist/utils.cjs +0 -58
  183. package/dist/utils.d.cts +0 -149
  184. package/dist/utils.d.ts +0 -149
  185. package/dist/utils.js +0 -1
  186. package/dist/vector/filter/index.cjs +0 -192
  187. package/dist/vector/filter/index.d.cts +0 -128
  188. package/dist/vector/filter/index.d.ts +0 -128
  189. package/dist/vector/filter/index.js +0 -190
  190. package/dist/vector/index.cjs +0 -10
  191. package/dist/vector/index.d.cts +0 -77
  192. package/dist/vector/index.d.ts +0 -77
  193. package/dist/vector/index.js +0 -1
  194. package/dist/voice/index.cjs +0 -18
  195. package/dist/voice/index.d.cts +0 -29
  196. package/dist/voice/index.d.ts +0 -29
  197. package/dist/voice/index.js +0 -1
  198. package/dist/workflows/constants.cjs +0 -10
  199. package/dist/workflows/constants.d.cts +0 -3
  200. package/dist/workflows/constants.d.ts +0 -3
  201. package/dist/workflows/constants.js +0 -1
  202. package/dist/workflows/index.cjs +0 -42
  203. package/dist/workflows/index.d.cts +0 -282
  204. package/dist/workflows/index.d.ts +0 -282
  205. package/dist/workflows/index.js +0 -1
  206. package/dist/workflows/legacy/index.cjs +0 -90
  207. package/dist/workflows/legacy/index.d.cts +0 -91
  208. package/dist/workflows/legacy/index.d.ts +0 -91
  209. package/dist/workflows/legacy/index.js +0 -1
  210. package/error.d.ts +0 -1
  211. package/eval.d.ts +0 -1
  212. package/hooks.d.ts +0 -1
  213. package/integration.d.ts +0 -1
  214. package/llm.d.ts +0 -1
  215. package/logger.d.ts +0 -1
  216. package/mastra.d.ts +0 -1
  217. package/mcp.d.ts +0 -1
  218. package/memory.d.ts +0 -1
  219. package/network/vNext.d.ts +0 -1
  220. package/network.d.ts +0 -1
  221. package/relevance.d.ts +0 -1
  222. package/runtime-context.d.ts +0 -1
  223. package/server.d.ts +0 -1
  224. package/storage.d.ts +0 -1
  225. package/telemetry/otel-vendor.d.ts +0 -1
  226. package/telemetry.d.ts +0 -1
  227. package/tools.d.ts +0 -1
  228. package/tts.d.ts +0 -1
  229. package/utils.d.ts +0 -1
  230. package/vector/filter.d.ts +0 -1
  231. package/vector.d.ts +0 -1
  232. package/voice.d.ts +0 -1
  233. package/workflows/_constants.d.ts +0 -1
  234. package/workflows/legacy.d.ts +0 -1
  235. package/workflows.d.ts +0 -1
@@ -1,2249 +0,0 @@
1
- import { EMITTER_SYMBOL } from './chunk-Y7D2JLKS.js';
2
- import { Agent } from './chunk-EWCOOO3H.js';
3
- import { Tool } from './chunk-C4LMN2IR.js';
4
- import { MastraError } from './chunk-6UNGH46J.js';
5
- import { MastraBase } from './chunk-5IEKR756.js';
6
- import { RegisteredLogger } from './chunk-5YDTZN2X.js';
7
- import { RuntimeContext } from './chunk-SGGPJWRQ.js';
8
- import { context, trace } from '@opentelemetry/api';
9
- import { randomUUID } from 'crypto';
10
- import EventEmitter from 'events';
11
- import { TransformStream } from 'stream/web';
12
- import { z } from 'zod';
13
-
14
- // src/workflows/execution-engine.ts
15
- var ExecutionEngine = class extends MastraBase {
16
- mastra;
17
- constructor({ mastra }) {
18
- super({ name: "ExecutionEngine", component: RegisteredLogger.WORKFLOW });
19
- this.mastra = mastra;
20
- }
21
- __registerMastra(mastra) {
22
- this.mastra = mastra;
23
- }
24
- };
25
- var DefaultExecutionEngine = class extends ExecutionEngine {
26
- /**
27
- * The runCounts map is used to keep track of the run count for each step.
28
- * The step id is used as the key and the run count is the value.
29
- */
30
- runCounts = /* @__PURE__ */ new Map();
31
- /**
32
- * Get or generate the run count for a step.
33
- * If the step id is not in the map, it will be added and the run count will be 0.
34
- * If the step id is in the map, it will return the run count.
35
- *
36
- * @param stepId - The id of the step.
37
- * @returns The run count for the step.
38
- */
39
- getOrGenerateRunCount(stepId) {
40
- if (this.runCounts.has(stepId)) {
41
- const currentRunCount = this.runCounts.get(stepId);
42
- const nextRunCount = currentRunCount + 1;
43
- this.runCounts.set(stepId, nextRunCount);
44
- return nextRunCount;
45
- }
46
- const runCount = 0;
47
- this.runCounts.set(stepId, runCount);
48
- return runCount;
49
- }
50
- async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
51
- const base = {
52
- status: lastOutput.status,
53
- steps: stepResults
54
- };
55
- if (lastOutput.status === "success") {
56
- await emitter.emit("watch", {
57
- type: "watch",
58
- payload: {
59
- workflowState: {
60
- status: lastOutput.status,
61
- steps: stepResults,
62
- result: lastOutput.output
63
- }
64
- },
65
- eventTimestamp: Date.now()
66
- });
67
- base.result = lastOutput.output;
68
- } else if (lastOutput.status === "failed") {
69
- await emitter.emit("watch", {
70
- type: "watch",
71
- payload: {
72
- workflowState: {
73
- status: lastOutput.status,
74
- steps: stepResults,
75
- result: null,
76
- error: lastOutput.error
77
- }
78
- },
79
- eventTimestamp: Date.now()
80
- });
81
- base.error = error instanceof Error ? error?.stack ?? error : lastOutput.error ?? (typeof error === "string" ? error : new Error("Unknown error: " + error)?.stack ?? new Error("Unknown error: " + error));
82
- } else if (lastOutput.status === "suspended") {
83
- const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
84
- if (stepResult?.status === "suspended") {
85
- const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
86
- return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
87
- }
88
- return [];
89
- });
90
- base.suspended = suspendedStepIds;
91
- await emitter.emit("watch", {
92
- type: "watch",
93
- payload: {
94
- workflowState: {
95
- status: lastOutput.status,
96
- steps: stepResults,
97
- result: null,
98
- error: null
99
- }
100
- },
101
- eventTimestamp: Date.now()
102
- });
103
- }
104
- executionSpan?.end();
105
- return base;
106
- }
107
- /**
108
- * Executes a workflow run with the provided execution graph and input
109
- * @param graph The execution graph to execute
110
- * @param input The input data for the workflow
111
- * @returns A promise that resolves to the workflow output
112
- */
113
- async execute(params) {
114
- const { workflowId, runId, graph, input, resume, retryConfig } = params;
115
- const { attempts = 0, delay = 0 } = retryConfig ?? {};
116
- const steps = graph.steps;
117
- if (steps.length === 0) {
118
- throw new MastraError({
119
- id: "WORKFLOW_EXECUTE_EMPTY_GRAPH",
120
- text: "Workflow must have at least one step",
121
- domain: "MASTRA_WORKFLOW" /* MASTRA_WORKFLOW */,
122
- category: "USER" /* USER */
123
- });
124
- }
125
- const executionSpan = this.mastra?.getTelemetry()?.tracer.startSpan(`workflow.${workflowId}.execute`, {
126
- attributes: { componentName: workflowId, runId }
127
- });
128
- let startIdx = 0;
129
- if (resume?.resumePath) {
130
- startIdx = resume.resumePath[0];
131
- resume.resumePath.shift();
132
- }
133
- const stepResults = resume?.stepResults || { input };
134
- let lastOutput;
135
- for (let i = startIdx; i < steps.length; i++) {
136
- const entry = steps[i];
137
- try {
138
- lastOutput = await this.executeEntry({
139
- workflowId,
140
- runId,
141
- entry,
142
- serializedStepGraph: params.serializedStepGraph,
143
- prevStep: steps[i - 1],
144
- stepResults,
145
- resume,
146
- executionContext: {
147
- workflowId,
148
- runId,
149
- executionPath: [i],
150
- suspendedPaths: {},
151
- retryConfig: { attempts, delay },
152
- executionSpan
153
- },
154
- abortController: params.abortController,
155
- emitter: params.emitter,
156
- runtimeContext: params.runtimeContext
157
- });
158
- if (lastOutput.result.status !== "success") {
159
- if (lastOutput.result.status === "bailed") {
160
- lastOutput.result.status = "success";
161
- }
162
- const result2 = await this.fmtReturnValue(
163
- executionSpan,
164
- params.emitter,
165
- stepResults,
166
- lastOutput.result
167
- );
168
- await this.persistStepUpdate({
169
- workflowId,
170
- runId,
171
- stepResults: lastOutput.stepResults,
172
- serializedStepGraph: params.serializedStepGraph,
173
- executionContext: lastOutput.executionContext,
174
- workflowStatus: result2.status,
175
- result: result2.result,
176
- error: result2.error
177
- });
178
- return result2;
179
- }
180
- } catch (e) {
181
- const error = e instanceof MastraError ? e : new MastraError(
182
- {
183
- id: "WORKFLOW_ENGINE_STEP_EXECUTION_FAILED",
184
- domain: "MASTRA_WORKFLOW" /* MASTRA_WORKFLOW */,
185
- category: "USER" /* USER */,
186
- details: { workflowId, runId }
187
- },
188
- e
189
- );
190
- this.logger?.trackException(error);
191
- this.logger?.error(`Error executing step: ${error?.stack}`);
192
- const result2 = await this.fmtReturnValue(
193
- executionSpan,
194
- params.emitter,
195
- stepResults,
196
- lastOutput.result,
197
- e
198
- );
199
- await this.persistStepUpdate({
200
- workflowId,
201
- runId,
202
- stepResults: lastOutput.stepResults,
203
- serializedStepGraph: params.serializedStepGraph,
204
- executionContext: lastOutput.executionContext,
205
- workflowStatus: result2.status,
206
- result: result2.result,
207
- error: result2.error
208
- });
209
- return result2;
210
- }
211
- }
212
- const result = await this.fmtReturnValue(executionSpan, params.emitter, stepResults, lastOutput.result);
213
- await this.persistStepUpdate({
214
- workflowId,
215
- runId,
216
- stepResults: lastOutput.stepResults,
217
- serializedStepGraph: params.serializedStepGraph,
218
- executionContext: lastOutput.executionContext,
219
- workflowStatus: result.status,
220
- result: result.result,
221
- error: result.error
222
- });
223
- return result;
224
- }
225
- getStepOutput(stepResults, step) {
226
- if (!step) {
227
- return stepResults.input;
228
- } else if (step.type === "step" || step.type === "waitForEvent") {
229
- return stepResults[step.step.id]?.output;
230
- } else if (step.type === "sleep" || step.type === "sleepUntil") {
231
- return stepResults[step.id]?.output;
232
- } else if (step.type === "parallel" || step.type === "conditional") {
233
- return step.steps.reduce(
234
- (acc, entry) => {
235
- if (entry.type === "step" || entry.type === "waitForEvent") {
236
- acc[entry.step.id] = stepResults[entry.step.id]?.output;
237
- } else if (entry.type === "parallel" || entry.type === "conditional") {
238
- const parallelResult = this.getStepOutput(stepResults, entry)?.output;
239
- acc = { ...acc, ...parallelResult };
240
- } else if (entry.type === "loop") {
241
- acc[entry.step.id] = stepResults[entry.step.id]?.output;
242
- } else if (entry.type === "foreach") {
243
- acc[entry.step.id] = stepResults[entry.step.id]?.output;
244
- } else if (entry.type === "sleep" || entry.type === "sleepUntil") {
245
- acc[entry.id] = stepResults[entry.id]?.output;
246
- }
247
- return acc;
248
- },
249
- {}
250
- );
251
- } else if (step.type === "loop") {
252
- return stepResults[step.step.id]?.output;
253
- } else if (step.type === "foreach") {
254
- return stepResults[step.step.id]?.output;
255
- }
256
- }
257
- async executeSleep({
258
- runId,
259
- entry,
260
- prevOutput,
261
- stepResults,
262
- emitter,
263
- abortController,
264
- runtimeContext
265
- }) {
266
- let { duration, fn } = entry;
267
- if (fn) {
268
- duration = await fn({
269
- runId,
270
- mastra: this.mastra,
271
- runtimeContext,
272
- inputData: prevOutput,
273
- runCount: -1,
274
- getInitData: () => stepResults?.input,
275
- getStepResult: (step) => {
276
- if (!step?.id) {
277
- return null;
278
- }
279
- const result = stepResults[step.id];
280
- if (result?.status === "success") {
281
- return result.output;
282
- }
283
- return null;
284
- },
285
- // TODO: this function shouldn't have suspend probably?
286
- suspend: async (_suspendPayload) => {
287
- },
288
- bail: () => {
289
- },
290
- abort: () => {
291
- abortController?.abort();
292
- },
293
- [EMITTER_SYMBOL]: emitter,
294
- engine: {},
295
- abortSignal: abortController?.signal
296
- });
297
- }
298
- await new Promise((resolve) => setTimeout(resolve, !duration || duration < 0 ? 0 : duration));
299
- }
300
- async executeSleepUntil({
301
- runId,
302
- entry,
303
- prevOutput,
304
- stepResults,
305
- emitter,
306
- abortController,
307
- runtimeContext
308
- }) {
309
- let { date, fn } = entry;
310
- if (fn) {
311
- date = await fn({
312
- runId,
313
- mastra: this.mastra,
314
- runtimeContext,
315
- inputData: prevOutput,
316
- runCount: -1,
317
- getInitData: () => stepResults?.input,
318
- getStepResult: (step) => {
319
- if (!step?.id) {
320
- return null;
321
- }
322
- const result = stepResults[step.id];
323
- if (result?.status === "success") {
324
- return result.output;
325
- }
326
- return null;
327
- },
328
- // TODO: this function shouldn't have suspend probably?
329
- suspend: async (_suspendPayload) => {
330
- },
331
- bail: () => {
332
- },
333
- abort: () => {
334
- abortController?.abort();
335
- },
336
- [EMITTER_SYMBOL]: emitter,
337
- engine: {},
338
- abortSignal: abortController?.signal
339
- });
340
- }
341
- const time = !date ? 0 : date?.getTime() - Date.now();
342
- await new Promise((resolve) => setTimeout(resolve, time < 0 ? 0 : time));
343
- }
344
- async executeWaitForEvent({
345
- event,
346
- emitter,
347
- timeout
348
- }) {
349
- return new Promise((resolve, reject) => {
350
- const cb = (eventData) => {
351
- resolve(eventData);
352
- };
353
- if (timeout) {
354
- setTimeout(() => {
355
- emitter.off(`user-event-${event}`, cb);
356
- reject(new Error("Timeout waiting for event"));
357
- }, timeout);
358
- }
359
- emitter.once(`user-event-${event}`, cb);
360
- });
361
- }
362
- async executeStep({
363
- workflowId,
364
- runId,
365
- step,
366
- stepResults,
367
- executionContext,
368
- resume,
369
- prevOutput,
370
- emitter,
371
- abortController,
372
- runtimeContext
373
- }) {
374
- const startTime = resume?.steps[0] === step.id ? void 0 : Date.now();
375
- const resumeTime = resume?.steps[0] === step.id ? Date.now() : void 0;
376
- const stepInfo = {
377
- ...stepResults[step.id],
378
- ...resume?.steps[0] === step.id ? { resumePayload: resume?.resumePayload } : { payload: prevOutput },
379
- ...startTime ? { startedAt: startTime } : {},
380
- ...resumeTime ? { resumedAt: resumeTime } : {}
381
- };
382
- await emitter.emit("watch", {
383
- type: "watch",
384
- payload: {
385
- currentStep: {
386
- id: step.id,
387
- status: "running",
388
- ...stepInfo
389
- },
390
- workflowState: {
391
- status: "running",
392
- steps: {
393
- ...stepResults,
394
- [step.id]: {
395
- status: "running",
396
- ...stepInfo
397
- }
398
- },
399
- result: null,
400
- error: null
401
- }
402
- },
403
- eventTimestamp: Date.now()
404
- });
405
- await emitter.emit("watch-v2", {
406
- type: "step-start",
407
- payload: {
408
- id: step.id,
409
- ...stepInfo,
410
- status: "running"
411
- }
412
- });
413
- const _runStep = (step2, spanName, attributes) => {
414
- return async (data) => {
415
- const telemetry = this.mastra?.getTelemetry();
416
- const span = executionContext.executionSpan;
417
- if (!telemetry || !span) {
418
- return step2.execute(data);
419
- }
420
- return context.with(trace.setSpan(context.active(), span), async () => {
421
- return telemetry.traceMethod(step2.execute.bind(step2), {
422
- spanName,
423
- attributes
424
- })(data);
425
- });
426
- };
427
- };
428
- const runStep = _runStep(step, `workflow.${workflowId}.step.${step.id}`, {
429
- componentName: workflowId,
430
- runId
431
- });
432
- let execResults;
433
- const retries = step.retries ?? executionContext.retryConfig.attempts ?? 0;
434
- const delay = executionContext.retryConfig.delay ?? 0;
435
- for (let i = 0; i < retries + 1; i++) {
436
- if (i > 0 && delay) {
437
- await new Promise((resolve) => setTimeout(resolve, delay));
438
- }
439
- try {
440
- let suspended;
441
- let bailed;
442
- const result = await runStep({
443
- runId,
444
- mastra: this.mastra,
445
- runtimeContext,
446
- inputData: prevOutput,
447
- runCount: this.getOrGenerateRunCount(step.id),
448
- resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
449
- getInitData: () => stepResults?.input,
450
- getStepResult: (step2) => {
451
- if (!step2?.id) {
452
- return null;
453
- }
454
- const result2 = stepResults[step2.id];
455
- if (result2?.status === "success") {
456
- return result2.output;
457
- }
458
- return null;
459
- },
460
- suspend: async (suspendPayload) => {
461
- executionContext.suspendedPaths[step.id] = executionContext.executionPath;
462
- suspended = { payload: suspendPayload };
463
- },
464
- bail: (result2) => {
465
- bailed = { payload: result2 };
466
- },
467
- abort: () => {
468
- abortController?.abort();
469
- },
470
- resume: {
471
- steps: resume?.steps?.slice(1) || [],
472
- resumePayload: resume?.resumePayload,
473
- // @ts-ignore
474
- runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
475
- },
476
- [EMITTER_SYMBOL]: emitter,
477
- engine: {},
478
- abortSignal: abortController?.signal
479
- });
480
- if (suspended) {
481
- execResults = { status: "suspended", suspendPayload: suspended.payload, suspendedAt: Date.now() };
482
- } else if (bailed) {
483
- execResults = { status: "bailed", output: bailed.payload, endedAt: Date.now() };
484
- } else {
485
- execResults = { status: "success", output: result, endedAt: Date.now() };
486
- }
487
- break;
488
- } catch (e) {
489
- const error = e instanceof MastraError ? e : new MastraError(
490
- {
491
- id: "WORKFLOW_STEP_INVOKE_FAILED",
492
- domain: "MASTRA_WORKFLOW" /* MASTRA_WORKFLOW */,
493
- category: "USER" /* USER */,
494
- details: { workflowId, runId, stepId: step.id }
495
- },
496
- e
497
- );
498
- this.logger.trackException(error);
499
- this.logger.error(`Error executing step ${step.id}: ` + error?.stack);
500
- execResults = {
501
- status: "failed",
502
- error: error?.stack,
503
- endedAt: Date.now()
504
- };
505
- }
506
- }
507
- await emitter.emit("watch", {
508
- type: "watch",
509
- payload: {
510
- currentStep: {
511
- id: step.id,
512
- ...stepInfo,
513
- ...execResults
514
- },
515
- workflowState: {
516
- status: "running",
517
- steps: {
518
- ...stepResults,
519
- [step.id]: {
520
- ...stepInfo,
521
- ...execResults
522
- }
523
- },
524
- result: null,
525
- error: null
526
- }
527
- },
528
- eventTimestamp: Date.now()
529
- });
530
- if (execResults.status === "suspended") {
531
- await emitter.emit("watch-v2", {
532
- type: "step-suspended",
533
- payload: {
534
- id: step.id,
535
- ...execResults
536
- }
537
- });
538
- } else {
539
- await emitter.emit("watch-v2", {
540
- type: "step-result",
541
- payload: {
542
- id: step.id,
543
- ...execResults
544
- }
545
- });
546
- await emitter.emit("watch-v2", {
547
- type: "step-finish",
548
- payload: {
549
- id: step.id,
550
- metadata: {}
551
- }
552
- });
553
- }
554
- return { ...stepInfo, ...execResults };
555
- }
556
- async executeParallel({
557
- workflowId,
558
- runId,
559
- entry,
560
- prevStep,
561
- serializedStepGraph,
562
- stepResults,
563
- resume,
564
- executionContext,
565
- emitter,
566
- abortController,
567
- runtimeContext
568
- }) {
569
- let execResults;
570
- const results = await Promise.all(
571
- entry.steps.map(
572
- (step, i) => this.executeEntry({
573
- workflowId,
574
- runId,
575
- entry: step,
576
- prevStep,
577
- stepResults,
578
- serializedStepGraph,
579
- resume,
580
- executionContext: {
581
- workflowId,
582
- runId,
583
- executionPath: [...executionContext.executionPath, i],
584
- suspendedPaths: executionContext.suspendedPaths,
585
- retryConfig: executionContext.retryConfig,
586
- executionSpan: executionContext.executionSpan
587
- },
588
- emitter,
589
- abortController,
590
- runtimeContext
591
- })
592
- )
593
- );
594
- const hasFailed = results.find((result) => result.result.status === "failed");
595
- const hasSuspended = results.find((result) => result.result.status === "suspended");
596
- if (hasFailed) {
597
- execResults = { status: "failed", error: hasFailed.result.error };
598
- } else if (hasSuspended) {
599
- execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
600
- } else if (abortController?.signal?.aborted) {
601
- execResults = { status: "canceled" };
602
- } else {
603
- execResults = {
604
- status: "success",
605
- output: results.reduce((acc, result, index) => {
606
- if (result.result.status === "success") {
607
- acc[entry.steps[index].step.id] = result.result.output;
608
- }
609
- return acc;
610
- }, {})
611
- };
612
- }
613
- return execResults;
614
- }
615
- async executeConditional({
616
- workflowId,
617
- runId,
618
- entry,
619
- prevOutput,
620
- prevStep,
621
- serializedStepGraph,
622
- stepResults,
623
- resume,
624
- executionContext,
625
- emitter,
626
- abortController,
627
- runtimeContext
628
- }) {
629
- let execResults;
630
- const truthyIndexes = (await Promise.all(
631
- entry.conditions.map(async (cond, index) => {
632
- try {
633
- const result = await cond({
634
- runId,
635
- mastra: this.mastra,
636
- runtimeContext,
637
- inputData: prevOutput,
638
- runCount: -1,
639
- getInitData: () => stepResults?.input,
640
- getStepResult: (step) => {
641
- if (!step?.id) {
642
- return null;
643
- }
644
- const result2 = stepResults[step.id];
645
- if (result2?.status === "success") {
646
- return result2.output;
647
- }
648
- return null;
649
- },
650
- // TODO: this function shouldn't have suspend probably?
651
- suspend: async (_suspendPayload) => {
652
- },
653
- bail: () => {
654
- },
655
- abort: () => {
656
- abortController?.abort();
657
- },
658
- [EMITTER_SYMBOL]: emitter,
659
- engine: {},
660
- abortSignal: abortController?.signal
661
- });
662
- return result ? index : null;
663
- } catch (e) {
664
- const error = e instanceof MastraError ? e : new MastraError(
665
- {
666
- id: "WORKFLOW_CONDITION_EVALUATION_FAILED",
667
- domain: "MASTRA_WORKFLOW" /* MASTRA_WORKFLOW */,
668
- category: "USER" /* USER */,
669
- details: { workflowId, runId }
670
- },
671
- e
672
- );
673
- this.logger.trackException(error);
674
- this.logger.error("Error evaluating condition: " + error?.stack);
675
- return null;
676
- }
677
- })
678
- )).filter((index) => index !== null);
679
- const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
680
- const results = await Promise.all(
681
- stepsToRun.map(
682
- (step, index) => this.executeEntry({
683
- workflowId,
684
- runId,
685
- entry: step,
686
- prevStep,
687
- stepResults,
688
- serializedStepGraph,
689
- resume,
690
- executionContext: {
691
- workflowId,
692
- runId,
693
- executionPath: [...executionContext.executionPath, index],
694
- suspendedPaths: executionContext.suspendedPaths,
695
- retryConfig: executionContext.retryConfig,
696
- executionSpan: executionContext.executionSpan
697
- },
698
- emitter,
699
- abortController,
700
- runtimeContext
701
- })
702
- )
703
- );
704
- const hasFailed = results.find((result) => result.result.status === "failed");
705
- const hasSuspended = results.find((result) => result.result.status === "suspended");
706
- if (hasFailed) {
707
- execResults = { status: "failed", error: hasFailed.result.error };
708
- } else if (hasSuspended) {
709
- execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
710
- } else if (abortController?.signal?.aborted) {
711
- execResults = { status: "canceled" };
712
- } else {
713
- execResults = {
714
- status: "success",
715
- output: results.reduce((acc, result, index) => {
716
- if (result.result.status === "success") {
717
- acc[stepsToRun[index].step.id] = result.result.output;
718
- }
719
- return acc;
720
- }, {})
721
- };
722
- }
723
- return execResults;
724
- }
725
- async executeLoop({
726
- workflowId,
727
- runId,
728
- entry,
729
- prevOutput,
730
- stepResults,
731
- resume,
732
- executionContext,
733
- emitter,
734
- abortController,
735
- runtimeContext
736
- }) {
737
- const { step, condition } = entry;
738
- let isTrue = true;
739
- let result = { status: "success", output: prevOutput };
740
- do {
741
- result = await this.executeStep({
742
- workflowId,
743
- runId,
744
- step,
745
- stepResults,
746
- executionContext,
747
- resume,
748
- prevOutput: result.output,
749
- emitter,
750
- abortController,
751
- runtimeContext
752
- });
753
- if (result.status !== "success") {
754
- return result;
755
- }
756
- isTrue = await condition({
757
- runId,
758
- mastra: this.mastra,
759
- runtimeContext,
760
- inputData: result.output,
761
- runCount: -1,
762
- getInitData: () => stepResults?.input,
763
- getStepResult: (step2) => {
764
- if (!step2?.id) {
765
- return null;
766
- }
767
- const result2 = stepResults[step2.id];
768
- return result2?.status === "success" ? result2.output : null;
769
- },
770
- suspend: async (_suspendPayload) => {
771
- },
772
- bail: () => {
773
- },
774
- abort: () => {
775
- abortController?.abort();
776
- },
777
- [EMITTER_SYMBOL]: emitter,
778
- engine: {},
779
- abortSignal: abortController?.signal
780
- });
781
- } while (entry.loopType === "dowhile" ? isTrue : !isTrue);
782
- return result;
783
- }
784
- async executeForeach({
785
- workflowId,
786
- runId,
787
- entry,
788
- prevOutput,
789
- stepResults,
790
- resume,
791
- executionContext,
792
- emitter,
793
- abortController,
794
- runtimeContext
795
- }) {
796
- const { step, opts } = entry;
797
- const results = [];
798
- const concurrency = opts.concurrency;
799
- const startTime = resume?.steps[0] === step.id ? void 0 : Date.now();
800
- const resumeTime = resume?.steps[0] === step.id ? Date.now() : void 0;
801
- for (let i = 0; i < prevOutput.length; i += concurrency) {
802
- const items = prevOutput.slice(i, i + concurrency);
803
- const itemsResults = await Promise.all(
804
- items.map((item) => {
805
- return this.executeStep({
806
- workflowId,
807
- runId,
808
- step,
809
- stepResults,
810
- executionContext,
811
- resume,
812
- prevOutput: item,
813
- emitter,
814
- abortController,
815
- runtimeContext
816
- });
817
- })
818
- );
819
- for (const result of itemsResults) {
820
- if (result.status !== "success") {
821
- return result;
822
- }
823
- results.push(result?.output);
824
- }
825
- }
826
- return {
827
- ...stepResults[step.id],
828
- status: "success",
829
- payload: prevOutput,
830
- ...resume?.steps[0] === step.id ? { resumePayload: resume?.resumePayload } : {},
831
- output: results,
832
- //@ts-ignore
833
- endedAt: Date.now(),
834
- ...startTime ? { startedAt: startTime } : {},
835
- ...resumeTime ? { resumedAt: resumeTime } : {}
836
- };
837
- }
838
- async persistStepUpdate({
839
- workflowId,
840
- runId,
841
- stepResults,
842
- serializedStepGraph,
843
- executionContext,
844
- workflowStatus,
845
- result,
846
- error
847
- }) {
848
- await this.mastra?.getStorage()?.persistWorkflowSnapshot({
849
- workflowName: workflowId,
850
- runId,
851
- snapshot: {
852
- runId,
853
- status: workflowStatus,
854
- value: {},
855
- context: stepResults,
856
- activePaths: [],
857
- serializedStepGraph,
858
- suspendedPaths: executionContext.suspendedPaths,
859
- result,
860
- error,
861
- // @ts-ignore
862
- timestamp: Date.now()
863
- }
864
- });
865
- }
866
- async executeEntry({
867
- workflowId,
868
- runId,
869
- entry,
870
- prevStep,
871
- serializedStepGraph,
872
- stepResults,
873
- resume,
874
- executionContext,
875
- emitter,
876
- abortController,
877
- runtimeContext
878
- }) {
879
- const prevOutput = this.getStepOutput(stepResults, prevStep);
880
- let execResults;
881
- if (entry.type === "step") {
882
- const { step } = entry;
883
- execResults = await this.executeStep({
884
- workflowId,
885
- runId,
886
- step,
887
- stepResults,
888
- executionContext,
889
- resume,
890
- prevOutput,
891
- emitter,
892
- abortController,
893
- runtimeContext
894
- });
895
- } else if (resume?.resumePath?.length && (entry.type === "parallel" || entry.type === "conditional")) {
896
- const idx = resume.resumePath.shift();
897
- return this.executeEntry({
898
- workflowId,
899
- runId,
900
- entry: entry.steps[idx],
901
- prevStep,
902
- serializedStepGraph,
903
- stepResults,
904
- resume,
905
- executionContext: {
906
- workflowId,
907
- runId,
908
- executionPath: [...executionContext.executionPath, idx],
909
- suspendedPaths: executionContext.suspendedPaths,
910
- retryConfig: executionContext.retryConfig,
911
- executionSpan: executionContext.executionSpan
912
- },
913
- emitter,
914
- abortController,
915
- runtimeContext
916
- });
917
- } else if (entry.type === "parallel") {
918
- execResults = await this.executeParallel({
919
- workflowId,
920
- runId,
921
- entry,
922
- prevStep,
923
- stepResults,
924
- serializedStepGraph,
925
- resume,
926
- executionContext,
927
- emitter,
928
- abortController,
929
- runtimeContext
930
- });
931
- } else if (entry.type === "conditional") {
932
- execResults = await this.executeConditional({
933
- workflowId,
934
- runId,
935
- entry,
936
- prevStep,
937
- prevOutput,
938
- stepResults,
939
- serializedStepGraph,
940
- resume,
941
- executionContext,
942
- emitter,
943
- abortController,
944
- runtimeContext
945
- });
946
- } else if (entry.type === "loop") {
947
- execResults = await this.executeLoop({
948
- workflowId,
949
- runId,
950
- entry,
951
- prevStep,
952
- prevOutput,
953
- stepResults,
954
- resume,
955
- executionContext,
956
- emitter,
957
- abortController,
958
- runtimeContext
959
- });
960
- } else if (entry.type === "foreach") {
961
- execResults = await this.executeForeach({
962
- workflowId,
963
- runId,
964
- entry,
965
- prevStep,
966
- prevOutput,
967
- stepResults,
968
- resume,
969
- executionContext,
970
- emitter,
971
- abortController,
972
- runtimeContext
973
- });
974
- } else if (entry.type === "sleep") {
975
- const startedAt = Date.now();
976
- await emitter.emit("watch", {
977
- type: "watch",
978
- payload: {
979
- currentStep: {
980
- id: entry.id,
981
- status: "waiting",
982
- payload: prevOutput,
983
- startedAt
984
- },
985
- workflowState: {
986
- status: "waiting",
987
- steps: {
988
- ...stepResults,
989
- [entry.id]: {
990
- status: "waiting",
991
- payload: prevOutput,
992
- startedAt
993
- }
994
- },
995
- result: null,
996
- error: null
997
- }
998
- },
999
- eventTimestamp: Date.now()
1000
- });
1001
- await emitter.emit("watch-v2", {
1002
- type: "step-waiting",
1003
- payload: {
1004
- id: entry.id,
1005
- payload: prevOutput,
1006
- startedAt,
1007
- status: "waiting"
1008
- }
1009
- });
1010
- await this.persistStepUpdate({
1011
- workflowId,
1012
- runId,
1013
- serializedStepGraph,
1014
- stepResults,
1015
- executionContext,
1016
- workflowStatus: "waiting"
1017
- });
1018
- await this.executeSleep({
1019
- workflowId,
1020
- runId,
1021
- entry,
1022
- prevStep,
1023
- prevOutput,
1024
- stepResults,
1025
- serializedStepGraph,
1026
- resume,
1027
- executionContext,
1028
- emitter,
1029
- abortController,
1030
- runtimeContext
1031
- });
1032
- await this.persistStepUpdate({
1033
- workflowId,
1034
- runId,
1035
- serializedStepGraph,
1036
- stepResults,
1037
- executionContext,
1038
- workflowStatus: "running"
1039
- });
1040
- const endedAt = Date.now();
1041
- const stepInfo = {
1042
- payload: prevOutput,
1043
- startedAt,
1044
- endedAt
1045
- };
1046
- execResults = { ...stepInfo, status: "success", output: prevOutput };
1047
- stepResults[entry.id] = { ...stepInfo, status: "success", output: prevOutput };
1048
- await emitter.emit("watch", {
1049
- type: "watch",
1050
- payload: {
1051
- currentStep: {
1052
- id: entry.id,
1053
- ...execResults
1054
- },
1055
- workflowState: {
1056
- status: "running",
1057
- steps: {
1058
- ...stepResults,
1059
- [entry.id]: {
1060
- ...execResults
1061
- }
1062
- },
1063
- result: null,
1064
- error: null
1065
- }
1066
- },
1067
- eventTimestamp: Date.now()
1068
- });
1069
- await emitter.emit("watch-v2", {
1070
- type: "step-result",
1071
- payload: {
1072
- id: entry.id,
1073
- ...execResults
1074
- }
1075
- });
1076
- await emitter.emit("watch-v2", {
1077
- type: "step-finish",
1078
- payload: {
1079
- id: entry.id,
1080
- metadata: {}
1081
- }
1082
- });
1083
- } else if (entry.type === "sleepUntil") {
1084
- const startedAt = Date.now();
1085
- await emitter.emit("watch", {
1086
- type: "watch",
1087
- payload: {
1088
- currentStep: {
1089
- id: entry.id,
1090
- status: "waiting",
1091
- payload: prevOutput,
1092
- startedAt
1093
- },
1094
- workflowState: {
1095
- status: "waiting",
1096
- steps: {
1097
- ...stepResults,
1098
- [entry.id]: {
1099
- status: "waiting",
1100
- payload: prevOutput,
1101
- startedAt
1102
- }
1103
- },
1104
- result: null,
1105
- error: null
1106
- }
1107
- },
1108
- eventTimestamp: Date.now()
1109
- });
1110
- await emitter.emit("watch-v2", {
1111
- type: "step-waiting",
1112
- payload: {
1113
- id: entry.id,
1114
- payload: prevOutput,
1115
- startedAt,
1116
- status: "waiting"
1117
- }
1118
- });
1119
- await this.persistStepUpdate({
1120
- workflowId,
1121
- runId,
1122
- serializedStepGraph,
1123
- stepResults,
1124
- executionContext,
1125
- workflowStatus: "waiting"
1126
- });
1127
- await this.executeSleepUntil({
1128
- workflowId,
1129
- runId,
1130
- entry,
1131
- prevStep,
1132
- prevOutput,
1133
- stepResults,
1134
- serializedStepGraph,
1135
- resume,
1136
- executionContext,
1137
- emitter,
1138
- abortController,
1139
- runtimeContext
1140
- });
1141
- await this.persistStepUpdate({
1142
- workflowId,
1143
- runId,
1144
- serializedStepGraph,
1145
- stepResults,
1146
- executionContext,
1147
- workflowStatus: "running"
1148
- });
1149
- const endedAt = Date.now();
1150
- const stepInfo = {
1151
- payload: prevOutput,
1152
- startedAt,
1153
- endedAt
1154
- };
1155
- execResults = { ...stepInfo, status: "success", output: prevOutput };
1156
- stepResults[entry.id] = { ...stepInfo, status: "success", output: prevOutput };
1157
- await emitter.emit("watch", {
1158
- type: "watch",
1159
- payload: {
1160
- currentStep: {
1161
- id: entry.id,
1162
- ...execResults
1163
- },
1164
- workflowState: {
1165
- status: "running",
1166
- steps: {
1167
- ...stepResults,
1168
- [entry.id]: {
1169
- ...execResults
1170
- }
1171
- },
1172
- result: null,
1173
- error: null
1174
- }
1175
- },
1176
- eventTimestamp: Date.now()
1177
- });
1178
- await emitter.emit("watch-v2", {
1179
- type: "step-result",
1180
- payload: {
1181
- id: entry.id,
1182
- ...execResults
1183
- }
1184
- });
1185
- await emitter.emit("watch-v2", {
1186
- type: "step-finish",
1187
- payload: {
1188
- id: entry.id,
1189
- metadata: {}
1190
- }
1191
- });
1192
- } else if (entry.type === "waitForEvent") {
1193
- const startedAt = Date.now();
1194
- let eventData;
1195
- await emitter.emit("watch", {
1196
- type: "watch",
1197
- payload: {
1198
- currentStep: {
1199
- id: entry.step.id,
1200
- status: "waiting",
1201
- payload: prevOutput,
1202
- startedAt
1203
- },
1204
- workflowState: {
1205
- status: "waiting",
1206
- steps: {
1207
- ...stepResults,
1208
- [entry.step.id]: {
1209
- status: "waiting",
1210
- payload: prevOutput,
1211
- startedAt
1212
- }
1213
- },
1214
- result: null,
1215
- error: null
1216
- }
1217
- },
1218
- eventTimestamp: Date.now()
1219
- });
1220
- await emitter.emit("watch-v2", {
1221
- type: "step-waiting",
1222
- payload: {
1223
- id: entry.step.id,
1224
- payload: prevOutput,
1225
- startedAt,
1226
- status: "waiting"
1227
- }
1228
- });
1229
- await this.persistStepUpdate({
1230
- workflowId,
1231
- runId,
1232
- serializedStepGraph,
1233
- stepResults,
1234
- executionContext,
1235
- workflowStatus: "waiting"
1236
- });
1237
- try {
1238
- eventData = await this.executeWaitForEvent({ event: entry.event, emitter, timeout: entry.timeout });
1239
- await this.persistStepUpdate({
1240
- workflowId,
1241
- runId,
1242
- serializedStepGraph,
1243
- stepResults,
1244
- executionContext,
1245
- workflowStatus: "running"
1246
- });
1247
- const { step } = entry;
1248
- execResults = await this.executeStep({
1249
- workflowId,
1250
- runId,
1251
- step,
1252
- stepResults,
1253
- executionContext,
1254
- resume: {
1255
- resumePayload: eventData,
1256
- steps: [entry.step.id]
1257
- },
1258
- prevOutput,
1259
- emitter,
1260
- abortController,
1261
- runtimeContext
1262
- });
1263
- } catch (error) {
1264
- execResults = {
1265
- status: "failed",
1266
- error
1267
- };
1268
- }
1269
- const endedAt = Date.now();
1270
- const stepInfo = {
1271
- payload: prevOutput,
1272
- startedAt,
1273
- endedAt
1274
- };
1275
- execResults = { ...execResults, ...stepInfo };
1276
- }
1277
- if (entry.type === "step" || entry.type === "waitForEvent" || entry.type === "loop" || entry.type === "foreach") {
1278
- stepResults[entry.step.id] = execResults;
1279
- }
1280
- if (abortController?.signal?.aborted) {
1281
- execResults = { ...execResults, status: "canceled" };
1282
- }
1283
- await this.persistStepUpdate({
1284
- workflowId,
1285
- runId,
1286
- serializedStepGraph,
1287
- stepResults,
1288
- executionContext,
1289
- workflowStatus: execResults.status
1290
- });
1291
- return { result: execResults, stepResults, executionContext };
1292
- }
1293
- };
1294
- function mapVariable(config) {
1295
- return config;
1296
- }
1297
- function createStep(params) {
1298
- if (params instanceof Agent) {
1299
- return {
1300
- id: params.name,
1301
- // @ts-ignore
1302
- inputSchema: z.object({
1303
- prompt: z.string()
1304
- // resourceId: z.string().optional(),
1305
- // threadId: z.string().optional(),
1306
- }),
1307
- // @ts-ignore
1308
- outputSchema: z.object({
1309
- text: z.string()
1310
- }),
1311
- execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort }) => {
1312
- let streamPromise = {};
1313
- streamPromise.promise = new Promise((resolve, reject) => {
1314
- streamPromise.resolve = resolve;
1315
- streamPromise.reject = reject;
1316
- });
1317
- const toolData = {
1318
- name: params.name,
1319
- args: inputData
1320
- };
1321
- await emitter.emit("watch-v2", {
1322
- type: "tool-call-streaming-start",
1323
- ...toolData
1324
- });
1325
- const { fullStream } = await params.stream(inputData.prompt, {
1326
- // resourceId: inputData.resourceId,
1327
- // threadId: inputData.threadId,
1328
- runtimeContext,
1329
- onFinish: (result) => {
1330
- streamPromise.resolve(result.text);
1331
- },
1332
- abortSignal
1333
- });
1334
- if (abortSignal.aborted) {
1335
- return abort();
1336
- }
1337
- for await (const chunk of fullStream) {
1338
- switch (chunk.type) {
1339
- case "text-delta":
1340
- await emitter.emit("watch-v2", {
1341
- type: "tool-call-delta",
1342
- ...toolData,
1343
- argsTextDelta: chunk.textDelta
1344
- });
1345
- break;
1346
- case "step-start":
1347
- case "step-finish":
1348
- case "finish":
1349
- break;
1350
- case "tool-call":
1351
- case "tool-result":
1352
- case "tool-call-streaming-start":
1353
- case "tool-call-delta":
1354
- case "source":
1355
- case "file":
1356
- default:
1357
- await emitter.emit("watch-v2", chunk);
1358
- break;
1359
- }
1360
- }
1361
- return {
1362
- text: await streamPromise.promise
1363
- };
1364
- }
1365
- };
1366
- }
1367
- if (params instanceof Tool) {
1368
- if (!params.inputSchema || !params.outputSchema) {
1369
- throw new Error("Tool must have input and output schemas defined");
1370
- }
1371
- return {
1372
- // TODO: tool probably should have strong id type
1373
- // @ts-ignore
1374
- id: params.id,
1375
- inputSchema: params.inputSchema,
1376
- outputSchema: params.outputSchema,
1377
- execute: async ({ inputData, mastra, runtimeContext }) => {
1378
- return params.execute({
1379
- context: inputData,
1380
- mastra,
1381
- runtimeContext
1382
- });
1383
- }
1384
- };
1385
- }
1386
- return {
1387
- id: params.id,
1388
- description: params.description,
1389
- inputSchema: params.inputSchema,
1390
- outputSchema: params.outputSchema,
1391
- resumeSchema: params.resumeSchema,
1392
- suspendSchema: params.suspendSchema,
1393
- retries: params.retries,
1394
- execute: params.execute
1395
- };
1396
- }
1397
- function cloneStep(step, opts) {
1398
- return {
1399
- id: opts.id,
1400
- description: step.description,
1401
- inputSchema: step.inputSchema,
1402
- outputSchema: step.outputSchema,
1403
- execute: step.execute,
1404
- retries: step.retries
1405
- };
1406
- }
1407
- function createWorkflow(params) {
1408
- return new Workflow(params);
1409
- }
1410
- function cloneWorkflow(workflow, opts) {
1411
- const wf = new Workflow({
1412
- id: opts.id,
1413
- inputSchema: workflow.inputSchema,
1414
- outputSchema: workflow.outputSchema,
1415
- steps: workflow.stepDefs,
1416
- mastra: workflow.mastra
1417
- });
1418
- wf.setStepFlow(workflow.stepGraph);
1419
- wf.commit();
1420
- return wf;
1421
- }
1422
- var Workflow = class extends MastraBase {
1423
- id;
1424
- description;
1425
- inputSchema;
1426
- outputSchema;
1427
- steps;
1428
- stepDefs;
1429
- stepFlow;
1430
- serializedStepFlow;
1431
- executionEngine;
1432
- executionGraph;
1433
- retryConfig;
1434
- #mastra;
1435
- #runs = /* @__PURE__ */ new Map();
1436
- constructor({
1437
- mastra,
1438
- id,
1439
- inputSchema,
1440
- outputSchema,
1441
- description,
1442
- executionEngine,
1443
- retryConfig,
1444
- steps
1445
- }) {
1446
- super({ name: id, component: RegisteredLogger.WORKFLOW });
1447
- this.id = id;
1448
- this.description = description;
1449
- this.inputSchema = inputSchema;
1450
- this.outputSchema = outputSchema;
1451
- this.retryConfig = retryConfig ?? { attempts: 0, delay: 0 };
1452
- this.executionGraph = this.buildExecutionGraph();
1453
- this.stepFlow = [];
1454
- this.serializedStepFlow = [];
1455
- this.#mastra = mastra;
1456
- this.steps = {};
1457
- this.stepDefs = steps;
1458
- if (!executionEngine) {
1459
- this.executionEngine = new DefaultExecutionEngine({ mastra: this.#mastra });
1460
- } else {
1461
- this.executionEngine = executionEngine;
1462
- }
1463
- this.#runs = /* @__PURE__ */ new Map();
1464
- }
1465
- get runs() {
1466
- return this.#runs;
1467
- }
1468
- get mastra() {
1469
- return this.#mastra;
1470
- }
1471
- __registerMastra(mastra) {
1472
- this.#mastra = mastra;
1473
- this.executionEngine.__registerMastra(mastra);
1474
- }
1475
- __registerPrimitives(p) {
1476
- if (p.telemetry) {
1477
- this.__setTelemetry(p.telemetry);
1478
- }
1479
- if (p.logger) {
1480
- this.__setLogger(p.logger);
1481
- }
1482
- }
1483
- setStepFlow(stepFlow) {
1484
- this.stepFlow = stepFlow;
1485
- }
1486
- /**
1487
- * Adds a step to the workflow
1488
- * @param step The step to add to the workflow
1489
- * @returns The workflow instance for chaining
1490
- */
1491
- then(step) {
1492
- this.stepFlow.push({ type: "step", step });
1493
- this.serializedStepFlow.push({
1494
- type: "step",
1495
- step: {
1496
- id: step.id,
1497
- description: step.description,
1498
- component: step.component,
1499
- serializedStepFlow: step.serializedStepFlow
1500
- }
1501
- });
1502
- this.steps[step.id] = step;
1503
- return this;
1504
- }
1505
- /**
1506
- * Adds a sleep step to the workflow
1507
- * @param duration The duration to sleep for
1508
- * @returns The workflow instance for chaining
1509
- */
1510
- sleep(duration) {
1511
- const id = `sleep_${randomUUID()}`;
1512
- const opts = typeof duration === "function" ? { type: "sleep", id, fn: duration } : { type: "sleep", id, duration };
1513
- const serializedOpts = typeof duration === "function" ? { type: "sleep", id, fn: duration.toString() } : { type: "sleep", id, duration };
1514
- this.stepFlow.push(opts);
1515
- this.serializedStepFlow.push(serializedOpts);
1516
- this.steps[id] = createStep({
1517
- id,
1518
- inputSchema: z.object({}),
1519
- outputSchema: z.object({}),
1520
- execute: async () => {
1521
- return {};
1522
- }
1523
- });
1524
- return this;
1525
- }
1526
- /**
1527
- * Adds a sleep until step to the workflow
1528
- * @param date The date to sleep until
1529
- * @returns The workflow instance for chaining
1530
- */
1531
- sleepUntil(date) {
1532
- const id = `sleep_${randomUUID()}`;
1533
- const opts = typeof date === "function" ? { type: "sleepUntil", id, fn: date } : { type: "sleepUntil", id, date };
1534
- const serializedOpts = typeof date === "function" ? { type: "sleepUntil", id, fn: date.toString() } : { type: "sleepUntil", id, date };
1535
- this.stepFlow.push(opts);
1536
- this.serializedStepFlow.push(serializedOpts);
1537
- this.steps[id] = createStep({
1538
- id,
1539
- inputSchema: z.object({}),
1540
- outputSchema: z.object({}),
1541
- execute: async () => {
1542
- return {};
1543
- }
1544
- });
1545
- return this;
1546
- }
1547
- waitForEvent(event, step, opts) {
1548
- this.stepFlow.push({ type: "waitForEvent", event, step, timeout: opts?.timeout });
1549
- this.serializedStepFlow.push({
1550
- type: "waitForEvent",
1551
- event,
1552
- step: {
1553
- id: step.id,
1554
- description: step.description,
1555
- component: step.component,
1556
- serializedStepFlow: step.serializedStepFlow
1557
- },
1558
- timeout: opts?.timeout
1559
- });
1560
- this.steps[step.id] = step;
1561
- return this;
1562
- }
1563
- map(mappingConfig) {
1564
- if (typeof mappingConfig === "function") {
1565
- const mappingStep2 = createStep({
1566
- id: `mapping_${randomUUID()}`,
1567
- inputSchema: z.object({}),
1568
- outputSchema: z.object({}),
1569
- execute: mappingConfig
1570
- });
1571
- this.stepFlow.push({ type: "step", step: mappingStep2 });
1572
- this.serializedStepFlow.push({
1573
- type: "step",
1574
- step: {
1575
- id: mappingStep2.id,
1576
- mapConfig: mappingConfig.toString()
1577
- }
1578
- });
1579
- return this;
1580
- }
1581
- const newMappingConfig = Object.entries(mappingConfig).reduce(
1582
- (a, [key, mapping]) => {
1583
- const m = mapping;
1584
- if (m.value !== void 0) {
1585
- a[key] = m;
1586
- } else if (m.fn !== void 0) {
1587
- a[key] = {
1588
- fn: m.fn.toString(),
1589
- schema: m.schema
1590
- };
1591
- } else if (m.runtimeContextPath) {
1592
- a[key] = {
1593
- runtimeContextPath: m.runtimeContextPath,
1594
- schema: m.schema
1595
- };
1596
- } else {
1597
- a[key] = m;
1598
- }
1599
- return a;
1600
- },
1601
- {}
1602
- );
1603
- const mappingStep = createStep({
1604
- id: `mapping_${randomUUID()}`,
1605
- inputSchema: z.object({}),
1606
- outputSchema: z.object({}),
1607
- execute: async (ctx) => {
1608
- const { getStepResult, getInitData, runtimeContext } = ctx;
1609
- const result = {};
1610
- for (const [key, mapping] of Object.entries(mappingConfig)) {
1611
- const m = mapping;
1612
- if (m.value !== void 0) {
1613
- result[key] = m.value;
1614
- continue;
1615
- }
1616
- if (m.fn !== void 0) {
1617
- result[key] = await m.fn(ctx);
1618
- continue;
1619
- }
1620
- if (m.runtimeContextPath) {
1621
- result[key] = runtimeContext.get(m.runtimeContextPath);
1622
- continue;
1623
- }
1624
- const stepResult = m.initData ? getInitData() : getStepResult(Array.isArray(m.step) ? m.step.find((s) => getStepResult(s)) : m.step);
1625
- if (m.path === ".") {
1626
- result[key] = stepResult;
1627
- continue;
1628
- }
1629
- const pathParts = m.path.split(".");
1630
- let value = stepResult;
1631
- for (const part of pathParts) {
1632
- if (typeof value === "object" && value !== null) {
1633
- value = value[part];
1634
- } else {
1635
- throw new Error(`Invalid path ${m.path} in step ${m.step.id}`);
1636
- }
1637
- }
1638
- result[key] = value;
1639
- }
1640
- return result;
1641
- }
1642
- });
1643
- this.stepFlow.push({ type: "step", step: mappingStep });
1644
- this.serializedStepFlow.push({
1645
- type: "step",
1646
- step: {
1647
- id: mappingStep.id,
1648
- mapConfig: JSON.stringify(newMappingConfig, null, 2)
1649
- }
1650
- });
1651
- return this;
1652
- }
1653
- // TODO: make typing better here
1654
- parallel(steps) {
1655
- this.stepFlow.push({ type: "parallel", steps: steps.map((step) => ({ type: "step", step })) });
1656
- this.serializedStepFlow.push({
1657
- type: "parallel",
1658
- steps: steps.map((step) => ({
1659
- type: "step",
1660
- step: {
1661
- id: step.id,
1662
- description: step.description,
1663
- component: step.component,
1664
- serializedStepFlow: step.serializedStepFlow
1665
- }
1666
- }))
1667
- });
1668
- steps.forEach((step) => {
1669
- this.steps[step.id] = step;
1670
- });
1671
- return this;
1672
- }
1673
- // TODO: make typing better here
1674
- branch(steps) {
1675
- this.stepFlow.push({
1676
- type: "conditional",
1677
- steps: steps.map(([_cond, step]) => ({ type: "step", step })),
1678
- // @ts-ignore
1679
- conditions: steps.map(([cond]) => cond),
1680
- serializedConditions: steps.map(([cond, _step]) => ({ id: `${_step.id}-condition`, fn: cond.toString() }))
1681
- });
1682
- this.serializedStepFlow.push({
1683
- type: "conditional",
1684
- steps: steps.map(([_cond, step]) => ({
1685
- type: "step",
1686
- step: {
1687
- id: step.id,
1688
- description: step.description,
1689
- component: step.component,
1690
- serializedStepFlow: step.serializedStepFlow
1691
- }
1692
- })),
1693
- serializedConditions: steps.map(([cond, _step]) => ({ id: `${_step.id}-condition`, fn: cond.toString() }))
1694
- });
1695
- steps.forEach(([_, step]) => {
1696
- this.steps[step.id] = step;
1697
- });
1698
- return this;
1699
- }
1700
- dowhile(step, condition) {
1701
- this.stepFlow.push({
1702
- type: "loop",
1703
- step,
1704
- // @ts-ignore
1705
- condition,
1706
- loopType: "dowhile",
1707
- serializedCondition: { id: `${step.id}-condition`, fn: condition.toString() }
1708
- });
1709
- this.serializedStepFlow.push({
1710
- type: "loop",
1711
- step: {
1712
- id: step.id,
1713
- description: step.description,
1714
- component: step.component,
1715
- serializedStepFlow: step.serializedStepFlow
1716
- },
1717
- serializedCondition: { id: `${step.id}-condition`, fn: condition.toString() },
1718
- loopType: "dowhile"
1719
- });
1720
- this.steps[step.id] = step;
1721
- return this;
1722
- }
1723
- dountil(step, condition) {
1724
- this.stepFlow.push({
1725
- type: "loop",
1726
- step,
1727
- // @ts-ignore
1728
- condition,
1729
- loopType: "dountil",
1730
- serializedCondition: { id: `${step.id}-condition`, fn: condition.toString() }
1731
- });
1732
- this.serializedStepFlow.push({
1733
- type: "loop",
1734
- step: {
1735
- id: step.id,
1736
- description: step.description,
1737
- component: step.component,
1738
- serializedStepFlow: step.serializedStepFlow
1739
- },
1740
- serializedCondition: { id: `${step.id}-condition`, fn: condition.toString() },
1741
- loopType: "dountil"
1742
- });
1743
- this.steps[step.id] = step;
1744
- return this;
1745
- }
1746
- foreach(step, opts) {
1747
- this.stepFlow.push({ type: "foreach", step, opts: opts ?? { concurrency: 1 } });
1748
- this.serializedStepFlow.push({
1749
- type: "foreach",
1750
- step: {
1751
- id: step.id,
1752
- description: step.description,
1753
- component: step.component,
1754
- serializedStepFlow: step.serializedStepFlow
1755
- },
1756
- opts: opts ?? { concurrency: 1 }
1757
- });
1758
- this.steps[step.id] = step;
1759
- return this;
1760
- }
1761
- /**
1762
- * Builds the execution graph for this workflow
1763
- * @returns The execution graph that can be used to execute the workflow
1764
- */
1765
- buildExecutionGraph() {
1766
- return {
1767
- id: this.id,
1768
- steps: this.stepFlow
1769
- };
1770
- }
1771
- /**
1772
- * Finalizes the workflow definition and prepares it for execution
1773
- * This method should be called after all steps have been added to the workflow
1774
- * @returns A built workflow instance ready for execution
1775
- */
1776
- commit() {
1777
- this.executionGraph = this.buildExecutionGraph();
1778
- return this;
1779
- }
1780
- get stepGraph() {
1781
- return this.stepFlow;
1782
- }
1783
- get serializedStepGraph() {
1784
- return this.serializedStepFlow;
1785
- }
1786
- /**
1787
- * Creates a new workflow run instance
1788
- * @param options Optional configuration for the run
1789
- * @returns A Run instance that can be used to execute the workflow
1790
- */
1791
- createRun(options) {
1792
- if (this.stepFlow.length === 0) {
1793
- throw new Error(
1794
- "Execution flow of workflow is not defined. Add steps to the workflow via .then(), .branch(), etc."
1795
- );
1796
- }
1797
- if (!this.executionGraph.steps) {
1798
- throw new Error("Uncommitted step flow changes detected. Call .commit() to register the steps.");
1799
- }
1800
- const runIdToUse = options?.runId || randomUUID();
1801
- const run = this.#runs.get(runIdToUse) ?? new Run({
1802
- workflowId: this.id,
1803
- runId: runIdToUse,
1804
- executionEngine: this.executionEngine,
1805
- executionGraph: this.executionGraph,
1806
- mastra: this.#mastra,
1807
- retryConfig: this.retryConfig,
1808
- serializedStepGraph: this.serializedStepGraph,
1809
- cleanup: () => this.#runs.delete(runIdToUse)
1810
- });
1811
- this.#runs.set(runIdToUse, run);
1812
- this.mastra?.getLogger().warn("createRun() is deprecated. Use createRunAsync() instead.");
1813
- return run;
1814
- }
1815
- /**
1816
- * Creates a new workflow run instance and stores a snapshot of the workflow in the storage
1817
- * @param options Optional configuration for the run
1818
- * @returns A Run instance that can be used to execute the workflow
1819
- */
1820
- async createRunAsync(options) {
1821
- if (this.stepFlow.length === 0) {
1822
- throw new Error(
1823
- "Execution flow of workflow is not defined. Add steps to the workflow via .then(), .branch(), etc."
1824
- );
1825
- }
1826
- if (!this.executionGraph.steps) {
1827
- throw new Error("Uncommitted step flow changes detected. Call .commit() to register the steps.");
1828
- }
1829
- const runIdToUse = options?.runId || randomUUID();
1830
- const run = this.#runs.get(runIdToUse) ?? new Run({
1831
- workflowId: this.id,
1832
- runId: runIdToUse,
1833
- executionEngine: this.executionEngine,
1834
- executionGraph: this.executionGraph,
1835
- mastra: this.#mastra,
1836
- retryConfig: this.retryConfig,
1837
- serializedStepGraph: this.serializedStepGraph,
1838
- cleanup: () => this.#runs.delete(runIdToUse)
1839
- });
1840
- this.#runs.set(runIdToUse, run);
1841
- const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse);
1842
- if (!workflowSnapshotInStorage) {
1843
- await this.mastra?.getStorage()?.persistWorkflowSnapshot({
1844
- workflowName: this.id,
1845
- runId: runIdToUse,
1846
- snapshot: {
1847
- runId: runIdToUse,
1848
- status: "pending",
1849
- value: {},
1850
- context: {},
1851
- activePaths: [],
1852
- serializedStepGraph: this.serializedStepGraph,
1853
- suspendedPaths: {},
1854
- result: void 0,
1855
- error: void 0,
1856
- // @ts-ignore
1857
- timestamp: Date.now()
1858
- }
1859
- });
1860
- }
1861
- return run;
1862
- }
1863
- async execute({
1864
- inputData,
1865
- resumeData,
1866
- suspend,
1867
- resume,
1868
- [EMITTER_SYMBOL]: emitter,
1869
- mastra,
1870
- runtimeContext,
1871
- abort,
1872
- abortSignal
1873
- }) {
1874
- this.__registerMastra(mastra);
1875
- const run = resume?.steps?.length ? await this.createRunAsync({ runId: resume.runId }) : await this.createRunAsync();
1876
- const nestedAbortCb = () => {
1877
- abort();
1878
- };
1879
- run.abortController?.signal.addEventListener("abort", nestedAbortCb);
1880
- abortSignal.addEventListener("abort", async () => {
1881
- run.abortController.signal.removeEventListener("abort", nestedAbortCb);
1882
- await run.cancel();
1883
- });
1884
- const unwatchV2 = run.watch((event) => {
1885
- emitter.emit("nested-watch-v2", { event, workflowId: this.id });
1886
- }, "watch-v2");
1887
- const unwatch = run.watch((event) => {
1888
- emitter.emit("nested-watch", { event, workflowId: this.id, runId: run.runId, isResume: !!resume?.steps?.length });
1889
- }, "watch");
1890
- const res = resume?.steps?.length ? await run.resume({ resumeData, step: resume.steps, runtimeContext }) : await run.start({ inputData, runtimeContext });
1891
- unwatch();
1892
- unwatchV2();
1893
- const suspendedSteps = Object.entries(res.steps).filter(([_stepName, stepResult]) => {
1894
- const stepRes = stepResult;
1895
- return stepRes?.status === "suspended";
1896
- });
1897
- if (suspendedSteps?.length) {
1898
- for (const [stepName, stepResult] of suspendedSteps) {
1899
- const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
1900
- await suspend({
1901
- ...stepResult?.suspendPayload,
1902
- __workflow_meta: { runId: run.runId, path: suspendPath }
1903
- });
1904
- }
1905
- }
1906
- if (res.status === "failed") {
1907
- throw res.error;
1908
- }
1909
- return res.status === "success" ? res.result : void 0;
1910
- }
1911
- async getWorkflowRuns(args) {
1912
- const storage = this.#mastra?.getStorage();
1913
- if (!storage) {
1914
- this.logger.debug("Cannot get workflow runs. Mastra storage is not initialized");
1915
- return { runs: [], total: 0 };
1916
- }
1917
- return storage.getWorkflowRuns({ workflowName: this.id, ...args ?? {} });
1918
- }
1919
- async getWorkflowRunById(runId) {
1920
- const storage = this.#mastra?.getStorage();
1921
- if (!storage) {
1922
- this.logger.debug("Cannot get workflow runs from storage. Mastra storage is not initialized");
1923
- return this.#runs.get(runId) ? { ...this.#runs.get(runId), workflowName: this.id } : null;
1924
- }
1925
- const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
1926
- return run ?? (this.#runs.get(runId) ? { ...this.#runs.get(runId), workflowName: this.id } : null);
1927
- }
1928
- async getWorkflowRunExecutionResult(runId) {
1929
- const storage = this.#mastra?.getStorage();
1930
- if (!storage) {
1931
- this.logger.debug("Cannot get workflow run execution result. Mastra storage is not initialized");
1932
- return null;
1933
- }
1934
- const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
1935
- let snapshot = run?.snapshot;
1936
- if (!snapshot) {
1937
- return null;
1938
- }
1939
- if (typeof snapshot === "string") {
1940
- try {
1941
- snapshot = JSON.parse(snapshot);
1942
- } catch (e) {
1943
- this.logger.debug("Cannot get workflow run execution result. Snapshot is not a valid JSON string", e);
1944
- return null;
1945
- }
1946
- }
1947
- return {
1948
- status: snapshot.status,
1949
- result: snapshot.result,
1950
- error: snapshot.error,
1951
- payload: snapshot.context?.input,
1952
- steps: snapshot.context
1953
- };
1954
- }
1955
- };
1956
- var Run = class {
1957
- abortController;
1958
- emitter;
1959
- /**
1960
- * Unique identifier for this workflow
1961
- */
1962
- workflowId;
1963
- /**
1964
- * Unique identifier for this run
1965
- */
1966
- runId;
1967
- /**
1968
- * Internal state of the workflow run
1969
- */
1970
- state = {};
1971
- /**
1972
- * The execution engine for this run
1973
- */
1974
- executionEngine;
1975
- /**
1976
- * The execution graph for this run
1977
- */
1978
- executionGraph;
1979
- /**
1980
- * The serialized step graph for this run
1981
- */
1982
- serializedStepGraph;
1983
- /**
1984
- * The storage for this run
1985
- */
1986
- #mastra;
1987
- closeStreamAction;
1988
- executionResults;
1989
- cleanup;
1990
- retryConfig;
1991
- constructor(params) {
1992
- this.workflowId = params.workflowId;
1993
- this.runId = params.runId;
1994
- this.serializedStepGraph = params.serializedStepGraph;
1995
- this.executionEngine = params.executionEngine;
1996
- this.executionGraph = params.executionGraph;
1997
- this.#mastra = params.mastra;
1998
- this.emitter = new EventEmitter();
1999
- this.retryConfig = params.retryConfig;
2000
- this.cleanup = params.cleanup;
2001
- this.abortController = new AbortController();
2002
- }
2003
- /**
2004
- * Cancels the workflow execution
2005
- */
2006
- async cancel() {
2007
- this.abortController?.abort();
2008
- }
2009
- async sendEvent(event, data) {
2010
- this.emitter.emit(`user-event-${event}`, data);
2011
- }
2012
- /**
2013
- * Starts the workflow execution with the provided input
2014
- * @param input The input data for the workflow
2015
- * @returns A promise that resolves to the workflow output
2016
- */
2017
- async start({
2018
- inputData,
2019
- runtimeContext
2020
- }) {
2021
- const result = await this.executionEngine.execute({
2022
- workflowId: this.workflowId,
2023
- runId: this.runId,
2024
- graph: this.executionGraph,
2025
- serializedStepGraph: this.serializedStepGraph,
2026
- input: inputData,
2027
- emitter: {
2028
- emit: async (event, data) => {
2029
- this.emitter.emit(event, data);
2030
- },
2031
- on: (event, callback) => {
2032
- this.emitter.on(event, callback);
2033
- },
2034
- off: (event, callback) => {
2035
- this.emitter.off(event, callback);
2036
- },
2037
- once: (event, callback) => {
2038
- this.emitter.once(event, callback);
2039
- }
2040
- },
2041
- retryConfig: this.retryConfig,
2042
- runtimeContext: runtimeContext ?? new RuntimeContext(),
2043
- abortController: this.abortController
2044
- });
2045
- if (result.status !== "suspended") {
2046
- this.cleanup?.();
2047
- }
2048
- return result;
2049
- }
2050
- /**
2051
- * Starts the workflow execution with the provided input as a stream
2052
- * @param input The input data for the workflow
2053
- * @returns A promise that resolves to the workflow output
2054
- */
2055
- stream({ inputData, runtimeContext } = {}) {
2056
- const { readable, writable } = new TransformStream();
2057
- const writer = writable.getWriter();
2058
- const unwatch = this.watch(async (event) => {
2059
- try {
2060
- await writer.write(event);
2061
- } catch {
2062
- }
2063
- }, "watch-v2");
2064
- this.closeStreamAction = async () => {
2065
- this.emitter.emit("watch-v2", {
2066
- type: "finish",
2067
- payload: { runId: this.runId }
2068
- });
2069
- unwatch();
2070
- try {
2071
- await writer.close();
2072
- } catch (err) {
2073
- console.error("Error closing stream:", err);
2074
- } finally {
2075
- writer.releaseLock();
2076
- }
2077
- };
2078
- this.emitter.emit("watch-v2", {
2079
- type: "start",
2080
- payload: { runId: this.runId }
2081
- });
2082
- this.executionResults = this.start({ inputData, runtimeContext }).then((result) => {
2083
- if (result.status !== "suspended") {
2084
- this.closeStreamAction?.().catch(() => {
2085
- });
2086
- }
2087
- return result;
2088
- });
2089
- return {
2090
- stream: readable,
2091
- getWorkflowState: () => this.executionResults
2092
- };
2093
- }
2094
- watch(cb, type = "watch") {
2095
- const watchCb = (event) => {
2096
- this.updateState(event.payload);
2097
- cb({ type: event.type, payload: this.getState(), eventTimestamp: event.eventTimestamp });
2098
- };
2099
- const nestedWatchCb = ({ event, workflowId }) => {
2100
- try {
2101
- const { type: type2, payload, eventTimestamp } = event;
2102
- const prefixedSteps = Object.fromEntries(
2103
- Object.entries(payload?.workflowState?.steps ?? {}).map(([stepId, step]) => [
2104
- `${workflowId}.${stepId}`,
2105
- step
2106
- ])
2107
- );
2108
- const newPayload = {
2109
- currentStep: {
2110
- ...payload?.currentStep,
2111
- id: `${workflowId}.${payload?.currentStep?.id}`
2112
- },
2113
- workflowState: {
2114
- steps: prefixedSteps
2115
- }
2116
- };
2117
- this.updateState(newPayload);
2118
- cb({ type: type2, payload: this.getState(), eventTimestamp });
2119
- } catch (e) {
2120
- console.error(e);
2121
- }
2122
- };
2123
- const nestedWatchV2Cb = ({
2124
- event,
2125
- workflowId
2126
- }) => {
2127
- this.emitter.emit("watch-v2", {
2128
- ...event,
2129
- ...event.payload?.id ? { payload: { ...event.payload, id: `${workflowId}.${event.payload.id}` } } : {}
2130
- });
2131
- };
2132
- if (type === "watch") {
2133
- this.emitter.on("watch", watchCb);
2134
- this.emitter.on("nested-watch", nestedWatchCb);
2135
- } else if (type === "watch-v2") {
2136
- this.emitter.on("watch-v2", cb);
2137
- this.emitter.on("nested-watch-v2", nestedWatchV2Cb);
2138
- }
2139
- return () => {
2140
- if (type === "watch-v2") {
2141
- this.emitter.off("watch-v2", cb);
2142
- this.emitter.off("nested-watch-v2", nestedWatchV2Cb);
2143
- } else {
2144
- this.emitter.off("watch", watchCb);
2145
- this.emitter.off("nested-watch", nestedWatchCb);
2146
- }
2147
- };
2148
- }
2149
- async resume(params) {
2150
- const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
2151
- (step) => typeof step === "string" ? step : step?.id
2152
- );
2153
- const snapshot = await this.#mastra?.getStorage()?.loadWorkflowSnapshot({
2154
- workflowName: this.workflowId,
2155
- runId: this.runId
2156
- });
2157
- if (!snapshot) {
2158
- throw new Error("No snapshot found for this workflow run");
2159
- }
2160
- if (snapshot.status !== "suspended") {
2161
- throw new Error("This workflow run was not suspended");
2162
- }
2163
- const suspendedStepIds = Object.keys(snapshot?.suspendedPaths ?? {});
2164
- const isStepSuspended = suspendedStepIds.includes(steps?.[0] ?? "");
2165
- if (!isStepSuspended) {
2166
- throw new Error("This workflow step was not suspended");
2167
- }
2168
- const executionResultPromise = this.executionEngine.execute({
2169
- workflowId: this.workflowId,
2170
- runId: this.runId,
2171
- graph: this.executionGraph,
2172
- serializedStepGraph: this.serializedStepGraph,
2173
- input: params.resumeData,
2174
- resume: {
2175
- steps,
2176
- stepResults: snapshot?.context,
2177
- resumePayload: params.resumeData,
2178
- // @ts-ignore
2179
- resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
2180
- },
2181
- emitter: {
2182
- emit: (event, data) => {
2183
- this.emitter.emit(event, data);
2184
- return Promise.resolve();
2185
- },
2186
- on: (event, callback) => {
2187
- this.emitter.on(event, callback);
2188
- },
2189
- off: (event, callback) => {
2190
- this.emitter.off(event, callback);
2191
- },
2192
- once: (event, callback) => {
2193
- this.emitter.once(event, callback);
2194
- }
2195
- },
2196
- runtimeContext: params.runtimeContext ?? new RuntimeContext(),
2197
- abortController: this.abortController
2198
- }).then((result) => {
2199
- if (result.status !== "suspended") {
2200
- this.closeStreamAction?.().catch(() => {
2201
- });
2202
- }
2203
- return result;
2204
- });
2205
- this.executionResults = executionResultPromise;
2206
- return executionResultPromise;
2207
- }
2208
- /**
2209
- * Returns the current state of the workflow run
2210
- * @returns The current state of the workflow run
2211
- */
2212
- getState() {
2213
- return this.state;
2214
- }
2215
- updateState(state) {
2216
- if (state.currentStep) {
2217
- this.state.currentStep = state.currentStep;
2218
- } else if (state.workflowState?.status !== "running") {
2219
- delete this.state.currentStep;
2220
- }
2221
- if (state.workflowState) {
2222
- this.state.workflowState = deepMergeWorkflowState(this.state.workflowState ?? {}, state.workflowState ?? {});
2223
- }
2224
- }
2225
- };
2226
- function deepMergeWorkflowState(a, b) {
2227
- if (!a || typeof a !== "object") return b;
2228
- if (!b || typeof b !== "object") return a;
2229
- const result = { ...a };
2230
- for (const key in b) {
2231
- if (b[key] === void 0) continue;
2232
- if (b[key] !== null && typeof b[key] === "object") {
2233
- const aVal = result[key];
2234
- const bVal = b[key];
2235
- if (Array.isArray(bVal)) {
2236
- result[key] = bVal.filter((item) => item !== void 0);
2237
- } else if (typeof aVal === "object" && aVal !== null) {
2238
- result[key] = deepMergeWorkflowState(aVal, bVal);
2239
- } else {
2240
- result[key] = bVal;
2241
- }
2242
- } else {
2243
- result[key] = b[key];
2244
- }
2245
- }
2246
- return result;
2247
- }
2248
-
2249
- export { DefaultExecutionEngine, ExecutionEngine, Run, Workflow, cloneStep, cloneWorkflow, createStep, createWorkflow, mapVariable };