@mastra/core 0.7.0 → 0.8.0-alpha.2

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 (149) hide show
  1. package/README.md +76 -74
  2. package/dist/agent/index.cjs +2 -2
  3. package/dist/agent/index.d.cts +5 -3
  4. package/dist/agent/index.d.ts +5 -3
  5. package/dist/agent/index.js +1 -1
  6. package/dist/{base-Cmunaaxb.d.ts → base-BA_in99t.d.ts} +4 -1
  7. package/dist/{base-Cyl73WbV.d.ts → base-CQuRWXAH.d.ts} +985 -913
  8. package/dist/{base-ObPJ-w8K.d.cts → base-CvQbEqGB.d.cts} +4 -1
  9. package/dist/{base-C0wILuA9.d.cts → base-Dpt4tO56.d.cts} +985 -913
  10. package/dist/base.cjs +2 -2
  11. package/dist/base.d.cts +1 -1
  12. package/dist/base.d.ts +1 -1
  13. package/dist/base.js +1 -1
  14. package/dist/bundler/index.cjs +2 -2
  15. package/dist/bundler/index.d.cts +1 -1
  16. package/dist/bundler/index.d.ts +1 -1
  17. package/dist/bundler/index.js +1 -1
  18. package/dist/{chunk-L7CR75HA.js → chunk-2BVZNKLX.js} +1 -1
  19. package/dist/{chunk-V5ORZPFW.cjs → chunk-3C6V2FEP.cjs} +1 -1
  20. package/dist/chunk-3HE5CJBG.cjs +4604 -0
  21. package/dist/{chunk-PNZK456O.js → chunk-4RMSGSQN.js} +4 -4
  22. package/dist/{chunk-WESJ2ZY7.cjs → chunk-57LXIDIK.cjs} +2 -2
  23. package/dist/chunk-5RRJEWMA.cjs +107 -0
  24. package/dist/{chunk-3CNO7YB5.js → chunk-5TFGORLG.js} +1 -1
  25. package/dist/{chunk-5FAJ6HUC.cjs → chunk-64VPB7ZD.cjs} +23 -2
  26. package/dist/chunk-6XLV4KSD.js +100 -0
  27. package/dist/{chunk-XLSROQ26.cjs → chunk-7I7AKQH3.cjs} +5 -5
  28. package/dist/{chunk-RUA6BSB6.cjs → chunk-7JBINHJX.cjs} +2 -2
  29. package/dist/chunk-A6MBM56X.js +268 -0
  30. package/dist/{chunk-2YF5JYTJ.js → chunk-BC5B4EGI.js} +21 -2
  31. package/dist/chunk-BF7ZLRGO.cjs +271 -0
  32. package/dist/{chunk-SMBKF6K5.js → chunk-BRBHQ6KS.js} +10 -1
  33. package/dist/{chunk-VN4M67DA.js → chunk-CLJQYXNM.js} +1 -1
  34. package/dist/{chunk-PL7PVTGF.cjs → chunk-D63P5O4Q.cjs} +4 -4
  35. package/dist/chunk-DCGLGWHI.cjs +141 -0
  36. package/dist/{chunk-YXJQFZOW.cjs → chunk-DL4QPJKI.cjs} +24 -10
  37. package/dist/{chunk-ZABXT2MN.js → chunk-FY57LEMC.js} +1 -1
  38. package/dist/{chunk-XLXJUYKH.js → chunk-GHK3HBWN.js} +1 -1
  39. package/dist/{chunk-ONDCHP6G.cjs → chunk-GO2D7FEK.cjs} +2 -2
  40. package/dist/{chunk-7VTZI3YN.js → chunk-H6ZU5N2C.js} +1 -1
  41. package/dist/{chunk-WBE5RTFI.js → chunk-HAWAUEWK.js} +2 -2
  42. package/dist/chunk-HCDXBSMK.js +4577 -0
  43. package/dist/{chunk-RU7CSPAV.js → chunk-JGJMVCJ4.js} +7 -84
  44. package/dist/{chunk-W5HVJX45.js → chunk-N5ZYOQBL.js} +46 -5
  45. package/dist/{chunk-NPOKIPWC.cjs → chunk-O7IW545H.cjs} +1 -1
  46. package/dist/{chunk-XB2TJ7LX.cjs → chunk-PHWEC4VD.cjs} +47 -6
  47. package/dist/{chunk-NUDAZEOG.js → chunk-PK5QRKSG.js} +1 -1
  48. package/dist/{chunk-43SD5CUE.js → chunk-QDHRRKQ5.js} +63 -9
  49. package/dist/{chunk-ZBKJDQPM.js → chunk-RBWBJC6D.js} +17 -3
  50. package/dist/{chunk-4PYORXWM.cjs → chunk-RXDLSCBA.cjs} +4 -4
  51. package/dist/{chunk-IQLRSKED.cjs → chunk-RZCYBC7D.cjs} +2 -2
  52. package/dist/{chunk-ASFUEC75.cjs → chunk-TNNHN4ZY.cjs} +67 -12
  53. package/dist/{chunk-QM6WIIPM.js → chunk-UF4LZV3D.js} +1 -1
  54. package/dist/{chunk-JJ4YQTFT.cjs → chunk-WAW7QBY4.cjs} +2 -2
  55. package/dist/{chunk-U7ONOIBO.cjs → chunk-YZDUZFVZ.cjs} +11 -2
  56. package/dist/deployer/index.cjs +2 -2
  57. package/dist/deployer/index.d.cts +1 -1
  58. package/dist/deployer/index.d.ts +1 -1
  59. package/dist/deployer/index.js +1 -1
  60. package/dist/eval/index.cjs +3 -3
  61. package/dist/eval/index.d.cts +8 -5
  62. package/dist/eval/index.d.ts +8 -5
  63. package/dist/eval/index.js +1 -1
  64. package/dist/hooks/index.d.cts +1 -1
  65. package/dist/hooks/index.d.ts +1 -1
  66. package/dist/index.cjs +102 -92
  67. package/dist/index.d.cts +11 -9
  68. package/dist/index.d.ts +11 -9
  69. package/dist/index.js +18 -19
  70. package/dist/integration/index.cjs +3 -3
  71. package/dist/integration/index.d.cts +5 -3
  72. package/dist/integration/index.d.ts +5 -3
  73. package/dist/integration/index.js +1 -1
  74. package/dist/llm/index.d.cts +5 -3
  75. package/dist/llm/index.d.ts +5 -3
  76. package/dist/logger/index.cjs +9 -9
  77. package/dist/logger/index.js +1 -1
  78. package/dist/mastra/index.cjs +2 -2
  79. package/dist/mastra/index.d.cts +5 -3
  80. package/dist/mastra/index.d.ts +5 -3
  81. package/dist/mastra/index.js +1 -1
  82. package/dist/memory/index.cjs +6 -2
  83. package/dist/memory/index.d.cts +5 -3
  84. package/dist/memory/index.d.ts +5 -3
  85. package/dist/memory/index.js +1 -1
  86. package/dist/network/index.cjs +8 -8
  87. package/dist/network/index.d.cts +5 -3
  88. package/dist/network/index.d.ts +5 -3
  89. package/dist/network/index.js +4 -4
  90. package/dist/relevance/index.cjs +4 -4
  91. package/dist/relevance/index.d.cts +10 -8
  92. package/dist/relevance/index.d.ts +10 -8
  93. package/dist/relevance/index.js +1 -1
  94. package/dist/server/index.cjs +17 -0
  95. package/dist/server/index.d.cts +37 -0
  96. package/dist/server/index.d.ts +37 -0
  97. package/dist/server/index.js +15 -0
  98. package/dist/storage/index.cjs +12 -8
  99. package/dist/storage/index.d.cts +5 -3
  100. package/dist/storage/index.d.ts +5 -3
  101. package/dist/storage/index.js +2 -2
  102. package/dist/storage/libsql/index.cjs +24 -24
  103. package/dist/storage/libsql/index.d.cts +5 -3
  104. package/dist/storage/libsql/index.d.ts +5 -3
  105. package/dist/storage/libsql/index.js +12 -12
  106. package/dist/telemetry/index.cjs +6 -6
  107. package/dist/telemetry/index.d.cts +5 -3
  108. package/dist/telemetry/index.d.ts +5 -3
  109. package/dist/telemetry/index.js +1 -1
  110. package/dist/tools/index.cjs +7 -3
  111. package/dist/tools/index.d.cts +6 -3
  112. package/dist/tools/index.d.ts +6 -3
  113. package/dist/tools/index.js +1 -1
  114. package/dist/tts/index.cjs +2 -2
  115. package/dist/tts/index.d.cts +1 -1
  116. package/dist/tts/index.d.ts +1 -1
  117. package/dist/tts/index.js +1 -1
  118. package/dist/{types-CwTG2XyQ.d.cts → types-BtMyV38I.d.cts} +4 -1
  119. package/dist/{types-CwTG2XyQ.d.ts → types-BtMyV38I.d.ts} +4 -1
  120. package/dist/utils.cjs +13 -13
  121. package/dist/utils.d.cts +7 -5
  122. package/dist/utils.d.ts +7 -5
  123. package/dist/utils.js +1 -1
  124. package/dist/vector/index.cjs +2 -2
  125. package/dist/vector/index.d.cts +1 -1
  126. package/dist/vector/index.d.ts +1 -1
  127. package/dist/vector/index.js +1 -1
  128. package/dist/vector/libsql/index.cjs +3 -3
  129. package/dist/vector/libsql/index.d.cts +1 -1
  130. package/dist/vector/libsql/index.d.ts +1 -1
  131. package/dist/vector/libsql/index.js +1 -1
  132. package/dist/voice/index.cjs +13 -249
  133. package/dist/voice/index.d.cts +22 -8
  134. package/dist/voice/index.d.ts +22 -8
  135. package/dist/voice/index.js +1 -252
  136. package/dist/workflows/index.cjs +28 -20
  137. package/dist/workflows/index.d.cts +18 -7
  138. package/dist/workflows/index.d.ts +18 -7
  139. package/dist/workflows/index.js +1 -1
  140. package/package.json +5 -3
  141. package/dist/chunk-2W2GYEYQ.cjs +0 -25
  142. package/dist/chunk-C6BBAS4I.cjs +0 -1715
  143. package/dist/chunk-F5UYWPV4.cjs +0 -14
  144. package/dist/chunk-GG6TEAMJ.cjs +0 -2289
  145. package/dist/chunk-R2M5CZ5U.js +0 -2264
  146. package/dist/chunk-RG66XEJT.js +0 -8
  147. package/dist/chunk-VNQRLYIA.js +0 -1715
  148. package/dist/chunk-WVVKLIUW.cjs +0 -218
  149. package/dist/chunk-ZINPRHAN.js +0 -22
@@ -0,0 +1,4604 @@
1
+ 'use strict';
2
+
3
+ var chunkBF7ZLRGO_cjs = require('./chunk-BF7ZLRGO.cjs');
4
+ var chunkPHWEC4VD_cjs = require('./chunk-PHWEC4VD.cjs');
5
+ var chunk64VPB7ZD_cjs = require('./chunk-64VPB7ZD.cjs');
6
+ var chunkD63P5O4Q_cjs = require('./chunk-D63P5O4Q.cjs');
7
+ var chunkO7IW545H_cjs = require('./chunk-O7IW545H.cjs');
8
+ var chunkST5RMVLG_cjs = require('./chunk-ST5RMVLG.cjs');
9
+ var chunkRWTSGWWL_cjs = require('./chunk-RWTSGWWL.cjs');
10
+ var api = require('@opentelemetry/api');
11
+ var zod = require('zod');
12
+ var radash = require('radash');
13
+ var crypto$1 = require('crypto');
14
+ var ai = require('ai');
15
+ var EventEmitter = require('events');
16
+ var sift = require('sift');
17
+ var xstate = require('xstate');
18
+
19
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
20
+
21
+ var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter);
22
+ var sift__default = /*#__PURE__*/_interopDefault(sift);
23
+
24
+ // src/workflows/step.ts
25
+ var Step = class {
26
+ id;
27
+ description;
28
+ inputSchema;
29
+ outputSchema;
30
+ payload;
31
+ execute;
32
+ retryConfig;
33
+ mastra;
34
+ constructor({
35
+ id,
36
+ description,
37
+ execute,
38
+ payload,
39
+ outputSchema,
40
+ inputSchema,
41
+ retryConfig
42
+ }) {
43
+ this.id = id;
44
+ this.description = description ?? "";
45
+ this.inputSchema = inputSchema;
46
+ this.payload = payload;
47
+ this.outputSchema = outputSchema;
48
+ this.execute = execute;
49
+ this.retryConfig = retryConfig;
50
+ }
51
+ };
52
+ function createStep(opts) {
53
+ return new Step(opts);
54
+ }
55
+
56
+ // src/workflows/types.ts
57
+ var WhenConditionReturnValue = /* @__PURE__ */(WhenConditionReturnValue2 => {
58
+ WhenConditionReturnValue2["CONTINUE"] = "continue";
59
+ WhenConditionReturnValue2["CONTINUE_FAILED"] = "continue_failed";
60
+ WhenConditionReturnValue2["ABORT"] = "abort";
61
+ WhenConditionReturnValue2["LIMBO"] = "limbo";
62
+ return WhenConditionReturnValue2;
63
+ })(WhenConditionReturnValue || {});
64
+
65
+ // src/llm/model/base.ts
66
+ var MastraLLMBase = class extends chunkD63P5O4Q_cjs.MastraBase {
67
+ // @ts-ignore
68
+ #mastra;
69
+ #model;
70
+ constructor({
71
+ name,
72
+ model
73
+ }) {
74
+ super({
75
+ component: chunkO7IW545H_cjs.RegisteredLogger.LLM,
76
+ name
77
+ });
78
+ this.#model = model;
79
+ }
80
+ getProvider() {
81
+ return this.#model.provider;
82
+ }
83
+ getModelId() {
84
+ return this.#model.modelId;
85
+ }
86
+ getModel() {
87
+ return this.#model;
88
+ }
89
+ convertToMessages(messages) {
90
+ if (Array.isArray(messages)) {
91
+ return messages.map(m => {
92
+ if (typeof m === "string") {
93
+ return {
94
+ role: "user",
95
+ content: m
96
+ };
97
+ }
98
+ return m;
99
+ });
100
+ }
101
+ return [{
102
+ role: "user",
103
+ content: messages
104
+ }];
105
+ }
106
+ __registerPrimitives(p) {
107
+ if (p.telemetry) {
108
+ this.__setTelemetry(p.telemetry);
109
+ }
110
+ if (p.logger) {
111
+ this.__setLogger(p.logger);
112
+ }
113
+ }
114
+ __registerMastra(p) {
115
+ this.#mastra = p;
116
+ }
117
+ async __text(input) {
118
+ this.logger.debug(`[LLMs:${this.name}] Generating text.`, {
119
+ input
120
+ });
121
+ throw new Error("Method not implemented.");
122
+ }
123
+ async __textObject(input) {
124
+ this.logger.debug(`[LLMs:${this.name}] Generating object.`, {
125
+ input
126
+ });
127
+ throw new Error("Method not implemented.");
128
+ }
129
+ async generate(messages, options = {}) {
130
+ this.logger.debug(`[LLMs:${this.name}] Generating text.`, {
131
+ messages,
132
+ options
133
+ });
134
+ throw new Error("Method not implemented.");
135
+ }
136
+ async __stream(input) {
137
+ this.logger.debug(`[LLMs:${this.name}] Streaming text.`, {
138
+ input
139
+ });
140
+ throw new Error("Method not implemented.");
141
+ }
142
+ async __streamObject(input) {
143
+ this.logger.debug(`[LLMs:${this.name}] Streaming object.`, {
144
+ input
145
+ });
146
+ throw new Error("Method not implemented.");
147
+ }
148
+ async stream(messages, options = {}) {
149
+ this.logger.debug(`[LLMs:${this.name}] Streaming text.`, {
150
+ messages,
151
+ options
152
+ });
153
+ throw new Error("Method not implemented.");
154
+ }
155
+ };
156
+ var MastraLLM = class extends MastraLLMBase {
157
+ #model;
158
+ #mastra;
159
+ constructor({
160
+ model,
161
+ mastra
162
+ }) {
163
+ super({
164
+ name: "aisdk",
165
+ model
166
+ });
167
+ this.#model = model;
168
+ if (mastra) {
169
+ this.#mastra = mastra;
170
+ if (mastra.getLogger()) {
171
+ this.__setLogger(mastra.getLogger());
172
+ }
173
+ }
174
+ }
175
+ __registerPrimitives(p) {
176
+ if (p.telemetry) {
177
+ this.__setTelemetry(p.telemetry);
178
+ }
179
+ if (p.logger) {
180
+ this.__setLogger(p.logger);
181
+ }
182
+ }
183
+ __registerMastra(p) {
184
+ this.#mastra = p;
185
+ }
186
+ getProvider() {
187
+ return this.#model.provider;
188
+ }
189
+ getModelId() {
190
+ return this.#model.modelId;
191
+ }
192
+ getModel() {
193
+ return this.#model;
194
+ }
195
+ convertTools({
196
+ tools,
197
+ runId,
198
+ threadId,
199
+ resourceId,
200
+ memory
201
+ } = {}) {
202
+ this.logger.debug("Starting tool conversion for LLM");
203
+ let mastraProxy = void 0;
204
+ const logger = this.logger;
205
+ if (this.#mastra) {
206
+ mastraProxy = chunk64VPB7ZD_cjs.createMastraProxy({
207
+ mastra: this.#mastra,
208
+ logger
209
+ });
210
+ }
211
+ const converted = Object.entries(tools || {}).reduce((memo, value) => {
212
+ const k = value[0];
213
+ const tool = value[1];
214
+ if (tool) {
215
+ const options = {
216
+ name: k,
217
+ runId,
218
+ threadId,
219
+ resourceId,
220
+ logger: this.logger,
221
+ memory,
222
+ mastra: mastraProxy
223
+ };
224
+ memo[k] = chunk64VPB7ZD_cjs.makeCoreTool(tool, options);
225
+ }
226
+ return memo;
227
+ }, {});
228
+ this.logger.debug(`Converted tools for LLM`);
229
+ return converted;
230
+ }
231
+ async __text({
232
+ runId,
233
+ messages,
234
+ maxSteps,
235
+ tools,
236
+ convertedTools,
237
+ temperature,
238
+ toolChoice = "auto",
239
+ onStepFinish,
240
+ experimental_output,
241
+ telemetry,
242
+ threadId,
243
+ resourceId,
244
+ memory,
245
+ ...rest
246
+ }) {
247
+ const model = this.#model;
248
+ this.logger.debug(`[LLM] - Generating text`, {
249
+ runId,
250
+ messages,
251
+ maxSteps,
252
+ threadId,
253
+ resourceId,
254
+ tools: Object.keys(tools || convertedTools || {})
255
+ });
256
+ const finalTools = convertedTools || this.convertTools({
257
+ tools,
258
+ runId,
259
+ threadId,
260
+ resourceId,
261
+ memory
262
+ });
263
+ const argsForExecute = {
264
+ model,
265
+ temperature,
266
+ tools: {
267
+ ...finalTools
268
+ },
269
+ toolChoice,
270
+ maxSteps,
271
+ onStepFinish: async props => {
272
+ void onStepFinish?.(props);
273
+ this.logger.debug("[LLM] - Step Change:", {
274
+ text: props?.text,
275
+ toolCalls: props?.toolCalls,
276
+ toolResults: props?.toolResults,
277
+ finishReason: props?.finishReason,
278
+ usage: props?.usage,
279
+ runId
280
+ });
281
+ if (props?.response?.headers?.["x-ratelimit-remaining-tokens"] && parseInt(props?.response?.headers?.["x-ratelimit-remaining-tokens"], 10) < 2e3) {
282
+ this.logger.warn("Rate limit approaching, waiting 10 seconds", {
283
+ runId
284
+ });
285
+ await chunk64VPB7ZD_cjs.delay(10 * 1e3);
286
+ }
287
+ },
288
+ ...rest
289
+ };
290
+ let schema;
291
+ if (experimental_output) {
292
+ this.logger.debug("[LLM] - Using experimental output", {
293
+ runId
294
+ });
295
+ if (typeof experimental_output.parse === "function") {
296
+ schema = experimental_output;
297
+ if (schema instanceof zod.z.ZodArray) {
298
+ schema = schema._def.type;
299
+ }
300
+ } else {
301
+ schema = ai.jsonSchema(experimental_output);
302
+ }
303
+ }
304
+ return await ai.generateText({
305
+ messages,
306
+ ...argsForExecute,
307
+ experimental_telemetry: {
308
+ ...this.experimental_telemetry,
309
+ ...telemetry
310
+ },
311
+ experimental_output: schema ? ai.Output.object({
312
+ schema
313
+ }) : void 0
314
+ });
315
+ }
316
+ async __textObject({
317
+ messages,
318
+ onStepFinish,
319
+ maxSteps = 5,
320
+ tools,
321
+ convertedTools,
322
+ structuredOutput,
323
+ runId,
324
+ temperature,
325
+ toolChoice = "auto",
326
+ telemetry,
327
+ threadId,
328
+ resourceId,
329
+ memory,
330
+ ...rest
331
+ }) {
332
+ const model = this.#model;
333
+ this.logger.debug(`[LLM] - Generating a text object`, {
334
+ runId
335
+ });
336
+ const finalTools = convertedTools || this.convertTools({
337
+ tools,
338
+ runId,
339
+ threadId,
340
+ resourceId,
341
+ memory
342
+ });
343
+ const argsForExecute = {
344
+ model,
345
+ temperature,
346
+ tools: {
347
+ ...finalTools
348
+ },
349
+ maxSteps,
350
+ toolChoice,
351
+ onStepFinish: async props => {
352
+ void onStepFinish?.(props);
353
+ this.logger.debug("[LLM] - Step Change:", {
354
+ text: props?.text,
355
+ toolCalls: props?.toolCalls,
356
+ toolResults: props?.toolResults,
357
+ finishReason: props?.finishReason,
358
+ usage: props?.usage,
359
+ runId
360
+ });
361
+ if (props?.response?.headers?.["x-ratelimit-remaining-tokens"] && parseInt(props?.response?.headers?.["x-ratelimit-remaining-tokens"], 10) < 2e3) {
362
+ this.logger.warn("Rate limit approaching, waiting 10 seconds", {
363
+ runId
364
+ });
365
+ await chunk64VPB7ZD_cjs.delay(10 * 1e3);
366
+ }
367
+ },
368
+ ...rest
369
+ };
370
+ let schema;
371
+ let output = "object";
372
+ if (typeof structuredOutput.parse === "function") {
373
+ schema = structuredOutput;
374
+ if (schema instanceof zod.z.ZodArray) {
375
+ output = "array";
376
+ schema = schema._def.type;
377
+ }
378
+ } else {
379
+ schema = ai.jsonSchema(structuredOutput);
380
+ }
381
+ return await ai.generateObject({
382
+ messages,
383
+ ...argsForExecute,
384
+ output,
385
+ schema,
386
+ experimental_telemetry: {
387
+ ...this.experimental_telemetry,
388
+ ...telemetry
389
+ }
390
+ });
391
+ }
392
+ async __stream({
393
+ messages,
394
+ onStepFinish,
395
+ onFinish,
396
+ maxSteps = 5,
397
+ tools,
398
+ convertedTools,
399
+ runId,
400
+ temperature,
401
+ toolChoice = "auto",
402
+ experimental_output,
403
+ telemetry,
404
+ threadId,
405
+ resourceId,
406
+ memory,
407
+ ...rest
408
+ }) {
409
+ const model = this.#model;
410
+ this.logger.debug(`[LLM] - Streaming text`, {
411
+ runId,
412
+ threadId,
413
+ resourceId,
414
+ messages,
415
+ maxSteps,
416
+ tools: Object.keys(tools || convertedTools || {})
417
+ });
418
+ const finalTools = convertedTools || this.convertTools({
419
+ tools,
420
+ runId,
421
+ threadId,
422
+ resourceId,
423
+ memory
424
+ });
425
+ const argsForExecute = {
426
+ model,
427
+ temperature,
428
+ tools: {
429
+ ...finalTools
430
+ },
431
+ maxSteps,
432
+ toolChoice,
433
+ onStepFinish: async props => {
434
+ void onStepFinish?.(props);
435
+ this.logger.debug("[LLM] - Stream Step Change:", {
436
+ text: props?.text,
437
+ toolCalls: props?.toolCalls,
438
+ toolResults: props?.toolResults,
439
+ finishReason: props?.finishReason,
440
+ usage: props?.usage,
441
+ runId
442
+ });
443
+ if (props?.response?.headers?.["x-ratelimit-remaining-tokens"] && parseInt(props?.response?.headers?.["x-ratelimit-remaining-tokens"], 10) < 2e3) {
444
+ this.logger.warn("Rate limit approaching, waiting 10 seconds", {
445
+ runId
446
+ });
447
+ await chunk64VPB7ZD_cjs.delay(10 * 1e3);
448
+ }
449
+ },
450
+ onFinish: async props => {
451
+ void onFinish?.(props);
452
+ this.logger.debug("[LLM] - Stream Finished:", {
453
+ text: props?.text,
454
+ toolCalls: props?.toolCalls,
455
+ toolResults: props?.toolResults,
456
+ finishReason: props?.finishReason,
457
+ usage: props?.usage,
458
+ runId,
459
+ threadId,
460
+ resourceId
461
+ });
462
+ },
463
+ ...rest
464
+ };
465
+ let schema;
466
+ if (experimental_output) {
467
+ this.logger.debug("[LLM] - Using experimental output", {
468
+ runId
469
+ });
470
+ if (typeof experimental_output.parse === "function") {
471
+ schema = experimental_output;
472
+ if (schema instanceof zod.z.ZodArray) {
473
+ schema = schema._def.type;
474
+ }
475
+ } else {
476
+ schema = ai.jsonSchema(experimental_output);
477
+ }
478
+ }
479
+ return await ai.streamText({
480
+ messages,
481
+ ...argsForExecute,
482
+ experimental_telemetry: {
483
+ ...this.experimental_telemetry,
484
+ ...telemetry
485
+ },
486
+ experimental_output: schema ? ai.Output.object({
487
+ schema
488
+ }) : void 0
489
+ });
490
+ }
491
+ async __streamObject({
492
+ messages,
493
+ onStepFinish,
494
+ onFinish,
495
+ maxSteps = 5,
496
+ tools,
497
+ convertedTools,
498
+ structuredOutput,
499
+ runId,
500
+ temperature,
501
+ toolChoice = "auto",
502
+ telemetry,
503
+ threadId,
504
+ resourceId,
505
+ memory,
506
+ ...rest
507
+ }) {
508
+ const model = this.#model;
509
+ this.logger.debug(`[LLM] - Streaming structured output`, {
510
+ runId,
511
+ messages,
512
+ maxSteps,
513
+ tools: Object.keys(tools || convertedTools || {})
514
+ });
515
+ const finalTools = convertedTools || this.convertTools({
516
+ tools,
517
+ runId,
518
+ threadId,
519
+ resourceId,
520
+ memory
521
+ });
522
+ const argsForExecute = {
523
+ model,
524
+ temperature,
525
+ tools: {
526
+ ...finalTools
527
+ },
528
+ maxSteps,
529
+ toolChoice,
530
+ onStepFinish: async props => {
531
+ void onStepFinish?.(props);
532
+ this.logger.debug("[LLM] - Stream Step Change:", {
533
+ text: props?.text,
534
+ toolCalls: props?.toolCalls,
535
+ toolResults: props?.toolResults,
536
+ finishReason: props?.finishReason,
537
+ usage: props?.usage,
538
+ runId,
539
+ threadId,
540
+ resourceId
541
+ });
542
+ if (props?.response?.headers?.["x-ratelimit-remaining-tokens"] && parseInt(props?.response?.headers?.["x-ratelimit-remaining-tokens"], 10) < 2e3) {
543
+ this.logger.warn("Rate limit approaching, waiting 10 seconds", {
544
+ runId
545
+ });
546
+ await chunk64VPB7ZD_cjs.delay(10 * 1e3);
547
+ }
548
+ },
549
+ onFinish: async props => {
550
+ void onFinish?.(props);
551
+ this.logger.debug("[LLM] - Stream Finished:", {
552
+ text: props?.text,
553
+ toolCalls: props?.toolCalls,
554
+ toolResults: props?.toolResults,
555
+ finishReason: props?.finishReason,
556
+ usage: props?.usage,
557
+ runId,
558
+ threadId,
559
+ resourceId
560
+ });
561
+ },
562
+ ...rest
563
+ };
564
+ let schema;
565
+ let output = "object";
566
+ if (typeof structuredOutput.parse === "function") {
567
+ schema = structuredOutput;
568
+ if (schema instanceof zod.z.ZodArray) {
569
+ output = "array";
570
+ schema = schema._def.type;
571
+ }
572
+ } else {
573
+ schema = ai.jsonSchema(structuredOutput);
574
+ }
575
+ return ai.streamObject({
576
+ messages,
577
+ ...argsForExecute,
578
+ output,
579
+ schema,
580
+ experimental_telemetry: {
581
+ ...this.experimental_telemetry,
582
+ ...telemetry
583
+ }
584
+ });
585
+ }
586
+ async generate(messages, {
587
+ maxSteps = 5,
588
+ onStepFinish,
589
+ tools,
590
+ convertedTools,
591
+ runId,
592
+ output,
593
+ temperature,
594
+ telemetry,
595
+ memory,
596
+ ...rest
597
+ } = {}) {
598
+ const msgs = this.convertToMessages(messages);
599
+ if (!output) {
600
+ return await this.__text({
601
+ messages: msgs,
602
+ onStepFinish,
603
+ maxSteps,
604
+ tools,
605
+ convertedTools,
606
+ runId,
607
+ temperature,
608
+ memory,
609
+ ...rest
610
+ });
611
+ }
612
+ return await this.__textObject({
613
+ messages: msgs,
614
+ structuredOutput: output,
615
+ onStepFinish,
616
+ maxSteps,
617
+ tools,
618
+ convertedTools,
619
+ runId,
620
+ telemetry,
621
+ memory,
622
+ ...rest
623
+ });
624
+ }
625
+ async stream(messages, {
626
+ maxSteps = 5,
627
+ onFinish,
628
+ onStepFinish,
629
+ tools,
630
+ convertedTools,
631
+ runId,
632
+ output,
633
+ temperature,
634
+ telemetry,
635
+ ...rest
636
+ } = {}) {
637
+ const msgs = this.convertToMessages(messages);
638
+ if (!output) {
639
+ return await this.__stream({
640
+ messages: msgs,
641
+ onStepFinish,
642
+ onFinish,
643
+ maxSteps,
644
+ tools,
645
+ convertedTools,
646
+ runId,
647
+ temperature,
648
+ telemetry,
649
+ ...rest
650
+ });
651
+ }
652
+ return await this.__streamObject({
653
+ messages: msgs,
654
+ structuredOutput: output,
655
+ onStepFinish,
656
+ onFinish,
657
+ maxSteps,
658
+ tools,
659
+ convertedTools,
660
+ runId,
661
+ temperature,
662
+ telemetry,
663
+ ...rest
664
+ });
665
+ }
666
+ convertToUIMessages(messages) {
667
+ function addToolMessageToChat({
668
+ toolMessage,
669
+ messages: messages2,
670
+ toolResultContents
671
+ }) {
672
+ const chatMessages2 = messages2.map(message => {
673
+ if (message.toolInvocations) {
674
+ return {
675
+ ...message,
676
+ toolInvocations: message.toolInvocations.map(toolInvocation => {
677
+ const toolResult = toolMessage.content.find(tool => tool.toolCallId === toolInvocation.toolCallId);
678
+ if (toolResult) {
679
+ return {
680
+ ...toolInvocation,
681
+ state: "result",
682
+ result: toolResult.result
683
+ };
684
+ }
685
+ return toolInvocation;
686
+ })
687
+ };
688
+ }
689
+ return message;
690
+ });
691
+ const resultContents = [...toolResultContents, ...toolMessage.content];
692
+ return {
693
+ chatMessages: chatMessages2,
694
+ toolResultContents: resultContents
695
+ };
696
+ }
697
+ const {
698
+ chatMessages
699
+ } = messages.reduce((obj, message) => {
700
+ if (message.role === "tool") {
701
+ return addToolMessageToChat({
702
+ toolMessage: message,
703
+ messages: obj.chatMessages,
704
+ toolResultContents: obj.toolResultContents
705
+ });
706
+ }
707
+ let textContent = "";
708
+ let toolInvocations = [];
709
+ if (typeof message.content === "string") {
710
+ textContent = message.content;
711
+ } else if (typeof message.content === "number") {
712
+ textContent = String(message.content);
713
+ } else if (Array.isArray(message.content)) {
714
+ for (const content of message.content) {
715
+ if (content.type === "text") {
716
+ textContent += content.text;
717
+ } else if (content.type === "tool-call") {
718
+ const toolResult = obj.toolResultContents.find(tool => tool.toolCallId === content.toolCallId);
719
+ toolInvocations.push({
720
+ state: toolResult ? "result" : "call",
721
+ toolCallId: content.toolCallId,
722
+ toolName: content.toolName,
723
+ args: content.args,
724
+ result: toolResult?.result
725
+ });
726
+ }
727
+ }
728
+ }
729
+ obj.chatMessages.push({
730
+ id: message.id,
731
+ role: message.role,
732
+ content: textContent,
733
+ toolInvocations
734
+ });
735
+ return obj;
736
+ }, {
737
+ chatMessages: [],
738
+ toolResultContents: []
739
+ });
740
+ return chatMessages;
741
+ }
742
+ };
743
+
744
+ // src/agent/index.ts
745
+ var _Agent_decorators, _init, _a;
746
+ _Agent_decorators = [chunkPHWEC4VD_cjs.InstrumentClass({
747
+ prefix: "agent",
748
+ excludeMethods: ["hasOwnMemory", "getMemory", "__primitive", "__setTools", "__setLogger", "__setTelemetry", "log"]
749
+ })];
750
+ exports.Agent = class Agent extends (_a = chunkD63P5O4Q_cjs.MastraBase) {
751
+ name;
752
+ llm;
753
+ instructions;
754
+ model;
755
+ #mastra;
756
+ #memory;
757
+ tools;
758
+ /** @deprecated This property is deprecated. Use evals instead. */
759
+ metrics;
760
+ evals;
761
+ voice;
762
+ constructor(config) {
763
+ super({
764
+ component: chunkO7IW545H_cjs.RegisteredLogger.AGENT
765
+ });
766
+ this.name = config.name;
767
+ this.instructions = config.instructions;
768
+ if (!config.model) {
769
+ throw new Error(`LanguageModel is required to create an Agent. Please provide the 'model'.`);
770
+ }
771
+ this.llm = new MastraLLM({
772
+ model: config.model,
773
+ mastra: config.mastra
774
+ });
775
+ this.tools = {};
776
+ this.metrics = {};
777
+ this.evals = {};
778
+ if (config.tools) {
779
+ this.tools = chunk64VPB7ZD_cjs.ensureToolProperties(config.tools);
780
+ }
781
+ if (config.mastra) {
782
+ this.__registerMastra(config.mastra);
783
+ this.__registerPrimitives({
784
+ telemetry: config.mastra.getTelemetry(),
785
+ logger: config.mastra.getLogger()
786
+ });
787
+ }
788
+ if (config.metrics) {
789
+ this.logger.warn("The metrics property is deprecated. Please use evals instead to add evaluation metrics.");
790
+ this.metrics = config.metrics;
791
+ this.evals = config.metrics;
792
+ }
793
+ if (config.evals) {
794
+ this.evals = config.evals;
795
+ }
796
+ if (config.memory) {
797
+ this.#memory = config.memory;
798
+ }
799
+ if (config.voice) {
800
+ this.voice = config.voice;
801
+ this.voice?.addTools(this.tools);
802
+ this.voice?.addInstructions(config.instructions);
803
+ } else {
804
+ this.voice = new chunkBF7ZLRGO_cjs.DefaultVoice();
805
+ }
806
+ }
807
+ hasOwnMemory() {
808
+ return Boolean(this.#memory);
809
+ }
810
+ getMemory() {
811
+ return this.#memory ?? this.#mastra?.memory;
812
+ }
813
+ __updateInstructions(newInstructions) {
814
+ this.instructions = newInstructions;
815
+ this.logger.debug(`[Agents:${this.name}] Instructions updated.`, {
816
+ model: this.model,
817
+ name: this.name
818
+ });
819
+ }
820
+ __registerPrimitives(p) {
821
+ if (p.telemetry) {
822
+ this.__setTelemetry(p.telemetry);
823
+ }
824
+ if (p.logger) {
825
+ this.__setLogger(p.logger);
826
+ }
827
+ this.llm.__registerPrimitives(p);
828
+ this.logger.debug(`[Agents:${this.name}] initialized.`, {
829
+ model: this.model,
830
+ name: this.name
831
+ });
832
+ }
833
+ __registerMastra(mastra) {
834
+ this.#mastra = mastra;
835
+ this.llm.__registerMastra(mastra);
836
+ }
837
+ /**
838
+ * Set the concrete tools for the agent
839
+ * @param tools
840
+ */
841
+ __setTools(tools) {
842
+ this.tools = tools;
843
+ this.logger.debug(`[Agents:${this.name}] Tools set for agent ${this.name}`, {
844
+ model: this.model,
845
+ name: this.name
846
+ });
847
+ }
848
+ async generateTitleFromUserMessage({
849
+ message
850
+ }) {
851
+ const {
852
+ text
853
+ } = await this.llm.__text({
854
+ messages: [{
855
+ role: "system",
856
+ content: `
857
+
858
+ - you will generate a short title based on the first message a user begins a conversation with
859
+ - ensure it is not more than 80 characters long
860
+ - the title should be a summary of the user's message
861
+ - do not use quotes or colons
862
+ - the entire text you return will be used as the title`
863
+ }, {
864
+ role: "user",
865
+ content: JSON.stringify(message)
866
+ }]
867
+ });
868
+ const cleanedText = text.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
869
+ return cleanedText;
870
+ }
871
+ getMostRecentUserMessage(messages) {
872
+ const userMessages = messages.filter(message => message.role === "user");
873
+ return userMessages.at(-1);
874
+ }
875
+ async genTitle(userMessage) {
876
+ let title = `New Thread ${(/* @__PURE__ */new Date()).toISOString()}`;
877
+ try {
878
+ if (userMessage) {
879
+ title = await this.generateTitleFromUserMessage({
880
+ message: userMessage
881
+ });
882
+ }
883
+ } catch (e) {
884
+ console.error("Error generating title:", e);
885
+ }
886
+ return title;
887
+ }
888
+ async fetchMemory({
889
+ threadId,
890
+ memoryConfig,
891
+ resourceId,
892
+ userMessages,
893
+ systemMessage,
894
+ runId
895
+ }) {
896
+ const memory = this.getMemory();
897
+ if (memory) {
898
+ const thread = await memory.getThreadById({
899
+ threadId
900
+ });
901
+ if (!thread) {
902
+ return {
903
+ threadId: threadId || "",
904
+ messages: userMessages
905
+ };
906
+ }
907
+ const newMessages = chunk64VPB7ZD_cjs.ensureAllMessagesAreCoreMessages(userMessages);
908
+ const messages = newMessages.map(u => {
909
+ return {
910
+ id: this.getMemory()?.generateId(),
911
+ createdAt: /* @__PURE__ */new Date(),
912
+ threadId,
913
+ ...u,
914
+ content: u.content,
915
+ role: u.role,
916
+ type: "text"
917
+ };
918
+ });
919
+ const [memoryMessages, memorySystemMessage] = threadId && memory ? await Promise.all([memory.rememberMessages({
920
+ threadId,
921
+ resourceId,
922
+ config: memoryConfig,
923
+ systemMessage,
924
+ vectorMessageSearch: messages.slice(-1).map(m => {
925
+ if (typeof m === `string`) {
926
+ return m;
927
+ }
928
+ return m?.content || ``;
929
+ }).join(`
930
+ `)
931
+ }).then(r => r.messages), memory.getSystemMessage({
932
+ threadId,
933
+ memoryConfig
934
+ })]) : [[], null];
935
+ this.logger.debug("Saved messages to memory", {
936
+ threadId,
937
+ runId
938
+ });
939
+ const processedMessages = memory.processMessages({
940
+ messages: this.sanitizeResponseMessages(memoryMessages),
941
+ newMessages,
942
+ systemMessage: typeof systemMessage?.content === `string` ? systemMessage.content : void 0,
943
+ memorySystemMessage: memorySystemMessage ?? ``
944
+ });
945
+ return {
946
+ threadId: thread.id,
947
+ messages: [memorySystemMessage ? {
948
+ role: "system",
949
+ content: memorySystemMessage
950
+ } : null, ...processedMessages, ...newMessages].filter(message => Boolean(message))
951
+ };
952
+ }
953
+ return {
954
+ threadId: threadId || "",
955
+ messages: userMessages
956
+ };
957
+ }
958
+ async saveResponse({
959
+ result,
960
+ threadId,
961
+ resourceId,
962
+ runId,
963
+ memoryConfig
964
+ }) {
965
+ const {
966
+ response
967
+ } = result;
968
+ try {
969
+ if (response.messages) {
970
+ const ms = Array.isArray(response.messages) ? response.messages : [response.messages];
971
+ const responseMessagesWithoutIncompleteToolCalls = this.sanitizeResponseMessages(ms);
972
+ const memory = this.getMemory();
973
+ if (memory) {
974
+ this.logger.debug(`[Agent:${this.name}] - Memory persistence: store=${this.getMemory()?.constructor.name} threadId=${threadId}`, {
975
+ runId,
976
+ resourceId,
977
+ threadId,
978
+ memoryStore: this.getMemory()?.constructor.name
979
+ });
980
+ await memory.saveMessages({
981
+ memoryConfig,
982
+ messages: responseMessagesWithoutIncompleteToolCalls.map((message, index) => {
983
+ const messageId = crypto$1.randomUUID();
984
+ let toolCallIds;
985
+ let toolCallArgs;
986
+ let toolNames;
987
+ let type = "text";
988
+ if (message.role === "tool") {
989
+ toolCallIds = message.content.map(content => content.toolCallId);
990
+ type = "tool-result";
991
+ }
992
+ if (message.role === "assistant") {
993
+ const assistantContent = message.content;
994
+ const assistantToolCalls = assistantContent.map(content => {
995
+ if (content.type === "tool-call") {
996
+ return {
997
+ toolCallId: content.toolCallId,
998
+ toolArgs: content.args,
999
+ toolName: content.toolName
1000
+ };
1001
+ }
1002
+ return void 0;
1003
+ })?.filter(Boolean);
1004
+ toolCallIds = assistantToolCalls?.map(toolCall => toolCall.toolCallId);
1005
+ toolCallArgs = assistantToolCalls?.map(toolCall => toolCall.toolArgs);
1006
+ toolNames = assistantToolCalls?.map(toolCall => toolCall.toolName);
1007
+ type = assistantContent?.[0]?.type;
1008
+ }
1009
+ return {
1010
+ id: messageId,
1011
+ threadId,
1012
+ resourceId,
1013
+ role: message.role,
1014
+ content: message.content,
1015
+ createdAt: new Date(Date.now() + index),
1016
+ // use Date.now() + index to make sure every message is atleast one millisecond apart
1017
+ toolCallIds: toolCallIds?.length ? toolCallIds : void 0,
1018
+ toolCallArgs: toolCallArgs?.length ? toolCallArgs : void 0,
1019
+ toolNames: toolNames?.length ? toolNames : void 0,
1020
+ type
1021
+ };
1022
+ })
1023
+ });
1024
+ }
1025
+ }
1026
+ } catch (err) {
1027
+ this.logger.error(`[Agent:${this.name}] - Failed to save assistant response`, {
1028
+ error: err,
1029
+ runId
1030
+ });
1031
+ }
1032
+ }
1033
+ sanitizeResponseMessages(messages) {
1034
+ let toolResultIds = [];
1035
+ let toolCallIds = [];
1036
+ for (const message of messages) {
1037
+ if (!Array.isArray(message.content)) continue;
1038
+ if (message.role === "tool") {
1039
+ for (const content of message.content) {
1040
+ if (content.type === "tool-result") {
1041
+ toolResultIds.push(content.toolCallId);
1042
+ }
1043
+ }
1044
+ } else if (message.role === "assistant" || message.role === "user") {
1045
+ for (const content of message.content) {
1046
+ if (typeof content !== `string`) {
1047
+ if (content.type === `tool-call`) {
1048
+ toolCallIds.push(content.toolCallId);
1049
+ }
1050
+ }
1051
+ }
1052
+ }
1053
+ }
1054
+ const messagesBySanitizedContent = messages.map(message => {
1055
+ if (message.role !== "assistant" && message.role !== `tool` && message.role !== `user`) return message;
1056
+ if (!message.content || typeof message.content === "string" || typeof message.content === "number") {
1057
+ return message;
1058
+ }
1059
+ const sanitizedContent = message.content.filter(content => {
1060
+ if (content.type === `tool-call`) {
1061
+ return toolResultIds.includes(content.toolCallId);
1062
+ }
1063
+ if (content.type === `text`) {
1064
+ return content.text.trim() !== ``;
1065
+ }
1066
+ if (content.type === `tool-result`) {
1067
+ return toolCallIds.includes(content.toolCallId);
1068
+ }
1069
+ return true;
1070
+ });
1071
+ return {
1072
+ ...message,
1073
+ content: sanitizedContent
1074
+ };
1075
+ });
1076
+ return messagesBySanitizedContent.filter(message => {
1077
+ if (typeof message.content === `string`) {
1078
+ return message.content !== "";
1079
+ }
1080
+ if (Array.isArray(message.content)) {
1081
+ return message.content.length && message.content.every(c => {
1082
+ if (c.type === `text`) {
1083
+ return c.text && c.text !== "";
1084
+ }
1085
+ return true;
1086
+ });
1087
+ }
1088
+ return true;
1089
+ });
1090
+ }
1091
+ convertTools({
1092
+ toolsets,
1093
+ threadId,
1094
+ resourceId,
1095
+ runId
1096
+ }) {
1097
+ this.logger.debug(`[Agents:${this.name}] - Assigning tools`, {
1098
+ runId,
1099
+ threadId,
1100
+ resourceId
1101
+ });
1102
+ const memory = this.getMemory();
1103
+ const memoryTools = memory?.getTools?.();
1104
+ let mastraProxy = void 0;
1105
+ const logger = this.logger;
1106
+ if (this.#mastra) {
1107
+ mastraProxy = chunk64VPB7ZD_cjs.createMastraProxy({
1108
+ mastra: this.#mastra,
1109
+ logger
1110
+ });
1111
+ }
1112
+ const converted = Object.entries(this.tools || {}).reduce((memo, value) => {
1113
+ const k = value[0];
1114
+ const tool = this.tools[k];
1115
+ if (tool) {
1116
+ const options = {
1117
+ name: k,
1118
+ runId,
1119
+ threadId,
1120
+ resourceId,
1121
+ logger: this.logger,
1122
+ mastra: mastraProxy,
1123
+ memory,
1124
+ agentName: this.name
1125
+ };
1126
+ memo[k] = chunk64VPB7ZD_cjs.makeCoreTool(tool, options);
1127
+ }
1128
+ return memo;
1129
+ }, {});
1130
+ const convertedMemoryTools = memoryTools ? Object.entries(memoryTools).reduce((memo, [k, tool]) => {
1131
+ memo[k] = {
1132
+ description: tool.description,
1133
+ parameters: tool.parameters,
1134
+ execute: typeof tool?.execute === "function" ? async (args, options) => {
1135
+ try {
1136
+ this.logger.debug(`[Agent:${this.name}] - Executing memory tool ${k}`, {
1137
+ name: k,
1138
+ description: tool.description,
1139
+ args,
1140
+ runId,
1141
+ threadId,
1142
+ resourceId
1143
+ });
1144
+ return tool?.execute?.({
1145
+ context: args,
1146
+ mastra: mastraProxy,
1147
+ memory,
1148
+ runId,
1149
+ threadId,
1150
+ resourceId
1151
+ }, options) ?? void 0;
1152
+ } catch (err) {
1153
+ this.logger.error(`[Agent:${this.name}] - Failed memory tool execution`, {
1154
+ error: err,
1155
+ runId,
1156
+ threadId,
1157
+ resourceId
1158
+ });
1159
+ throw err;
1160
+ }
1161
+ } : void 0
1162
+ };
1163
+ return memo;
1164
+ }, {}) : {};
1165
+ const toolsFromToolsetsConverted = {
1166
+ ...converted,
1167
+ ...convertedMemoryTools
1168
+ };
1169
+ const toolsFromToolsets = Object.values(toolsets || {});
1170
+ if (toolsFromToolsets.length > 0) {
1171
+ this.logger.debug(`[Agent:${this.name}] - Adding tools from toolsets ${Object.keys(toolsets || {}).join(", ")}`, {
1172
+ runId
1173
+ });
1174
+ toolsFromToolsets.forEach(toolset => {
1175
+ Object.entries(toolset).forEach(([toolName, tool]) => {
1176
+ const toolObj = tool;
1177
+ const options = {
1178
+ name: toolName,
1179
+ runId,
1180
+ threadId,
1181
+ resourceId,
1182
+ logger: this.logger,
1183
+ agentName: this.name
1184
+ };
1185
+ toolsFromToolsetsConverted[toolName] = chunk64VPB7ZD_cjs.makeCoreTool(toolObj, options, "toolset");
1186
+ });
1187
+ });
1188
+ }
1189
+ return toolsFromToolsetsConverted;
1190
+ }
1191
+ async preExecute({
1192
+ resourceId,
1193
+ runId,
1194
+ threadId,
1195
+ memoryConfig,
1196
+ messages,
1197
+ systemMessage
1198
+ }) {
1199
+ let coreMessages = [];
1200
+ let threadIdToUse = threadId;
1201
+ this.logger.debug(`Saving user messages in memory for agent ${this.name}`, {
1202
+ runId
1203
+ });
1204
+ const saveMessageResponse = await this.fetchMemory({
1205
+ threadId,
1206
+ resourceId,
1207
+ userMessages: messages,
1208
+ memoryConfig,
1209
+ systemMessage
1210
+ });
1211
+ coreMessages = saveMessageResponse.messages;
1212
+ threadIdToUse = saveMessageResponse.threadId;
1213
+ return {
1214
+ coreMessages,
1215
+ threadIdToUse
1216
+ };
1217
+ }
1218
+ __primitive({
1219
+ instructions,
1220
+ messages,
1221
+ context,
1222
+ threadId,
1223
+ memoryConfig,
1224
+ resourceId,
1225
+ runId,
1226
+ toolsets
1227
+ }) {
1228
+ return {
1229
+ before: async () => {
1230
+ if (process.env.NODE_ENV !== "test") {
1231
+ this.logger.debug(`[Agents:${this.name}] - Starting generation`, {
1232
+ runId
1233
+ });
1234
+ }
1235
+ const systemMessage = {
1236
+ role: "system",
1237
+ content: instructions || `${this.instructions}.`
1238
+ };
1239
+ let coreMessages = messages;
1240
+ let threadIdToUse = threadId;
1241
+ let thread;
1242
+ const memory = this.getMemory();
1243
+ if (threadId && memory && !resourceId) {
1244
+ throw new Error(`A resourceId must be provided when passing a threadId and using Memory. Saw threadId ${threadId} but resourceId is ${resourceId}`);
1245
+ }
1246
+ if (memory && resourceId) {
1247
+ this.logger.debug(`[Agent:${this.name}] - Memory persistence enabled: store=${this.getMemory()?.constructor.name}, resourceId=${resourceId}`, {
1248
+ runId,
1249
+ resourceId,
1250
+ threadId: threadIdToUse,
1251
+ memoryStore: this.getMemory()?.constructor.name
1252
+ });
1253
+ thread = threadIdToUse ? await memory.getThreadById({
1254
+ threadId: threadIdToUse
1255
+ }) : void 0;
1256
+ if (!thread) {
1257
+ thread = await memory.createThread({
1258
+ threadId: threadIdToUse,
1259
+ resourceId,
1260
+ memoryConfig
1261
+ });
1262
+ }
1263
+ threadIdToUse = thread.id;
1264
+ const preExecuteResult = await this.preExecute({
1265
+ resourceId,
1266
+ runId,
1267
+ threadId: threadIdToUse,
1268
+ memoryConfig,
1269
+ messages,
1270
+ systemMessage
1271
+ });
1272
+ coreMessages = preExecuteResult.coreMessages;
1273
+ threadIdToUse = preExecuteResult.threadIdToUse;
1274
+ }
1275
+ let convertedTools;
1276
+ if (toolsets && Object.keys(toolsets || {}).length > 0 || this.getMemory() && resourceId) {
1277
+ const reasons = [];
1278
+ if (toolsets && Object.keys(toolsets || {}).length > 0) {
1279
+ reasons.push(`toolsets present (${Object.keys(toolsets || {}).length} tools)`);
1280
+ }
1281
+ if (this.getMemory() && resourceId) {
1282
+ reasons.push("memory and resourceId available");
1283
+ }
1284
+ this.logger.debug(`[Agent:${this.name}] - Enhancing tools: ${reasons.join(", ")}`, {
1285
+ runId,
1286
+ toolsets: toolsets ? Object.keys(toolsets) : void 0,
1287
+ hasMemory: !!this.getMemory(),
1288
+ hasResourceId: !!resourceId
1289
+ });
1290
+ convertedTools = this.convertTools({
1291
+ toolsets,
1292
+ threadId: threadIdToUse,
1293
+ resourceId,
1294
+ runId
1295
+ });
1296
+ }
1297
+ const messageObjects = [systemMessage, ...(context || []), ...coreMessages];
1298
+ return {
1299
+ messageObjects,
1300
+ convertedTools,
1301
+ threadId: threadIdToUse,
1302
+ thread
1303
+ };
1304
+ },
1305
+ after: async ({
1306
+ result,
1307
+ thread: threadAfter,
1308
+ threadId: threadId2,
1309
+ memoryConfig: memoryConfig2,
1310
+ outputText,
1311
+ runId: runId2
1312
+ }) => {
1313
+ const resToLog = {
1314
+ text: result?.text,
1315
+ object: result?.object,
1316
+ toolResults: result?.toolResults,
1317
+ toolCalls: result?.toolCalls,
1318
+ usage: result?.usage,
1319
+ steps: result?.steps?.map(s => {
1320
+ return {
1321
+ stepType: s?.stepType,
1322
+ text: result?.text,
1323
+ object: result?.object,
1324
+ toolResults: result?.toolResults,
1325
+ toolCalls: result?.toolCalls,
1326
+ usage: result?.usage
1327
+ };
1328
+ })
1329
+ };
1330
+ this.logger.debug(`[Agent:${this.name}] - Post processing LLM response`, {
1331
+ runId: runId2,
1332
+ result: resToLog,
1333
+ threadId: threadId2
1334
+ });
1335
+ const memory = this.getMemory();
1336
+ const thread = threadAfter || (threadId2 ? await memory?.getThreadById({
1337
+ threadId: threadId2
1338
+ }) : void 0);
1339
+ if (memory && resourceId && thread) {
1340
+ try {
1341
+ const userMessage = this.getMostRecentUserMessage(messages);
1342
+ const newMessages = userMessage ? [userMessage] : messages;
1343
+ const threadMessages = newMessages.map(u => {
1344
+ return {
1345
+ id: this.getMemory()?.generateId(),
1346
+ createdAt: /* @__PURE__ */new Date(),
1347
+ threadId: thread.id,
1348
+ resourceId,
1349
+ ...u,
1350
+ content: u.content,
1351
+ role: u.role,
1352
+ type: "text"
1353
+ };
1354
+ });
1355
+ await Promise.all([(async () => {
1356
+ await memory.saveMessages({
1357
+ messages: threadMessages,
1358
+ memoryConfig: memoryConfig2
1359
+ });
1360
+ await this.saveResponse({
1361
+ result,
1362
+ threadId: threadId2,
1363
+ resourceId,
1364
+ memoryConfig: memoryConfig2,
1365
+ runId: runId2
1366
+ });
1367
+ })(), (async () => {
1368
+ if (!thread.title?.startsWith("New Thread")) {
1369
+ return;
1370
+ }
1371
+ const config = memory.getMergedThreadConfig(memoryConfig2);
1372
+ const title = config?.threads?.generateTitle ? await this.genTitle(userMessage) : void 0;
1373
+ if (!title) {
1374
+ return;
1375
+ }
1376
+ return memory.createThread({
1377
+ threadId: thread.id,
1378
+ resourceId,
1379
+ memoryConfig: memoryConfig2,
1380
+ title
1381
+ });
1382
+ })()]);
1383
+ } catch (e) {
1384
+ this.logger.error("Error saving response", {
1385
+ error: e,
1386
+ runId: runId2,
1387
+ result: resToLog,
1388
+ threadId: threadId2
1389
+ });
1390
+ }
1391
+ }
1392
+ if (Object.keys(this.evals || {}).length > 0) {
1393
+ const input = messages.map(message => message.content).join("\n");
1394
+ const runIdToUse = runId2 || crypto.randomUUID();
1395
+ for (const metric of Object.values(this.evals || {})) {
1396
+ chunkST5RMVLG_cjs.executeHook("onGeneration" /* ON_GENERATION */, {
1397
+ input,
1398
+ output: outputText,
1399
+ runId: runIdToUse,
1400
+ metric,
1401
+ agentName: this.name,
1402
+ instructions: instructions || this.instructions
1403
+ });
1404
+ }
1405
+ }
1406
+ }
1407
+ };
1408
+ }
1409
+ async generate(messages, {
1410
+ instructions,
1411
+ context,
1412
+ threadId: threadIdInFn,
1413
+ memoryOptions,
1414
+ resourceId,
1415
+ maxSteps = 5,
1416
+ onStepFinish,
1417
+ runId,
1418
+ output,
1419
+ toolsets,
1420
+ temperature,
1421
+ toolChoice = "auto",
1422
+ experimental_output,
1423
+ telemetry,
1424
+ ...rest
1425
+ } = {}) {
1426
+ let messagesToUse = [];
1427
+ if (typeof messages === `string`) {
1428
+ messagesToUse = [{
1429
+ role: "user",
1430
+ content: messages
1431
+ }];
1432
+ } else if (Array.isArray(messages)) {
1433
+ messagesToUse = messages.map(message => {
1434
+ if (typeof message === `string`) {
1435
+ return {
1436
+ role: "user",
1437
+ content: message
1438
+ };
1439
+ }
1440
+ return message;
1441
+ });
1442
+ } else {
1443
+ messagesToUse = [messages];
1444
+ }
1445
+ const runIdToUse = runId || crypto$1.randomUUID();
1446
+ const {
1447
+ before,
1448
+ after
1449
+ } = this.__primitive({
1450
+ instructions,
1451
+ messages: messagesToUse,
1452
+ context,
1453
+ threadId: threadIdInFn,
1454
+ memoryConfig: memoryOptions,
1455
+ resourceId,
1456
+ runId: runIdToUse,
1457
+ toolsets
1458
+ });
1459
+ const {
1460
+ threadId,
1461
+ thread,
1462
+ messageObjects,
1463
+ convertedTools
1464
+ } = await before();
1465
+ if (!output && experimental_output) {
1466
+ const result2 = await this.llm.__text({
1467
+ messages: messageObjects,
1468
+ tools: this.tools,
1469
+ convertedTools,
1470
+ onStepFinish: result3 => {
1471
+ void onStepFinish?.(result3);
1472
+ },
1473
+ maxSteps: maxSteps || 5,
1474
+ runId: runIdToUse,
1475
+ temperature,
1476
+ toolChoice: toolChoice || "auto",
1477
+ experimental_output,
1478
+ threadId,
1479
+ resourceId,
1480
+ memory: this.getMemory(),
1481
+ ...rest
1482
+ });
1483
+ const outputText2 = result2.text;
1484
+ await after({
1485
+ result: result2,
1486
+ threadId,
1487
+ thread,
1488
+ memoryConfig: memoryOptions,
1489
+ outputText: outputText2,
1490
+ runId: runIdToUse
1491
+ });
1492
+ const newResult = result2;
1493
+ newResult.object = result2.experimental_output;
1494
+ return newResult;
1495
+ }
1496
+ if (!output) {
1497
+ const result2 = await this.llm.__text({
1498
+ messages: messageObjects,
1499
+ tools: this.tools,
1500
+ convertedTools,
1501
+ onStepFinish: result3 => {
1502
+ void onStepFinish?.(result3);
1503
+ },
1504
+ maxSteps,
1505
+ runId: runIdToUse,
1506
+ temperature,
1507
+ toolChoice,
1508
+ telemetry,
1509
+ threadId,
1510
+ resourceId,
1511
+ memory: this.getMemory(),
1512
+ ...rest
1513
+ });
1514
+ const outputText2 = result2.text;
1515
+ await after({
1516
+ result: result2,
1517
+ thread,
1518
+ threadId,
1519
+ memoryConfig: memoryOptions,
1520
+ outputText: outputText2,
1521
+ runId: runIdToUse
1522
+ });
1523
+ return result2;
1524
+ }
1525
+ const result = await this.llm.__textObject({
1526
+ messages: messageObjects,
1527
+ tools: this.tools,
1528
+ structuredOutput: output,
1529
+ convertedTools,
1530
+ onStepFinish: result2 => {
1531
+ void onStepFinish?.(result2);
1532
+ },
1533
+ maxSteps,
1534
+ runId: runIdToUse,
1535
+ temperature,
1536
+ toolChoice,
1537
+ telemetry,
1538
+ memory: this.getMemory(),
1539
+ ...rest
1540
+ });
1541
+ const outputText = JSON.stringify(result.object);
1542
+ await after({
1543
+ result,
1544
+ thread,
1545
+ threadId,
1546
+ memoryConfig: memoryOptions,
1547
+ outputText,
1548
+ runId: runIdToUse
1549
+ });
1550
+ return result;
1551
+ }
1552
+ async stream(messages, {
1553
+ instructions,
1554
+ context,
1555
+ threadId: threadIdInFn,
1556
+ memoryOptions,
1557
+ resourceId,
1558
+ maxSteps = 5,
1559
+ onFinish,
1560
+ onStepFinish,
1561
+ runId,
1562
+ toolsets,
1563
+ output,
1564
+ temperature,
1565
+ toolChoice = "auto",
1566
+ experimental_output,
1567
+ telemetry,
1568
+ ...rest
1569
+ } = {}) {
1570
+ const runIdToUse = runId || crypto$1.randomUUID();
1571
+ let messagesToUse = [];
1572
+ if (typeof messages === `string`) {
1573
+ messagesToUse = [{
1574
+ role: "user",
1575
+ content: messages
1576
+ }];
1577
+ } else {
1578
+ messagesToUse = messages.map(message => {
1579
+ if (typeof message === `string`) {
1580
+ return {
1581
+ role: "user",
1582
+ content: message
1583
+ };
1584
+ }
1585
+ return message;
1586
+ });
1587
+ }
1588
+ const {
1589
+ before,
1590
+ after
1591
+ } = this.__primitive({
1592
+ instructions,
1593
+ messages: messagesToUse,
1594
+ context,
1595
+ threadId: threadIdInFn,
1596
+ memoryConfig: memoryOptions,
1597
+ resourceId,
1598
+ runId: runIdToUse,
1599
+ toolsets
1600
+ });
1601
+ const {
1602
+ threadId,
1603
+ thread,
1604
+ messageObjects,
1605
+ convertedTools
1606
+ } = await before();
1607
+ if (!output && experimental_output) {
1608
+ this.logger.debug(`Starting agent ${this.name} llm stream call`, {
1609
+ runId
1610
+ });
1611
+ const streamResult = await this.llm.__stream({
1612
+ messages: messageObjects,
1613
+ temperature,
1614
+ tools: this.tools,
1615
+ convertedTools,
1616
+ onStepFinish: result => {
1617
+ void onStepFinish?.(result);
1618
+ },
1619
+ onFinish: async result => {
1620
+ try {
1621
+ const outputText = result.text;
1622
+ await after({
1623
+ result,
1624
+ thread,
1625
+ threadId,
1626
+ memoryConfig: memoryOptions,
1627
+ outputText,
1628
+ runId: runIdToUse
1629
+ });
1630
+ } catch (e) {
1631
+ this.logger.error("Error saving memory on finish", {
1632
+ error: e,
1633
+ runId
1634
+ });
1635
+ }
1636
+ void onFinish?.(result);
1637
+ },
1638
+ maxSteps,
1639
+ runId: runIdToUse,
1640
+ toolChoice,
1641
+ experimental_output,
1642
+ memory: this.getMemory(),
1643
+ ...rest
1644
+ });
1645
+ const newStreamResult = streamResult;
1646
+ newStreamResult.partialObjectStream = streamResult.experimental_partialOutputStream;
1647
+ return newStreamResult;
1648
+ } else if (!output) {
1649
+ this.logger.debug(`Starting agent ${this.name} llm stream call`, {
1650
+ runId
1651
+ });
1652
+ return this.llm.__stream({
1653
+ messages: messageObjects,
1654
+ temperature,
1655
+ tools: this.tools,
1656
+ convertedTools,
1657
+ onStepFinish: result => {
1658
+ void onStepFinish?.(result);
1659
+ },
1660
+ onFinish: async result => {
1661
+ try {
1662
+ const outputText = result.text;
1663
+ await after({
1664
+ result,
1665
+ thread,
1666
+ threadId,
1667
+ memoryConfig: memoryOptions,
1668
+ outputText,
1669
+ runId: runIdToUse
1670
+ });
1671
+ } catch (e) {
1672
+ this.logger.error("Error saving memory on finish", {
1673
+ error: e,
1674
+ runId
1675
+ });
1676
+ }
1677
+ void onFinish?.(result);
1678
+ },
1679
+ maxSteps,
1680
+ runId: runIdToUse,
1681
+ toolChoice,
1682
+ telemetry,
1683
+ memory: this.getMemory(),
1684
+ ...rest
1685
+ });
1686
+ }
1687
+ this.logger.debug(`Starting agent ${this.name} llm streamObject call`, {
1688
+ runId
1689
+ });
1690
+ return this.llm.__streamObject({
1691
+ messages: messageObjects,
1692
+ tools: this.tools,
1693
+ temperature,
1694
+ structuredOutput: output,
1695
+ convertedTools,
1696
+ onStepFinish: result => {
1697
+ void onStepFinish?.(result);
1698
+ },
1699
+ onFinish: async result => {
1700
+ try {
1701
+ const outputText = JSON.stringify(result.object);
1702
+ await after({
1703
+ result,
1704
+ thread,
1705
+ threadId,
1706
+ memoryConfig: memoryOptions,
1707
+ outputText,
1708
+ runId: runIdToUse
1709
+ });
1710
+ } catch (e) {
1711
+ this.logger.error("Error saving memory on finish", {
1712
+ error: e,
1713
+ runId
1714
+ });
1715
+ }
1716
+ void onFinish?.(result);
1717
+ },
1718
+ runId: runIdToUse,
1719
+ toolChoice,
1720
+ telemetry,
1721
+ memory: this.getMemory(),
1722
+ ...rest
1723
+ });
1724
+ }
1725
+ /**
1726
+ * Convert text to speech using the configured voice provider
1727
+ * @param input Text or text stream to convert to speech
1728
+ * @param options Speech options including speaker and provider-specific options
1729
+ * @returns Audio stream
1730
+ * @deprecated Use agent.voice.speak() instead
1731
+ */
1732
+ async speak(input, options) {
1733
+ if (!this.voice) {
1734
+ throw new Error("No voice provider configured");
1735
+ }
1736
+ this.logger.warn("Warning: agent.speak() is deprecated. Please use agent.voice.speak() instead.");
1737
+ try {
1738
+ return this.voice.speak(input, options);
1739
+ } catch (e) {
1740
+ this.logger.error("Error during agent speak", {
1741
+ error: e
1742
+ });
1743
+ throw e;
1744
+ }
1745
+ }
1746
+ /**
1747
+ * Convert speech to text using the configured voice provider
1748
+ * @param audioStream Audio stream to transcribe
1749
+ * @param options Provider-specific transcription options
1750
+ * @returns Text or text stream
1751
+ * @deprecated Use agent.voice.listen() instead
1752
+ */
1753
+ async listen(audioStream, options) {
1754
+ if (!this.voice) {
1755
+ throw new Error("No voice provider configured");
1756
+ }
1757
+ this.logger.warn("Warning: agent.listen() is deprecated. Please use agent.voice.listen() instead");
1758
+ try {
1759
+ return this.voice.listen(audioStream, options);
1760
+ } catch (e) {
1761
+ this.logger.error("Error during agent listen", {
1762
+ error: e
1763
+ });
1764
+ throw e;
1765
+ }
1766
+ }
1767
+ /**
1768
+ * Get a list of available speakers from the configured voice provider
1769
+ * @throws {Error} If no voice provider is configured
1770
+ * @returns {Promise<Array<{voiceId: string}>>} List of available speakers
1771
+ * @deprecated Use agent.voice.getSpeakers() instead
1772
+ */
1773
+ async getSpeakers() {
1774
+ if (!this.voice) {
1775
+ throw new Error("No voice provider configured");
1776
+ }
1777
+ this.logger.warn("Warning: agent.getSpeakers() is deprecated. Please use agent.voice.getSpeakers() instead.");
1778
+ try {
1779
+ return await this.voice.getSpeakers();
1780
+ } catch (e) {
1781
+ this.logger.error("Error during agent getSpeakers", {
1782
+ error: e
1783
+ });
1784
+ throw e;
1785
+ }
1786
+ }
1787
+ toStep() {
1788
+ const x = agentToStep(this);
1789
+ return new Step(x);
1790
+ }
1791
+ };
1792
+ exports.Agent = /*@__PURE__*/(_ => {
1793
+ _init = chunkRWTSGWWL_cjs.__decoratorStart(_a);
1794
+ exports.Agent = chunkRWTSGWWL_cjs.__decorateElement(_init, 0, "Agent", _Agent_decorators, exports.Agent);
1795
+ chunkRWTSGWWL_cjs.__runInitializers(_init, 1, exports.Agent);
1796
+
1797
+ // src/workflows/utils.ts
1798
+ return exports.Agent;
1799
+ })();
1800
+ // src/workflows/utils.ts
1801
+ function isErrorEvent(stateEvent) {
1802
+ return stateEvent.type.startsWith("xstate.error.actor.");
1803
+ }
1804
+ function isTransitionEvent(stateEvent) {
1805
+ return stateEvent.type.startsWith("xstate.done.actor.");
1806
+ }
1807
+ function isVariableReference(value) {
1808
+ return typeof value === "object" && "step" in value && "path" in value;
1809
+ }
1810
+ function getStepResult(result) {
1811
+ if (result?.status === "success") return result.output;
1812
+ return void 0;
1813
+ }
1814
+ function getSuspendedPaths({
1815
+ value,
1816
+ path,
1817
+ suspendedPaths
1818
+ }) {
1819
+ if (typeof value === "string") {
1820
+ if (value === "suspended") {
1821
+ suspendedPaths.add(path);
1822
+ }
1823
+ } else {
1824
+ Object.keys(value).forEach(key => getSuspendedPaths({
1825
+ value: value[key],
1826
+ path: path ? `${path}.${key}` : key,
1827
+ suspendedPaths
1828
+ }));
1829
+ }
1830
+ }
1831
+ function isFinalState(status) {
1832
+ return ["completed", "failed"].includes(status);
1833
+ }
1834
+ function isLimboState(status) {
1835
+ return status === "limbo";
1836
+ }
1837
+ function recursivelyCheckForFinalState({
1838
+ value,
1839
+ suspendedPaths,
1840
+ path
1841
+ }) {
1842
+ if (typeof value === "string") {
1843
+ return isFinalState(value) || isLimboState(value) || suspendedPaths.has(path);
1844
+ }
1845
+ return Object.keys(value).every(key => recursivelyCheckForFinalState({
1846
+ value: value[key],
1847
+ suspendedPaths,
1848
+ path: path ? `${path}.${key}` : key
1849
+ }));
1850
+ }
1851
+ function getActivePathsAndStatus(value) {
1852
+ const paths = [];
1853
+ const traverse = (current, path = []) => {
1854
+ for (const [key, value2] of Object.entries(current)) {
1855
+ const currentPath = [...path, key];
1856
+ if (typeof value2 === "string") {
1857
+ paths.push({
1858
+ stepPath: currentPath,
1859
+ stepId: key,
1860
+ status: value2
1861
+ });
1862
+ } else if (typeof value2 === "object" && value2 !== null) {
1863
+ traverse(value2, currentPath);
1864
+ }
1865
+ }
1866
+ };
1867
+ traverse(value);
1868
+ return paths;
1869
+ }
1870
+ function mergeChildValue(startStepId, parent, child) {
1871
+ const traverse = current => {
1872
+ const obj = {};
1873
+ for (const [key, value] of Object.entries(current)) {
1874
+ if (key === startStepId) {
1875
+ obj[key] = {
1876
+ ...child
1877
+ };
1878
+ } else if (typeof value === "string") {
1879
+ obj[key] = value;
1880
+ } else if (typeof value === "object" && value !== null) {
1881
+ obj[key] = traverse(value);
1882
+ }
1883
+ }
1884
+ return obj;
1885
+ };
1886
+ return traverse(parent);
1887
+ }
1888
+ var updateStepInHierarchy = (value, targetStepId) => {
1889
+ const result = {};
1890
+ for (const key of Object.keys(value)) {
1891
+ const currentValue = value[key];
1892
+ if (key === targetStepId) {
1893
+ result[key] = "pending";
1894
+ } else if (typeof currentValue === "object" && currentValue !== null) {
1895
+ result[key] = updateStepInHierarchy(currentValue, targetStepId);
1896
+ } else {
1897
+ result[key] = currentValue;
1898
+ }
1899
+ }
1900
+ return result;
1901
+ };
1902
+ function getResultActivePaths(state) {
1903
+ const activePaths = getActivePathsAndStatus(state.value);
1904
+ const activePathsAndStatus = activePaths.reduce((acc, curr) => {
1905
+ const entry = {
1906
+ status: curr.status,
1907
+ stepPath: curr.stepPath
1908
+ };
1909
+ if (curr.status === "suspended") {
1910
+ entry.suspendPayload = state.context.steps[curr.stepId].suspendPayload;
1911
+ entry.stepPath = curr.stepPath;
1912
+ }
1913
+ acc.set(curr.stepId, entry);
1914
+ return acc;
1915
+ }, /* @__PURE__ */new Map());
1916
+ return activePathsAndStatus;
1917
+ }
1918
+ function isWorkflow(step) {
1919
+ return step instanceof Workflow;
1920
+ }
1921
+ function isAgent(step) {
1922
+ return step instanceof exports.Agent;
1923
+ }
1924
+ function resolveVariables({
1925
+ runId,
1926
+ logger,
1927
+ variables,
1928
+ context
1929
+ }) {
1930
+ const resolvedData = {};
1931
+ for (const [key, variable] of Object.entries(variables)) {
1932
+ const sourceData = variable.step === "trigger" ? context.triggerData : getStepResult(context.steps[variable.step.id ?? variable.step.name]);
1933
+ logger.debug(`Got source data for ${key} variable from ${variable.step === "trigger" ? "trigger" : variable.step.id ?? variable.step.name}`, {
1934
+ sourceData,
1935
+ path: variable.path,
1936
+ runId
1937
+ });
1938
+ if (!sourceData && variable.step !== "trigger") {
1939
+ resolvedData[key] = void 0;
1940
+ continue;
1941
+ }
1942
+ const value = variable.path === "" || variable.path === "." ? sourceData : radash.get(sourceData, variable.path);
1943
+ logger.debug(`Resolved variable ${key}`, {
1944
+ value,
1945
+ runId
1946
+ });
1947
+ resolvedData[key] = value;
1948
+ }
1949
+ return resolvedData;
1950
+ }
1951
+ function agentToStep(agent, {
1952
+ mastra
1953
+ } = {}) {
1954
+ return {
1955
+ id: agent.name,
1956
+ inputSchema: zod.z.object({
1957
+ prompt: zod.z.string(),
1958
+ resourceId: zod.z.string().optional(),
1959
+ threadId: zod.z.string().optional()
1960
+ }),
1961
+ outputSchema: zod.z.object({
1962
+ text: zod.z.string()
1963
+ }),
1964
+ execute: async ({
1965
+ context,
1966
+ runId,
1967
+ mastra: mastraFromExecute
1968
+ }) => {
1969
+ const realMastra = mastraFromExecute ?? mastra;
1970
+ if (!realMastra) {
1971
+ throw new Error("Mastra instance not found");
1972
+ }
1973
+ agent.__registerMastra(realMastra);
1974
+ agent.__registerPrimitives({
1975
+ logger: realMastra.getLogger(),
1976
+ telemetry: realMastra.getTelemetry()
1977
+ });
1978
+ const result = await agent.generate(context.inputData.prompt, {
1979
+ runId,
1980
+ resourceId: context.inputData.resourceId,
1981
+ threadId: context.inputData.threadId
1982
+ });
1983
+ return {
1984
+ text: result.text
1985
+ };
1986
+ }
1987
+ };
1988
+ }
1989
+ function workflowToStep(workflow, {
1990
+ mastra
1991
+ }) {
1992
+ workflow.setNested(true);
1993
+ return {
1994
+ id: workflow.name,
1995
+ workflow,
1996
+ execute: async ({
1997
+ context,
1998
+ suspend,
1999
+ emit,
2000
+ mastra: mastraFromExecute
2001
+ }) => {
2002
+ const realMastra = mastraFromExecute ?? mastra;
2003
+ if (realMastra) {
2004
+ workflow.__registerMastra(realMastra);
2005
+ workflow.__registerPrimitives({
2006
+ logger: realMastra.getLogger(),
2007
+ telemetry: realMastra.getTelemetry()
2008
+ });
2009
+ }
2010
+ const run = context.isResume ? workflow.createRun({
2011
+ runId: context.isResume.runId
2012
+ }) : workflow.createRun();
2013
+ const unwatch = run.watch(state => {
2014
+ emit("state-update", workflow.name, state.results, {
2015
+ ...context,
2016
+ ...{
2017
+ [workflow.name]: state.results
2018
+ }
2019
+ });
2020
+ });
2021
+ const awaitedResult = context.isResume && context.isResume.stepId.includes(".") ? await run.resume({
2022
+ stepId: context.isResume.stepId.split(".").slice(1).join("."),
2023
+ context: context.inputData
2024
+ }) : await run.start({
2025
+ triggerData: context.inputData
2026
+ });
2027
+ unwatch();
2028
+ if (!awaitedResult) {
2029
+ throw new Error("Workflow run failed");
2030
+ }
2031
+ if (awaitedResult.activePaths?.size > 0) {
2032
+ const suspendedStep = [...awaitedResult.activePaths.entries()].find(([, {
2033
+ status
2034
+ }]) => {
2035
+ return status === "suspended";
2036
+ });
2037
+ if (suspendedStep) {
2038
+ await suspend(suspendedStep[1].suspendPayload, {
2039
+ ...awaitedResult,
2040
+ runId: run.runId
2041
+ });
2042
+ }
2043
+ }
2044
+ return {
2045
+ ...awaitedResult,
2046
+ runId: run.runId
2047
+ };
2048
+ }
2049
+ };
2050
+ }
2051
+ var Machine = class extends EventEmitter__default.default {
2052
+ logger;
2053
+ #mastra;
2054
+ #workflowInstance;
2055
+ #executionSpan;
2056
+ #stepGraph;
2057
+ #machine;
2058
+ #runId;
2059
+ #startStepId;
2060
+ name;
2061
+ #actor = null;
2062
+ #steps = {};
2063
+ #retryConfig;
2064
+ constructor({
2065
+ logger,
2066
+ mastra,
2067
+ workflowInstance,
2068
+ executionSpan,
2069
+ name,
2070
+ runId,
2071
+ steps,
2072
+ stepGraph,
2073
+ retryConfig,
2074
+ startStepId
2075
+ }) {
2076
+ super();
2077
+ this.#mastra = mastra;
2078
+ this.#workflowInstance = workflowInstance;
2079
+ this.#executionSpan = executionSpan;
2080
+ this.logger = logger;
2081
+ this.#runId = runId;
2082
+ this.#startStepId = startStepId;
2083
+ this.name = name;
2084
+ this.#stepGraph = stepGraph;
2085
+ this.#steps = steps;
2086
+ this.#retryConfig = retryConfig;
2087
+ this.initializeMachine();
2088
+ }
2089
+ get startStepId() {
2090
+ return this.#startStepId;
2091
+ }
2092
+ async execute({
2093
+ stepId,
2094
+ input,
2095
+ snapshot,
2096
+ resumeData
2097
+ } = {}) {
2098
+ if (snapshot) {
2099
+ this.logger.debug(`Workflow snapshot received`, {
2100
+ runId: this.#runId,
2101
+ snapshot
2102
+ });
2103
+ }
2104
+ const origSteps = input.steps;
2105
+ const isResumedInitialStep = this.#stepGraph?.initial[0]?.step?.id === stepId;
2106
+ if (isResumedInitialStep) {
2107
+ snapshot = void 0;
2108
+ input.steps = {};
2109
+ }
2110
+ this.logger.debug(`Machine input prepared`, {
2111
+ runId: this.#runId,
2112
+ input
2113
+ });
2114
+ const actorSnapshot = snapshot ? {
2115
+ ...snapshot,
2116
+ context: {
2117
+ ...input,
2118
+ inputData: {
2119
+ ...(snapshot?.context?.inputData || {}),
2120
+ ...resumeData
2121
+ },
2122
+ // ts-ignore is needed here because our snapshot types don't really match xstate snapshot types right now. We should fix this in general.
2123
+ // @ts-ignore
2124
+ isResume: {
2125
+ runId: snapshot?.context?.steps[stepId.split(".")?.[0]]?.output?.runId || this.#runId,
2126
+ stepId
2127
+ }
2128
+ }
2129
+ } : void 0;
2130
+ this.logger.debug(`Creating actor with configuration`, {
2131
+ input,
2132
+ actorSnapshot,
2133
+ runId: this.#runId,
2134
+ machineStates: this.#machine.config.states
2135
+ });
2136
+ this.#actor = xstate.createActor(this.#machine, {
2137
+ inspect: inspectionEvent => {
2138
+ this.logger.debug("XState inspection event", {
2139
+ type: inspectionEvent.type,
2140
+ event: inspectionEvent.event,
2141
+ runId: this.#runId
2142
+ });
2143
+ },
2144
+ input: {
2145
+ ...input,
2146
+ inputData: {
2147
+ ...(snapshot?.context?.inputData || {}),
2148
+ ...resumeData
2149
+ }
2150
+ },
2151
+ snapshot: actorSnapshot
2152
+ });
2153
+ this.#actor.start();
2154
+ if (stepId) {
2155
+ this.#actor.send({
2156
+ type: "RESET_TO_PENDING",
2157
+ stepId
2158
+ });
2159
+ }
2160
+ this.logger.debug("Actor started", {
2161
+ runId: this.#runId
2162
+ });
2163
+ return new Promise((resolve, reject) => {
2164
+ if (!this.#actor) {
2165
+ this.logger.error("Actor not initialized", {
2166
+ runId: this.#runId
2167
+ });
2168
+ const e = new Error("Actor not initialized");
2169
+ this.#executionSpan?.recordException(e);
2170
+ this.#executionSpan?.end();
2171
+ reject(e);
2172
+ return;
2173
+ }
2174
+ const suspendedPaths = /* @__PURE__ */new Set();
2175
+ this.#actor.subscribe(async state => {
2176
+ this.emit("state-update", this.#startStepId, state);
2177
+ getSuspendedPaths({
2178
+ value: state.value,
2179
+ path: "",
2180
+ suspendedPaths
2181
+ });
2182
+ const allStatesValue = state.value;
2183
+ const allStatesComplete = recursivelyCheckForFinalState({
2184
+ value: allStatesValue,
2185
+ suspendedPaths,
2186
+ path: ""
2187
+ });
2188
+ this.logger.debug("State completion check", {
2189
+ allStatesComplete,
2190
+ suspendedPaths: Array.from(suspendedPaths),
2191
+ runId: this.#runId
2192
+ });
2193
+ if (!allStatesComplete) {
2194
+ this.logger.debug("Not all states complete", {
2195
+ allStatesComplete,
2196
+ suspendedPaths: Array.from(suspendedPaths),
2197
+ runId: this.#runId
2198
+ });
2199
+ return;
2200
+ }
2201
+ try {
2202
+ this.logger.debug("All states complete", {
2203
+ runId: this.#runId
2204
+ });
2205
+ await this.#workflowInstance.persistWorkflowSnapshot();
2206
+ this.#cleanup();
2207
+ this.#executionSpan?.end();
2208
+ resolve({
2209
+ runId: this.#runId,
2210
+ results: isResumedInitialStep ? {
2211
+ ...origSteps,
2212
+ ...state.context.steps
2213
+ } : state.context.steps,
2214
+ activePaths: getResultActivePaths(state),
2215
+ timestamp: Date.now()
2216
+ });
2217
+ } catch (error) {
2218
+ this.logger.debug("Failed to persist final snapshot", {
2219
+ error
2220
+ });
2221
+ this.#cleanup();
2222
+ this.#executionSpan?.end();
2223
+ resolve({
2224
+ runId: this.#runId,
2225
+ results: isResumedInitialStep ? {
2226
+ ...origSteps,
2227
+ ...state.context.steps
2228
+ } : state.context.steps,
2229
+ activePaths: getResultActivePaths(state),
2230
+ timestamp: Date.now()
2231
+ });
2232
+ }
2233
+ });
2234
+ });
2235
+ }
2236
+ #cleanup() {
2237
+ if (this.#actor) {
2238
+ this.#actor.stop();
2239
+ this.#actor = null;
2240
+ }
2241
+ this.removeAllListeners();
2242
+ }
2243
+ #makeDelayMap() {
2244
+ const delayMap = {};
2245
+ Object.keys(this.#steps).forEach(stepId => {
2246
+ delayMap[stepId] = this.#steps[stepId]?.retryConfig?.delay || this.#retryConfig?.delay || 1e3;
2247
+ });
2248
+ return delayMap;
2249
+ }
2250
+ #getDefaultActions() {
2251
+ return {
2252
+ updateStepResult: xstate.assign({
2253
+ steps: ({
2254
+ context,
2255
+ event
2256
+ }) => {
2257
+ if (!isTransitionEvent(event)) return context.steps;
2258
+ const {
2259
+ stepId,
2260
+ result
2261
+ } = event.output;
2262
+ return {
2263
+ ...context.steps,
2264
+ [stepId]: {
2265
+ status: "success",
2266
+ output: result
2267
+ }
2268
+ };
2269
+ }
2270
+ }),
2271
+ setStepError: xstate.assign({
2272
+ steps: ({
2273
+ context,
2274
+ event
2275
+ }, params) => {
2276
+ if (!isErrorEvent(event)) return context.steps;
2277
+ const {
2278
+ stepId
2279
+ } = params;
2280
+ if (!stepId) return context.steps;
2281
+ return {
2282
+ ...context.steps,
2283
+ [stepId]: {
2284
+ status: "failed",
2285
+ error: event.error.message
2286
+ }
2287
+ };
2288
+ }
2289
+ }),
2290
+ notifyStepCompletion: async (_, params) => {
2291
+ const {
2292
+ stepId
2293
+ } = params;
2294
+ this.logger.debug(`Step ${stepId} completed`);
2295
+ },
2296
+ snapshotStep: xstate.assign({
2297
+ _snapshot: ({}, params) => {
2298
+ const {
2299
+ stepId
2300
+ } = params;
2301
+ return {
2302
+ stepId
2303
+ };
2304
+ }
2305
+ }),
2306
+ persistSnapshot: async ({
2307
+ context
2308
+ }) => {
2309
+ if (context._snapshot) {
2310
+ await this.#workflowInstance.persistWorkflowSnapshot();
2311
+ }
2312
+ return;
2313
+ },
2314
+ decrementAttemptCount: xstate.assign({
2315
+ attempts: ({
2316
+ context,
2317
+ event
2318
+ }, params) => {
2319
+ if (!isTransitionEvent(event)) return context.attempts;
2320
+ const {
2321
+ stepId
2322
+ } = params;
2323
+ const attemptCount = context.attempts[stepId];
2324
+ if (attemptCount === void 0) return context.attempts;
2325
+ return {
2326
+ ...context.attempts,
2327
+ [stepId]: attemptCount - 1
2328
+ };
2329
+ }
2330
+ })
2331
+ };
2332
+ }
2333
+ #getDefaultActors() {
2334
+ return {
2335
+ resolverFunction: xstate.fromPromise(async ({
2336
+ input
2337
+ }) => {
2338
+ const {
2339
+ stepNode,
2340
+ context
2341
+ } = input;
2342
+ const attemptCount = context.attempts[stepNode.step.id];
2343
+ const resolvedData = this.#resolveVariables({
2344
+ stepConfig: stepNode.config,
2345
+ context,
2346
+ stepId: stepNode.step.id
2347
+ });
2348
+ this.logger.debug(`Resolved variables for ${stepNode.step.id}`, {
2349
+ resolvedData,
2350
+ runId: this.#runId
2351
+ });
2352
+ const logger = this.logger;
2353
+ let mastraProxy = void 0;
2354
+ if (this.#mastra) {
2355
+ mastraProxy = chunk64VPB7ZD_cjs.createMastraProxy({
2356
+ mastra: this.#mastra,
2357
+ logger
2358
+ });
2359
+ }
2360
+ let result = void 0;
2361
+ try {
2362
+ result = await stepNode.config.handler({
2363
+ context: {
2364
+ ...context,
2365
+ inputData: {
2366
+ ...(context?.inputData || {}),
2367
+ ...resolvedData
2368
+ },
2369
+ getStepResult: stepId => {
2370
+ const resolvedStepId = typeof stepId === "string" ? stepId : stepId.id;
2371
+ if (resolvedStepId === "trigger") {
2372
+ return context.triggerData;
2373
+ }
2374
+ const result2 = context.steps[resolvedStepId];
2375
+ if (result2 && result2.status === "success") {
2376
+ return result2.output;
2377
+ }
2378
+ return void 0;
2379
+ }
2380
+ },
2381
+ emit: (event, ...args) => {
2382
+ this.emit(event, ...args);
2383
+ },
2384
+ suspend: async (payload, softSuspend) => {
2385
+ await this.#workflowInstance.suspend(stepNode.step.id, this);
2386
+ if (this.#actor) {
2387
+ context.steps[stepNode.step.id] = {
2388
+ status: "suspended",
2389
+ suspendPayload: payload,
2390
+ output: softSuspend
2391
+ };
2392
+ this.logger.debug(`Sending SUSPENDED event for step ${stepNode.step.id}`);
2393
+ this.#actor?.send({
2394
+ type: "SUSPENDED",
2395
+ suspendPayload: payload,
2396
+ stepId: stepNode.step.id,
2397
+ softSuspend
2398
+ });
2399
+ } else {
2400
+ this.logger.debug(`Actor not available for step ${stepNode.step.id}`);
2401
+ }
2402
+ },
2403
+ runId: this.#runId,
2404
+ mastra: mastraProxy
2405
+ });
2406
+ } catch (error) {
2407
+ this.logger.debug(`Step ${stepNode.step.id} failed`, {
2408
+ stepId: stepNode.step.id,
2409
+ error,
2410
+ runId: this.#runId
2411
+ });
2412
+ this.logger.debug(`Attempt count for step ${stepNode.step.id}`, {
2413
+ attemptCount,
2414
+ attempts: context.attempts,
2415
+ runId: this.#runId,
2416
+ stepId: stepNode.step.id
2417
+ });
2418
+ if (!attemptCount || attemptCount < 0) {
2419
+ return {
2420
+ type: "STEP_FAILED",
2421
+ error: error instanceof Error ? error.message : `Step:${stepNode.step.id} failed with error: ${error}`,
2422
+ stepId: stepNode.step.id
2423
+ };
2424
+ }
2425
+ return {
2426
+ type: "STEP_WAITING",
2427
+ stepId: stepNode.step.id
2428
+ };
2429
+ }
2430
+ this.logger.debug(`Step ${stepNode.step.id} result`, {
2431
+ stepId: stepNode.step.id,
2432
+ result,
2433
+ runId: this.#runId
2434
+ });
2435
+ return {
2436
+ type: "STEP_SUCCESS",
2437
+ result,
2438
+ stepId: stepNode.step.id
2439
+ };
2440
+ }),
2441
+ conditionCheck: xstate.fromPromise(async ({
2442
+ input
2443
+ }) => {
2444
+ const {
2445
+ context,
2446
+ stepNode
2447
+ } = input;
2448
+ const stepConfig = stepNode.config;
2449
+ this.logger.debug(`Checking conditions for step ${stepNode.step.id}`, {
2450
+ stepId: stepNode.step.id,
2451
+ runId: this.#runId
2452
+ });
2453
+ if (!stepConfig?.when) {
2454
+ return {
2455
+ type: "CONDITIONS_MET"
2456
+ };
2457
+ }
2458
+ this.logger.debug(`Checking conditions for step ${stepNode.step.id}`, {
2459
+ stepId: stepNode.step.id,
2460
+ runId: this.#runId
2461
+ });
2462
+ if (typeof stepConfig?.when === "function") {
2463
+ let conditionMet = await stepConfig.when({
2464
+ context: {
2465
+ ...context,
2466
+ getStepResult: stepId => {
2467
+ const resolvedStepId = typeof stepId === "string" ? stepId : stepId.id;
2468
+ if (resolvedStepId === "trigger") {
2469
+ return context.triggerData;
2470
+ }
2471
+ const result = context.steps[resolvedStepId];
2472
+ if (result && result.status === "success") {
2473
+ return result.output;
2474
+ }
2475
+ return void 0;
2476
+ }
2477
+ },
2478
+ mastra: this.#mastra
2479
+ });
2480
+ if (conditionMet === "abort" /* ABORT */) {
2481
+ conditionMet = false;
2482
+ } else if (conditionMet === "continue_failed" /* CONTINUE_FAILED */) {
2483
+ return {
2484
+ type: "CONDITIONS_SKIP_TO_COMPLETED"
2485
+ };
2486
+ } else if (conditionMet === "limbo" /* LIMBO */) {
2487
+ return {
2488
+ type: "CONDITIONS_LIMBO"
2489
+ };
2490
+ } else if (conditionMet) {
2491
+ this.logger.debug(`Condition met for step ${stepNode.step.id}`, {
2492
+ stepId: stepNode.step.id,
2493
+ runId: this.#runId
2494
+ });
2495
+ return {
2496
+ type: "CONDITIONS_MET"
2497
+ };
2498
+ }
2499
+ return this.#workflowInstance.hasSubscribers(stepNode.step.id) ? {
2500
+ type: "CONDITIONS_SKIPPED"
2501
+ } : {
2502
+ type: "CONDITIONS_LIMBO"
2503
+ };
2504
+ } else {
2505
+ const conditionMet = this.#evaluateCondition(stepConfig.when, context);
2506
+ if (!conditionMet) {
2507
+ return {
2508
+ type: "CONDITION_FAILED",
2509
+ error: `Step:${stepNode.step.id} condition check failed`
2510
+ };
2511
+ }
2512
+ }
2513
+ return {
2514
+ type: "CONDITIONS_MET"
2515
+ };
2516
+ }),
2517
+ spawnSubscriberFunction: xstate.fromPromise(async ({
2518
+ input
2519
+ }) => {
2520
+ const {
2521
+ parentStepId,
2522
+ context
2523
+ } = input;
2524
+ const result = await this.#workflowInstance.runMachine(parentStepId, context);
2525
+ return Promise.resolve({
2526
+ steps: result.reduce((acc, r) => {
2527
+ return {
2528
+ ...acc,
2529
+ ...r?.results
2530
+ };
2531
+ }, {})
2532
+ });
2533
+ })
2534
+ };
2535
+ }
2536
+ #resolveVariables({
2537
+ stepConfig,
2538
+ context,
2539
+ stepId
2540
+ }) {
2541
+ this.logger.debug(`Resolving variables for step ${stepId}`, {
2542
+ stepId,
2543
+ runId: this.#runId
2544
+ });
2545
+ const resolvedData = {};
2546
+ for (const [key, variable] of Object.entries(stepConfig.data)) {
2547
+ const sourceData = variable.step === "trigger" ? context.triggerData : getStepResult(context.steps[variable.step.id]);
2548
+ this.logger.debug(`Got source data for ${key} variable from ${variable.step === "trigger" ? "trigger" : variable.step.id}`, {
2549
+ sourceData,
2550
+ path: variable.path,
2551
+ runId: this.#runId
2552
+ });
2553
+ if (!sourceData && variable.step !== "trigger") {
2554
+ resolvedData[key] = void 0;
2555
+ continue;
2556
+ }
2557
+ const value = variable.path === "" || variable.path === "." ? sourceData : radash.get(sourceData, variable.path);
2558
+ this.logger.debug(`Resolved variable ${key}`, {
2559
+ value,
2560
+ runId: this.#runId
2561
+ });
2562
+ resolvedData[key] = value;
2563
+ }
2564
+ return resolvedData;
2565
+ }
2566
+ initializeMachine() {
2567
+ const machine = xstate.setup({
2568
+ types: {},
2569
+ delays: this.#makeDelayMap(),
2570
+ actions: this.#getDefaultActions(),
2571
+ actors: this.#getDefaultActors()
2572
+ }).createMachine({
2573
+ id: this.name,
2574
+ type: "parallel",
2575
+ context: ({
2576
+ input
2577
+ }) => ({
2578
+ ...input
2579
+ }),
2580
+ states: this.#buildStateHierarchy(this.#stepGraph)
2581
+ });
2582
+ this.#machine = machine;
2583
+ return machine;
2584
+ }
2585
+ #buildStateHierarchy(stepGraph) {
2586
+ const states = {};
2587
+ stepGraph.initial.forEach(stepNode => {
2588
+ const nextSteps = [...(stepGraph[stepNode.step.id] || [])];
2589
+ states[stepNode.step.id] = {
2590
+ ...this.#buildBaseState(stepNode, nextSteps)
2591
+ };
2592
+ });
2593
+ return states;
2594
+ }
2595
+ #buildBaseState(stepNode, nextSteps = []) {
2596
+ const nextStep = nextSteps.shift();
2597
+ return {
2598
+ initial: "pending",
2599
+ on: {
2600
+ RESET_TO_PENDING: {
2601
+ target: ".pending"
2602
+ // Note the dot to target child state
2603
+ }
2604
+ },
2605
+ states: {
2606
+ pending: {
2607
+ entry: () => {
2608
+ this.logger.debug(`Step ${stepNode.step.id} pending`, {
2609
+ stepId: stepNode.step.id,
2610
+ runId: this.#runId
2611
+ });
2612
+ },
2613
+ exit: () => {
2614
+ this.logger.debug(`Step ${stepNode.step.id} finished pending`, {
2615
+ stepId: stepNode.step.id,
2616
+ runId: this.#runId
2617
+ });
2618
+ },
2619
+ invoke: {
2620
+ src: "conditionCheck",
2621
+ input: ({
2622
+ context
2623
+ }) => {
2624
+ return {
2625
+ context,
2626
+ stepNode
2627
+ };
2628
+ },
2629
+ onDone: [{
2630
+ guard: ({
2631
+ event
2632
+ }) => {
2633
+ return event.output.type === "SUSPENDED";
2634
+ },
2635
+ target: "suspended",
2636
+ actions: [xstate.assign({
2637
+ steps: ({
2638
+ context,
2639
+ event
2640
+ }) => {
2641
+ if (event.output.type !== "SUSPENDED") return context.steps;
2642
+ if (event.output.softSuspend) {
2643
+ return {
2644
+ ...context.steps,
2645
+ [stepNode.step.id]: {
2646
+ status: "suspended",
2647
+ ...(context.steps?.[stepNode.step.id] || {}),
2648
+ output: event.output.softSuspend
2649
+ }
2650
+ };
2651
+ }
2652
+ return {
2653
+ ...context.steps,
2654
+ [stepNode.step.id]: {
2655
+ status: "suspended",
2656
+ ...(context.steps?.[stepNode.step.id] || {})
2657
+ }
2658
+ };
2659
+ },
2660
+ attempts: ({
2661
+ context,
2662
+ event
2663
+ }) => {
2664
+ if (event.output.type !== "SUSPENDED") return context.attempts;
2665
+ return {
2666
+ ...context.attempts,
2667
+ [stepNode.step.id]: stepNode.step.retryConfig?.attempts || 0
2668
+ };
2669
+ }
2670
+ })]
2671
+ }, {
2672
+ guard: ({
2673
+ event
2674
+ }) => {
2675
+ return event.output.type === "WAITING";
2676
+ },
2677
+ target: "waiting",
2678
+ actions: [{
2679
+ type: "decrementAttemptCount",
2680
+ params: {
2681
+ stepId: stepNode.step.id
2682
+ }
2683
+ }, xstate.assign({
2684
+ steps: ({
2685
+ context,
2686
+ event
2687
+ }) => {
2688
+ if (event.output.type !== "WAITING") return context.steps;
2689
+ return {
2690
+ ...context.steps,
2691
+ [stepNode.step.id]: {
2692
+ status: "waiting"
2693
+ }
2694
+ };
2695
+ }
2696
+ })]
2697
+ }, {
2698
+ guard: ({
2699
+ event
2700
+ }) => {
2701
+ return event.output.type === "CONDITIONS_MET";
2702
+ },
2703
+ target: "executing"
2704
+ }, {
2705
+ guard: ({
2706
+ event
2707
+ }) => {
2708
+ return event.output.type === "CONDITIONS_SKIP_TO_COMPLETED";
2709
+ },
2710
+ target: "completed"
2711
+ }, {
2712
+ guard: ({
2713
+ event
2714
+ }) => {
2715
+ return event.output.type === "CONDITIONS_SKIPPED";
2716
+ },
2717
+ actions: xstate.assign({
2718
+ steps: ({
2719
+ context
2720
+ }) => {
2721
+ const newStep = {
2722
+ ...context.steps,
2723
+ [stepNode.step.id]: {
2724
+ status: "skipped"
2725
+ }
2726
+ };
2727
+ this.logger.debug(`Step ${stepNode.step.id} skipped`, {
2728
+ stepId: stepNode.step.id,
2729
+ runId: this.#runId
2730
+ });
2731
+ return newStep;
2732
+ }
2733
+ }),
2734
+ target: "runningSubscribers"
2735
+ }, {
2736
+ guard: ({
2737
+ event
2738
+ }) => {
2739
+ return event.output.type === "CONDITIONS_LIMBO";
2740
+ },
2741
+ target: "limbo",
2742
+ actions: xstate.assign({
2743
+ steps: ({
2744
+ context
2745
+ }) => {
2746
+ const newStep = {
2747
+ ...context.steps,
2748
+ [stepNode.step.id]: {
2749
+ status: "skipped"
2750
+ }
2751
+ };
2752
+ this.logger.debug(`Step ${stepNode.step.id} skipped`, {
2753
+ stepId: stepNode.step.id,
2754
+ runId: this.#runId
2755
+ });
2756
+ return newStep;
2757
+ }
2758
+ })
2759
+ }, {
2760
+ guard: ({
2761
+ event
2762
+ }) => {
2763
+ return event.output.type === "CONDITION_FAILED";
2764
+ },
2765
+ target: "failed",
2766
+ actions: xstate.assign({
2767
+ steps: ({
2768
+ context,
2769
+ event
2770
+ }) => {
2771
+ if (event.output.type !== "CONDITION_FAILED") return context.steps;
2772
+ this.logger.debug(`Workflow condition check failed`, {
2773
+ error: event.output.error,
2774
+ stepId: stepNode.step.id
2775
+ });
2776
+ return {
2777
+ ...context.steps,
2778
+ [stepNode.step.id]: {
2779
+ status: "failed",
2780
+ error: event.output.error
2781
+ }
2782
+ };
2783
+ }
2784
+ })
2785
+ }]
2786
+ }
2787
+ },
2788
+ waiting: {
2789
+ entry: () => {
2790
+ this.logger.debug(`Step ${stepNode.step.id} waiting`, {
2791
+ stepId: stepNode.step.id,
2792
+ timestamp: (/* @__PURE__ */new Date()).toISOString(),
2793
+ runId: this.#runId
2794
+ });
2795
+ },
2796
+ exit: () => {
2797
+ this.logger.debug(`Step ${stepNode.step.id} finished waiting`, {
2798
+ stepId: stepNode.step.id,
2799
+ timestamp: (/* @__PURE__ */new Date()).toISOString(),
2800
+ runId: this.#runId
2801
+ });
2802
+ },
2803
+ after: {
2804
+ [stepNode.step.id]: {
2805
+ target: "pending"
2806
+ }
2807
+ }
2808
+ },
2809
+ limbo: {
2810
+ // no target, will stay in limbo indefinitely
2811
+ entry: () => {
2812
+ this.logger.debug(`Step ${stepNode.step.id} limbo`, {
2813
+ stepId: stepNode.step.id,
2814
+ timestamp: (/* @__PURE__ */new Date()).toISOString(),
2815
+ runId: this.#runId
2816
+ });
2817
+ },
2818
+ exit: () => {
2819
+ this.logger.debug(`Step ${stepNode.step.id} finished limbo`, {
2820
+ stepId: stepNode.step.id,
2821
+ timestamp: (/* @__PURE__ */new Date()).toISOString(),
2822
+ runId: this.#runId
2823
+ });
2824
+ }
2825
+ },
2826
+ suspended: {
2827
+ type: "final",
2828
+ entry: [() => {
2829
+ this.logger.debug(`Step ${stepNode.step.id} suspended`, {
2830
+ stepId: stepNode.step.id,
2831
+ runId: this.#runId
2832
+ });
2833
+ }, xstate.assign({
2834
+ steps: ({
2835
+ context,
2836
+ event
2837
+ }) => {
2838
+ return {
2839
+ ...context.steps,
2840
+ [stepNode.step.id]: {
2841
+ ...(context?.steps?.[stepNode.step.id] || {}),
2842
+ status: "suspended",
2843
+ suspendPayload: event.type === "SUSPENDED" ? event.suspendPayload : void 0,
2844
+ output: event.type === "SUSPENDED" ? event.softSuspend : void 0
2845
+ }
2846
+ };
2847
+ }
2848
+ })]
2849
+ },
2850
+ executing: {
2851
+ entry: () => {
2852
+ this.logger.debug(`Step ${stepNode.step.id} executing`, {
2853
+ stepId: stepNode.step.id,
2854
+ runId: this.#runId
2855
+ });
2856
+ },
2857
+ on: {
2858
+ SUSPENDED: {
2859
+ target: "suspended",
2860
+ actions: [xstate.assign({
2861
+ steps: ({
2862
+ context,
2863
+ event
2864
+ }) => {
2865
+ return {
2866
+ ...context.steps,
2867
+ [stepNode.step.id]: {
2868
+ status: "suspended",
2869
+ suspendPayload: event.type === "SUSPENDED" ? event.suspendPayload : void 0,
2870
+ output: event.type === "SUSPENDED" ? event.softSuspend : void 0
2871
+ }
2872
+ };
2873
+ }
2874
+ })]
2875
+ }
2876
+ },
2877
+ invoke: {
2878
+ src: "resolverFunction",
2879
+ input: ({
2880
+ context
2881
+ }) => ({
2882
+ context,
2883
+ stepNode
2884
+ }),
2885
+ onDone: [{
2886
+ guard: ({
2887
+ event
2888
+ }) => {
2889
+ return event.output.type === "STEP_FAILED";
2890
+ },
2891
+ target: "failed",
2892
+ actions: xstate.assign({
2893
+ steps: ({
2894
+ context,
2895
+ event
2896
+ }) => {
2897
+ if (event.output.type !== "STEP_FAILED") return context.steps;
2898
+ const newStep = {
2899
+ ...context.steps,
2900
+ [stepNode.step.id]: {
2901
+ status: "failed",
2902
+ error: event.output.error
2903
+ }
2904
+ };
2905
+ this.logger.debug(`Step ${stepNode.step.id} failed`, {
2906
+ error: event.output.error,
2907
+ stepId: stepNode.step.id
2908
+ });
2909
+ return newStep;
2910
+ }
2911
+ })
2912
+ }, {
2913
+ guard: ({
2914
+ event
2915
+ }) => {
2916
+ return event.output.type === "STEP_SUCCESS";
2917
+ },
2918
+ actions: [({
2919
+ event
2920
+ }) => {
2921
+ this.logger.debug(`Step ${stepNode.step.id} finished executing`, {
2922
+ stepId: stepNode.step.id,
2923
+ output: event.output,
2924
+ runId: this.#runId
2925
+ });
2926
+ }, {
2927
+ type: "updateStepResult",
2928
+ params: {
2929
+ stepId: stepNode.step.id
2930
+ }
2931
+ }, {
2932
+ type: "spawnSubscribers",
2933
+ params: {
2934
+ stepId: stepNode.step.id
2935
+ }
2936
+ }],
2937
+ target: "runningSubscribers"
2938
+ }, {
2939
+ guard: ({
2940
+ event
2941
+ }) => {
2942
+ return event.output.type === "STEP_WAITING";
2943
+ },
2944
+ target: "waiting",
2945
+ actions: [{
2946
+ type: "decrementAttemptCount",
2947
+ params: {
2948
+ stepId: stepNode.step.id
2949
+ }
2950
+ }, xstate.assign({
2951
+ steps: ({
2952
+ context,
2953
+ event
2954
+ }) => {
2955
+ if (event.output.type !== "STEP_WAITING") return context.steps;
2956
+ return {
2957
+ ...context.steps,
2958
+ [stepNode.step.id]: {
2959
+ status: "waiting"
2960
+ }
2961
+ };
2962
+ }
2963
+ })]
2964
+ }],
2965
+ onError: {
2966
+ target: "failed",
2967
+ actions: [{
2968
+ type: "setStepError",
2969
+ params: {
2970
+ stepId: stepNode.step.id
2971
+ }
2972
+ }]
2973
+ }
2974
+ }
2975
+ },
2976
+ runningSubscribers: {
2977
+ entry: () => {
2978
+ this.logger.debug(`Step ${stepNode.step.id} running subscribers`, {
2979
+ stepId: stepNode.step.id,
2980
+ runId: this.#runId
2981
+ });
2982
+ },
2983
+ exit: () => {
2984
+ this.logger.debug(`Step ${stepNode.step.id} finished running subscribers`, {
2985
+ stepId: stepNode.step.id,
2986
+ runId: this.#runId
2987
+ });
2988
+ },
2989
+ invoke: {
2990
+ src: "spawnSubscriberFunction",
2991
+ input: ({
2992
+ context
2993
+ }) => ({
2994
+ parentStepId: stepNode.step.id,
2995
+ context
2996
+ }),
2997
+ onDone: {
2998
+ target: nextStep ? nextStep.step.id : "completed",
2999
+ actions: [xstate.assign({
3000
+ steps: ({
3001
+ context,
3002
+ event
3003
+ }) => ({
3004
+ ...context.steps,
3005
+ ...event.output.steps
3006
+ })
3007
+ }), () => this.logger.debug(`Subscriber execution completed`, {
3008
+ stepId: stepNode.step.id
3009
+ })]
3010
+ },
3011
+ onError: {
3012
+ target: nextStep ? nextStep.step.id : "completed",
3013
+ actions: ({
3014
+ event
3015
+ }) => {
3016
+ this.logger.debug(`Subscriber execution failed`, {
3017
+ error: event.error,
3018
+ stepId: stepNode.step.id
3019
+ });
3020
+ }
3021
+ }
3022
+ }
3023
+ },
3024
+ completed: {
3025
+ type: "final",
3026
+ entry: [{
3027
+ type: "notifyStepCompletion",
3028
+ params: {
3029
+ stepId: stepNode.step.id
3030
+ }
3031
+ }, {
3032
+ type: "snapshotStep",
3033
+ params: {
3034
+ stepId: stepNode.step.id
3035
+ }
3036
+ }, {
3037
+ type: "persistSnapshot"
3038
+ }]
3039
+ },
3040
+ failed: {
3041
+ type: "final",
3042
+ entry: [{
3043
+ type: "notifyStepCompletion",
3044
+ params: {
3045
+ stepId: stepNode.step.id
3046
+ }
3047
+ }, {
3048
+ type: "snapshotStep",
3049
+ params: {
3050
+ stepId: stepNode.step.id
3051
+ }
3052
+ }, {
3053
+ type: "persistSnapshot"
3054
+ }]
3055
+ },
3056
+ // build chain of next steps recursively
3057
+ ...(nextStep ? {
3058
+ [nextStep.step.id]: {
3059
+ ...this.#buildBaseState(nextStep, nextSteps)
3060
+ }
3061
+ } : {})
3062
+ }
3063
+ };
3064
+ }
3065
+ #evaluateCondition(condition, context) {
3066
+ let andBranchResult = true;
3067
+ let baseResult = true;
3068
+ let orBranchResult = true;
3069
+ const simpleCondition = Object.entries(condition).find(([key]) => key.includes("."));
3070
+ if (simpleCondition) {
3071
+ const [key, queryValue] = simpleCondition;
3072
+ const [stepId, ...pathParts] = key.split(".");
3073
+ const path = pathParts.join(".");
3074
+ const sourceData = stepId === "trigger" ? context.triggerData : getStepResult(context.steps[stepId]);
3075
+ this.logger.debug(`Got condition data from step ${stepId}`, {
3076
+ stepId,
3077
+ sourceData,
3078
+ runId: this.#runId
3079
+ });
3080
+ if (!sourceData) {
3081
+ return false;
3082
+ }
3083
+ let value = radash.get(sourceData, path);
3084
+ if (stepId !== "trigger" && path === "status" && !value) {
3085
+ value = "success";
3086
+ }
3087
+ if (typeof queryValue === "object" && queryValue !== null) {
3088
+ baseResult = sift__default.default(queryValue)(value);
3089
+ } else {
3090
+ baseResult = value === queryValue;
3091
+ }
3092
+ }
3093
+ if ("ref" in condition) {
3094
+ const {
3095
+ ref,
3096
+ query
3097
+ } = condition;
3098
+ const sourceData = ref.step === "trigger" ? context.triggerData : getStepResult(context.steps[ref.step.id]);
3099
+ this.logger.debug(`Got condition data from ${ref.step === "trigger" ? "trigger" : ref.step.id}`, {
3100
+ sourceData,
3101
+ runId: this.#runId
3102
+ });
3103
+ if (!sourceData) {
3104
+ return false;
3105
+ }
3106
+ let value = radash.get(sourceData, ref.path);
3107
+ if (ref.step !== "trigger" && ref.path === "status" && !value) {
3108
+ value = "success";
3109
+ }
3110
+ baseResult = sift__default.default(query)(value);
3111
+ }
3112
+ if ("and" in condition) {
3113
+ andBranchResult = condition.and.every(cond => this.#evaluateCondition(cond, context));
3114
+ this.logger.debug(`Evaluated AND condition`, {
3115
+ andBranchResult,
3116
+ runId: this.#runId
3117
+ });
3118
+ }
3119
+ if ("or" in condition) {
3120
+ orBranchResult = condition.or.some(cond => this.#evaluateCondition(cond, context));
3121
+ this.logger.debug(`Evaluated OR condition`, {
3122
+ orBranchResult,
3123
+ runId: this.#runId
3124
+ });
3125
+ }
3126
+ if ("not" in condition) {
3127
+ baseResult = !this.#evaluateCondition(condition.not, context);
3128
+ this.logger.debug(`Evaluated NOT condition`, {
3129
+ baseResult,
3130
+ runId: this.#runId
3131
+ });
3132
+ }
3133
+ const finalResult = baseResult && andBranchResult && orBranchResult;
3134
+ this.logger.debug(`Evaluated condition`, {
3135
+ finalResult,
3136
+ runId: this.#runId
3137
+ });
3138
+ return finalResult;
3139
+ }
3140
+ getSnapshot() {
3141
+ const snapshot = this.#actor?.getSnapshot();
3142
+ return snapshot;
3143
+ }
3144
+ };
3145
+
3146
+ // src/workflows/workflow-instance.ts
3147
+ var WorkflowInstance = class {
3148
+ name;
3149
+ #mastra;
3150
+ #machines = {};
3151
+ logger;
3152
+ #steps = {};
3153
+ #stepGraph;
3154
+ #stepSubscriberGraph = {};
3155
+ #retryConfig;
3156
+ events;
3157
+ #runId;
3158
+ #state = null;
3159
+ #executionSpan;
3160
+ #onStepTransition = /* @__PURE__ */new Set();
3161
+ #onFinish;
3162
+ #resultMapping;
3163
+ // indexed by stepId
3164
+ #suspendedMachines = {};
3165
+ // {step1&&step2: {step1: true, step2: true}}
3166
+ #compoundDependencies = {};
3167
+ constructor({
3168
+ name,
3169
+ logger,
3170
+ steps,
3171
+ runId,
3172
+ retryConfig,
3173
+ mastra,
3174
+ stepGraph,
3175
+ stepSubscriberGraph,
3176
+ onFinish,
3177
+ onStepTransition,
3178
+ resultMapping,
3179
+ events
3180
+ }) {
3181
+ this.name = name;
3182
+ this.logger = logger;
3183
+ this.#steps = steps;
3184
+ this.#stepGraph = stepGraph;
3185
+ this.#stepSubscriberGraph = stepSubscriberGraph;
3186
+ this.#retryConfig = retryConfig;
3187
+ this.#mastra = mastra;
3188
+ this.#runId = runId ?? crypto.randomUUID();
3189
+ this.#onFinish = onFinish;
3190
+ this.#resultMapping = resultMapping;
3191
+ this.events = events;
3192
+ onStepTransition?.forEach(handler => this.#onStepTransition.add(handler));
3193
+ this.#initializeCompoundDependencies();
3194
+ }
3195
+ setState(state) {
3196
+ this.#state = state;
3197
+ }
3198
+ get runId() {
3199
+ return this.#runId;
3200
+ }
3201
+ get executionSpan() {
3202
+ return this.#executionSpan;
3203
+ }
3204
+ watch(onTransition) {
3205
+ this.#onStepTransition.add(onTransition);
3206
+ return () => {
3207
+ this.#onStepTransition.delete(onTransition);
3208
+ };
3209
+ }
3210
+ async start({
3211
+ triggerData
3212
+ } = {}) {
3213
+ const results = await this.execute({
3214
+ triggerData
3215
+ });
3216
+ if (this.#onFinish) {
3217
+ this.#onFinish();
3218
+ }
3219
+ return {
3220
+ ...results,
3221
+ runId: this.runId
3222
+ };
3223
+ }
3224
+ isCompoundDependencyMet(stepKey) {
3225
+ if (!this.#isCompoundKey(stepKey)) return true;
3226
+ const dependencies = this.#compoundDependencies[stepKey];
3227
+ return dependencies ? Object.values(dependencies).every(status => status === true) : true;
3228
+ }
3229
+ async execute({
3230
+ triggerData,
3231
+ snapshot,
3232
+ stepId,
3233
+ resumeData
3234
+ } = {}) {
3235
+ this.#executionSpan = this.#mastra?.getTelemetry()?.tracer.startSpan(`workflow.${this.name}.execute`, {
3236
+ attributes: {
3237
+ componentName: this.name,
3238
+ runId: this.runId
3239
+ }
3240
+ });
3241
+ let machineInput = {
3242
+ // Maintain the original step results and their output
3243
+ steps: {},
3244
+ triggerData: triggerData || {},
3245
+ attempts: Object.keys(this.#steps).reduce((acc, stepKey) => {
3246
+ acc[stepKey] = this.#steps[stepKey]?.retryConfig?.attempts || this.#retryConfig?.attempts || 0;
3247
+ return acc;
3248
+ }, {})
3249
+ };
3250
+ let stepGraph = this.#stepGraph;
3251
+ let startStepId = "trigger";
3252
+ if (snapshot) {
3253
+ const runState = snapshot;
3254
+ if (stepId && runState?.suspendedSteps?.[stepId]) {
3255
+ startStepId = runState.suspendedSteps[stepId];
3256
+ stepGraph = this.#stepSubscriberGraph[startStepId] ?? this.#stepGraph;
3257
+ machineInput = runState.context;
3258
+ }
3259
+ }
3260
+ const defaultMachine = new Machine({
3261
+ logger: this.logger,
3262
+ mastra: this.#mastra,
3263
+ workflowInstance: this,
3264
+ name: this.name,
3265
+ runId: this.runId,
3266
+ steps: this.#steps,
3267
+ stepGraph,
3268
+ executionSpan: this.#executionSpan,
3269
+ startStepId,
3270
+ retryConfig: this.#retryConfig
3271
+ });
3272
+ this.#machines[startStepId] = defaultMachine;
3273
+ const stateUpdateHandler = (startStepId2, state, ctx) => {
3274
+ let fullState = {
3275
+ value: {},
3276
+ context: {}
3277
+ };
3278
+ if (ctx) {
3279
+ fullState["value"] = state;
3280
+ fullState["context"] = ctx;
3281
+ } else {
3282
+ fullState = state;
3283
+ }
3284
+ if (startStepId2 === "trigger") {
3285
+ this.#state = fullState.value;
3286
+ } else {
3287
+ this.#state = mergeChildValue(startStepId2, this.#state, fullState.value);
3288
+ }
3289
+ const now = Date.now();
3290
+ if (this.#onStepTransition) {
3291
+ this.#onStepTransition.forEach(onTransition => {
3292
+ void onTransition({
3293
+ runId: this.#runId,
3294
+ results: fullState.context.steps,
3295
+ activePaths: getResultActivePaths(fullState),
3296
+ timestamp: now
3297
+ });
3298
+ });
3299
+ }
3300
+ };
3301
+ defaultMachine.on("state-update", stateUpdateHandler);
3302
+ const {
3303
+ results,
3304
+ activePaths
3305
+ } = await defaultMachine.execute({
3306
+ snapshot,
3307
+ stepId,
3308
+ input: machineInput,
3309
+ resumeData
3310
+ });
3311
+ await this.persistWorkflowSnapshot();
3312
+ const result = {
3313
+ results,
3314
+ activePaths,
3315
+ timestamp: Date.now()
3316
+ };
3317
+ if (this.#resultMapping) {
3318
+ result.result = resolveVariables({
3319
+ runId: this.#runId,
3320
+ logger: this.logger,
3321
+ variables: this.#resultMapping,
3322
+ context: {
3323
+ steps: results,
3324
+ triggerData}
3325
+ });
3326
+ }
3327
+ return result;
3328
+ }
3329
+ hasSubscribers(stepId) {
3330
+ return Object.keys(this.#stepSubscriberGraph).some(key => key.split("&&").includes(stepId));
3331
+ }
3332
+ async runMachine(parentStepId, input) {
3333
+ const stepStatus = input.steps[parentStepId]?.status;
3334
+ const subscriberKeys = Object.keys(this.#stepSubscriberGraph).filter(key => key.split("&&").includes(parentStepId));
3335
+ subscriberKeys.forEach(key => {
3336
+ if (["success", "failure", "skipped"].includes(stepStatus) && this.#isCompoundKey(key)) {
3337
+ this.#compoundDependencies[key][parentStepId] = true;
3338
+ }
3339
+ });
3340
+ const stateUpdateHandler = (startStepId, state, ctx) => {
3341
+ let fullState = {
3342
+ value: {},
3343
+ context: {}
3344
+ };
3345
+ if (ctx) {
3346
+ fullState["value"] = state;
3347
+ fullState["context"] = ctx;
3348
+ } else {
3349
+ fullState = state;
3350
+ }
3351
+ if (startStepId === "trigger") {
3352
+ this.#state = fullState.value;
3353
+ } else {
3354
+ this.#state = mergeChildValue(startStepId, this.#state, fullState.value);
3355
+ }
3356
+ const now = Date.now();
3357
+ if (this.#onStepTransition) {
3358
+ this.#onStepTransition.forEach(onTransition => {
3359
+ void onTransition({
3360
+ runId: this.#runId,
3361
+ results: fullState.context.steps,
3362
+ activePaths: getResultActivePaths(fullState),
3363
+ timestamp: now
3364
+ });
3365
+ });
3366
+ }
3367
+ };
3368
+ const results = await Promise.all(subscriberKeys.map(async key => {
3369
+ if (!this.#stepSubscriberGraph[key] || !this.isCompoundDependencyMet(key)) {
3370
+ return;
3371
+ }
3372
+ this.#initializeCompoundDependencies();
3373
+ const machine = new Machine({
3374
+ logger: this.logger,
3375
+ mastra: this.#mastra,
3376
+ workflowInstance: this,
3377
+ name: parentStepId === "trigger" ? this.name : `${this.name}-${parentStepId}`,
3378
+ runId: this.runId,
3379
+ steps: this.#steps,
3380
+ stepGraph: this.#stepSubscriberGraph[key],
3381
+ executionSpan: this.#executionSpan,
3382
+ startStepId: parentStepId
3383
+ });
3384
+ machine.on("state-update", stateUpdateHandler);
3385
+ this.#machines[parentStepId] = machine;
3386
+ return machine.execute({
3387
+ input
3388
+ });
3389
+ }));
3390
+ return results;
3391
+ }
3392
+ async suspend(stepId, machine) {
3393
+ this.#suspendedMachines[stepId] = machine;
3394
+ }
3395
+ /**
3396
+ * Persists the workflow state to the database
3397
+ */
3398
+ async persistWorkflowSnapshot() {
3399
+ const storage = this.#mastra?.getStorage();
3400
+ if (!storage) {
3401
+ this.logger.debug("Snapshot cannot be persisted. Mastra engine is not initialized", {
3402
+ runId: this.#runId
3403
+ });
3404
+ return;
3405
+ }
3406
+ const existingSnapshot = await storage.loadWorkflowSnapshot({
3407
+ workflowName: this.name,
3408
+ runId: this.#runId
3409
+ });
3410
+ const machineSnapshots = {};
3411
+ for (const [stepId, machine] of Object.entries(this.#machines)) {
3412
+ const machineSnapshot = machine?.getSnapshot();
3413
+ if (machineSnapshot) {
3414
+ machineSnapshots[stepId] = {
3415
+ ...machineSnapshot
3416
+ };
3417
+ }
3418
+ }
3419
+ let snapshot = machineSnapshots["trigger"];
3420
+ delete machineSnapshots["trigger"];
3421
+ const suspendedSteps = Object.entries(this.#suspendedMachines).reduce((acc, [stepId, machine]) => {
3422
+ acc[stepId] = machine.startStepId;
3423
+ return acc;
3424
+ }, {});
3425
+ if (!snapshot && existingSnapshot) {
3426
+ existingSnapshot.childStates = {
3427
+ ...existingSnapshot.childStates,
3428
+ ...machineSnapshots
3429
+ };
3430
+ existingSnapshot.suspendedSteps = {
3431
+ ...existingSnapshot.suspendedSteps,
3432
+ ...suspendedSteps
3433
+ };
3434
+ await storage.persistWorkflowSnapshot({
3435
+ workflowName: this.name,
3436
+ runId: this.#runId,
3437
+ snapshot: existingSnapshot
3438
+ });
3439
+ return;
3440
+ } else if (snapshot && !existingSnapshot) {
3441
+ snapshot.suspendedSteps = suspendedSteps;
3442
+ snapshot.childStates = {
3443
+ ...machineSnapshots
3444
+ };
3445
+ await storage.persistWorkflowSnapshot({
3446
+ workflowName: this.name,
3447
+ runId: this.#runId,
3448
+ snapshot
3449
+ });
3450
+ return;
3451
+ } else if (!snapshot) {
3452
+ this.logger.debug("Snapshot cannot be persisted. No snapshot received.", {
3453
+ runId: this.#runId
3454
+ });
3455
+ return;
3456
+ }
3457
+ snapshot.suspendedSteps = {
3458
+ ...existingSnapshot.suspendedSteps,
3459
+ ...suspendedSteps
3460
+ };
3461
+ if (!existingSnapshot || snapshot === existingSnapshot) {
3462
+ await storage.persistWorkflowSnapshot({
3463
+ workflowName: this.name,
3464
+ runId: this.#runId,
3465
+ snapshot
3466
+ });
3467
+ return;
3468
+ }
3469
+ if (existingSnapshot?.childStates) {
3470
+ snapshot.childStates = {
3471
+ ...existingSnapshot.childStates,
3472
+ ...machineSnapshots
3473
+ };
3474
+ } else {
3475
+ snapshot.childStates = machineSnapshots;
3476
+ }
3477
+ await storage.persistWorkflowSnapshot({
3478
+ workflowName: this.name,
3479
+ runId: this.#runId,
3480
+ snapshot
3481
+ });
3482
+ }
3483
+ async getState() {
3484
+ const storedSnapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
3485
+ workflowName: this.name,
3486
+ runId: this.runId
3487
+ });
3488
+ const prevSnapshot = storedSnapshot ? {
3489
+ trigger: storedSnapshot,
3490
+ ...Object.entries(storedSnapshot?.childStates ?? {}).reduce((acc, [stepId, snapshot2]) => ({
3491
+ ...acc,
3492
+ [stepId]: snapshot2
3493
+ }), {})
3494
+ } : {};
3495
+ const currentSnapshot = Object.entries(this.#machines).reduce((acc, [stepId, machine]) => {
3496
+ const snapshot2 = machine.getSnapshot();
3497
+ if (!snapshot2) {
3498
+ return acc;
3499
+ }
3500
+ return {
3501
+ ...acc,
3502
+ [stepId]: snapshot2
3503
+ };
3504
+ }, {});
3505
+ Object.assign(prevSnapshot, currentSnapshot);
3506
+ const trigger = prevSnapshot.trigger;
3507
+ delete prevSnapshot.trigger;
3508
+ const snapshot = {
3509
+ ...trigger};
3510
+ const m = getActivePathsAndStatus(prevSnapshot.value);
3511
+ return {
3512
+ runId: this.runId,
3513
+ value: snapshot.value,
3514
+ context: snapshot.context,
3515
+ activePaths: m,
3516
+ timestamp: Date.now()
3517
+ };
3518
+ }
3519
+ async resumeWithEvent(eventName, data) {
3520
+ const event = this.events?.[eventName];
3521
+ if (!event) {
3522
+ throw new Error(`Event ${eventName} not found`);
3523
+ }
3524
+ const results = await this.resume({
3525
+ stepId: `__${eventName}_event`,
3526
+ context: {
3527
+ resumedEvent: data
3528
+ }
3529
+ });
3530
+ return results;
3531
+ }
3532
+ async resume({
3533
+ stepId,
3534
+ context: resumeContext
3535
+ }) {
3536
+ await new Promise(resolve => setTimeout(resolve, 0));
3537
+ return this._resume({
3538
+ stepId,
3539
+ context: resumeContext
3540
+ });
3541
+ }
3542
+ async #loadWorkflowSnapshot(runId) {
3543
+ const storage = this.#mastra?.getStorage();
3544
+ if (!storage) {
3545
+ this.logger.debug("Snapshot cannot be loaded. Mastra engine is not initialized", {
3546
+ runId
3547
+ });
3548
+ return;
3549
+ }
3550
+ await this.persistWorkflowSnapshot();
3551
+ return storage.loadWorkflowSnapshot({
3552
+ runId,
3553
+ workflowName: this.name
3554
+ });
3555
+ }
3556
+ async _resume({
3557
+ stepId,
3558
+ context: resumeContext
3559
+ }) {
3560
+ const snapshot = await this.#loadWorkflowSnapshot(this.runId);
3561
+ if (!snapshot) {
3562
+ throw new Error(`No snapshot found for workflow run ${this.runId}`);
3563
+ }
3564
+ const stepParts = stepId.split(".");
3565
+ const stepPath = stepParts.join(".");
3566
+ if (stepParts.length > 1) {
3567
+ stepId = stepParts[0] ?? stepId;
3568
+ }
3569
+ let parsedSnapshot;
3570
+ try {
3571
+ parsedSnapshot = typeof snapshot === "string" ? JSON.parse(snapshot) : snapshot;
3572
+ } catch (error) {
3573
+ this.logger.debug("Failed to parse workflow snapshot for resume", {
3574
+ error,
3575
+ runId: this.runId
3576
+ });
3577
+ throw new Error("Failed to parse workflow snapshot");
3578
+ }
3579
+ const startStepId = parsedSnapshot.suspendedSteps?.[stepId];
3580
+ if (!startStepId) {
3581
+ return;
3582
+ }
3583
+ parsedSnapshot = startStepId === "trigger" ? parsedSnapshot : {
3584
+ ...parsedSnapshot?.childStates?.[startStepId],
3585
+ ...{
3586
+ suspendedSteps: parsedSnapshot.suspendedSteps
3587
+ }
3588
+ };
3589
+ if (!parsedSnapshot) {
3590
+ throw new Error(`No snapshot found for step: ${stepId} starting at ${startStepId}`);
3591
+ }
3592
+ if (resumeContext) {
3593
+ parsedSnapshot.context.steps[stepId] = {
3594
+ status: "success",
3595
+ output: {
3596
+ ...(parsedSnapshot?.context?.steps?.[stepId]?.output || {}),
3597
+ ...resumeContext
3598
+ }
3599
+ };
3600
+ }
3601
+ if (parsedSnapshot.children) {
3602
+ Object.entries(parsedSnapshot.children).forEach(([, child]) => {
3603
+ if (child.snapshot?.input?.stepNode) {
3604
+ const stepDef = this.#makeStepDef(child.snapshot.input.stepNode.step.id);
3605
+ child.snapshot.input.stepNode.config = {
3606
+ ...child.snapshot.input.stepNode.config,
3607
+ ...stepDef
3608
+ };
3609
+ child.snapshot.input.context = parsedSnapshot.context;
3610
+ }
3611
+ });
3612
+ }
3613
+ parsedSnapshot.value = updateStepInHierarchy(parsedSnapshot.value, stepId);
3614
+ if (parsedSnapshot.context?.attempts) {
3615
+ parsedSnapshot.context.attempts[stepId] = this.#steps[stepId]?.retryConfig?.attempts || this.#retryConfig?.attempts || 0;
3616
+ }
3617
+ this.logger.debug("Resuming workflow with updated snapshot", {
3618
+ updatedSnapshot: parsedSnapshot,
3619
+ runId: this.runId,
3620
+ stepId
3621
+ });
3622
+ return this.execute({
3623
+ snapshot: parsedSnapshot,
3624
+ stepId: stepPath,
3625
+ resumeData: resumeContext
3626
+ });
3627
+ }
3628
+ #initializeCompoundDependencies() {
3629
+ Object.keys(this.#stepSubscriberGraph).forEach(stepKey => {
3630
+ if (this.#isCompoundKey(stepKey)) {
3631
+ const requiredSteps = stepKey.split("&&");
3632
+ this.#compoundDependencies[stepKey] = requiredSteps.reduce((acc, step) => {
3633
+ acc[step] = false;
3634
+ return acc;
3635
+ }, {});
3636
+ }
3637
+ });
3638
+ }
3639
+ #makeStepDef(stepId) {
3640
+ const executeStep = (handler2, spanName, attributes) => {
3641
+ return async data => {
3642
+ return await api.context.with(api.trace.setSpan(api.context.active(), this.#executionSpan), async () => {
3643
+ if (this.#mastra?.getTelemetry()) {
3644
+ return this.#mastra.getTelemetry()?.traceMethod(handler2, {
3645
+ spanName,
3646
+ attributes
3647
+ })(data);
3648
+ } else {
3649
+ return handler2(data);
3650
+ }
3651
+ });
3652
+ };
3653
+ };
3654
+ const handler = async ({
3655
+ context,
3656
+ ...rest
3657
+ }) => {
3658
+ const targetStep = this.#steps[stepId];
3659
+ if (!targetStep) throw new Error(`Step not found`);
3660
+ const {
3661
+ payload = {},
3662
+ execute = async () => {}
3663
+ } = targetStep;
3664
+ const mergedData = {
3665
+ ...payload,
3666
+ ...context
3667
+ };
3668
+ const finalAction = this.#mastra?.getTelemetry() ? executeStep(execute, `workflow.${this.name}.action.${stepId}`, {
3669
+ componentName: this.name,
3670
+ runId: rest.runId
3671
+ }) : execute;
3672
+ return finalAction ? await finalAction({
3673
+ context: mergedData,
3674
+ ...rest
3675
+ }) : {};
3676
+ };
3677
+ const finalHandler = ({
3678
+ context,
3679
+ ...rest
3680
+ }) => {
3681
+ if (this.#executionSpan) {
3682
+ return executeStep(handler, `workflow.${this.name}.step.${stepId}`, {
3683
+ componentName: this.name,
3684
+ runId: rest?.runId
3685
+ })({
3686
+ context,
3687
+ ...rest
3688
+ });
3689
+ }
3690
+ return handler({
3691
+ context,
3692
+ ...rest
3693
+ });
3694
+ };
3695
+ return {
3696
+ handler: finalHandler,
3697
+ data: {}
3698
+ };
3699
+ }
3700
+ #isCompoundKey(key) {
3701
+ return key.includes("&&");
3702
+ }
3703
+ };
3704
+
3705
+ // src/workflows/workflow.ts
3706
+ var Workflow = class extends chunkD63P5O4Q_cjs.MastraBase {
3707
+ name;
3708
+ triggerSchema;
3709
+ resultSchema;
3710
+ resultMapping;
3711
+ events;
3712
+ #retryConfig;
3713
+ #mastra;
3714
+ #runs = /* @__PURE__ */new Map();
3715
+ #isNested = false;
3716
+ #onStepTransition = /* @__PURE__ */new Set();
3717
+ // registers stepIds on `after` calls
3718
+ #afterStepStack = [];
3719
+ #lastStepStack = [];
3720
+ #lastBuilderType = null;
3721
+ #ifStack = [];
3722
+ #stepGraph = {
3723
+ initial: []
3724
+ };
3725
+ #serializedStepGraph = {
3726
+ initial: []
3727
+ };
3728
+ #stepSubscriberGraph = {};
3729
+ #serializedStepSubscriberGraph = {};
3730
+ #steps = {};
3731
+ /**
3732
+ * Creates a new Workflow instance
3733
+ * @param name - Identifier for the workflow (not necessarily unique)
3734
+ * @param logger - Optional logger instance
3735
+ */
3736
+ constructor({
3737
+ name,
3738
+ triggerSchema,
3739
+ result,
3740
+ retryConfig,
3741
+ mastra,
3742
+ events
3743
+ }) {
3744
+ super({
3745
+ component: "WORKFLOW",
3746
+ name
3747
+ });
3748
+ this.name = name;
3749
+ this.#retryConfig = retryConfig;
3750
+ this.triggerSchema = triggerSchema;
3751
+ this.resultSchema = result?.schema;
3752
+ this.resultMapping = result?.mapping;
3753
+ this.events = events;
3754
+ if (mastra) {
3755
+ this.__registerPrimitives({
3756
+ telemetry: mastra.getTelemetry(),
3757
+ logger: mastra.getLogger()
3758
+ });
3759
+ this.#mastra = mastra;
3760
+ }
3761
+ }
3762
+ step(next, config) {
3763
+ if (Array.isArray(next)) {
3764
+ const nextSteps = next.map(step2 => {
3765
+ if (isWorkflow(step2)) {
3766
+ const asStep = step2.toStep();
3767
+ return asStep;
3768
+ } else if (isAgent(step2)) {
3769
+ return agentToStep(step2);
3770
+ } else {
3771
+ return step2;
3772
+ }
3773
+ });
3774
+ nextSteps.forEach(step2 => this.step(step2, config));
3775
+ this.after(nextSteps);
3776
+ this.step(new Step({
3777
+ id: `__after_${next.map(step2 => step2?.id ?? step2?.name).join("_")}`,
3778
+ execute: async () => {
3779
+ return {
3780
+ success: true
3781
+ };
3782
+ }
3783
+ }));
3784
+ return this;
3785
+ }
3786
+ const {
3787
+ variables = {}
3788
+ } = config || {};
3789
+ const requiredData = {};
3790
+ for (const [key, variable] of Object.entries(variables)) {
3791
+ if (variable && isVariableReference(variable)) {
3792
+ requiredData[key] = variable;
3793
+ }
3794
+ }
3795
+ const step = isWorkflow(next) ?
3796
+ // @ts-ignore
3797
+ workflowToStep(next, {
3798
+ mastra: this.#mastra
3799
+ }) : isAgent(next) ?
3800
+ // @ts-ignore
3801
+ agentToStep(next, {
3802
+ mastra: this.#mastra
3803
+ }) : next;
3804
+ const stepKey = this.#makeStepKey(step);
3805
+ const when = config?.["#internal"]?.when || config?.when;
3806
+ const graphEntry = {
3807
+ step,
3808
+ config: {
3809
+ ...this.#makeStepDef(stepKey),
3810
+ ...config,
3811
+ loopLabel: config?.["#internal"]?.loopLabel,
3812
+ loopType: config?.["#internal"]?.loopType,
3813
+ serializedWhen: typeof when === "function" ? when.toString() : when,
3814
+ data: requiredData
3815
+ }
3816
+ };
3817
+ this.#steps[stepKey] = step;
3818
+ const parentStepKey = this.#getParentStepKey({
3819
+ loop_check: true
3820
+ });
3821
+ const stepGraph = this.#stepSubscriberGraph[parentStepKey || ""];
3822
+ const serializedStepGraph = this.#serializedStepSubscriberGraph[parentStepKey || ""];
3823
+ if (parentStepKey && stepGraph) {
3824
+ if (!stepGraph.initial.some(step2 => step2.step.id === stepKey)) {
3825
+ stepGraph.initial.push(graphEntry);
3826
+ if (serializedStepGraph) serializedStepGraph.initial.push(graphEntry);
3827
+ }
3828
+ stepGraph[stepKey] = [];
3829
+ if (serializedStepGraph) serializedStepGraph[stepKey] = [];
3830
+ } else {
3831
+ if (!this.#stepGraph[stepKey]) this.#stepGraph[stepKey] = [];
3832
+ this.#stepGraph.initial.push(graphEntry);
3833
+ this.#serializedStepGraph.initial.push(graphEntry);
3834
+ }
3835
+ this.#lastStepStack.push(stepKey);
3836
+ this.#lastBuilderType = "step";
3837
+ return this;
3838
+ }
3839
+ #__internalStep(next, config, internalUse) {
3840
+ if (Array.isArray(next)) {
3841
+ const nextSteps = next.map(step2 => {
3842
+ if (isWorkflow(step2)) {
3843
+ const asStep = step2.toStep();
3844
+ return asStep;
3845
+ } else {
3846
+ return step2;
3847
+ }
3848
+ });
3849
+ nextSteps.forEach(step2 => this.#__internalStep(step2, config, internalUse));
3850
+ this.after(nextSteps);
3851
+ this.#__internalStep(new Step({
3852
+ id: `__after_${next.map(step2 => step2?.id ?? step2?.name).join("_")}`,
3853
+ execute: async () => {
3854
+ return {
3855
+ success: true
3856
+ };
3857
+ }
3858
+ }), void 0, internalUse);
3859
+ return this;
3860
+ }
3861
+ const {
3862
+ variables = {}
3863
+ } = config || {};
3864
+ const requiredData = {};
3865
+ for (const [key, variable] of Object.entries(variables)) {
3866
+ if (variable && isVariableReference(variable)) {
3867
+ requiredData[key] = variable;
3868
+ }
3869
+ }
3870
+ const step = isWorkflow(next) ?
3871
+ // @ts-ignore
3872
+ workflowToStep(next, {
3873
+ mastra: this.#mastra
3874
+ }) : next;
3875
+ const stepKey = this.#makeStepKey(step);
3876
+ const when = config?.["#internal"]?.when || config?.when;
3877
+ const graphEntry = {
3878
+ step,
3879
+ config: {
3880
+ ...this.#makeStepDef(stepKey),
3881
+ ...config,
3882
+ loopLabel: config?.["#internal"]?.loopLabel,
3883
+ loopType: config?.["#internal"]?.loopType,
3884
+ serializedWhen: typeof when === "function" ? when.toString() : when,
3885
+ data: requiredData
3886
+ }
3887
+ };
3888
+ this.#steps[stepKey] = step;
3889
+ const parentStepKey = this.#getParentStepKey();
3890
+ const stepGraph = this.#stepSubscriberGraph[parentStepKey || ""];
3891
+ const serializedStepGraph = this.#serializedStepSubscriberGraph[parentStepKey || ""];
3892
+ if (parentStepKey && stepGraph) {
3893
+ if (!stepGraph.initial.some(step2 => step2.step.id === stepKey)) {
3894
+ stepGraph.initial.push(graphEntry);
3895
+ if (serializedStepGraph) serializedStepGraph.initial.push(graphEntry);
3896
+ }
3897
+ stepGraph[stepKey] = [];
3898
+ if (serializedStepGraph) serializedStepGraph[stepKey] = [];
3899
+ } else {
3900
+ if (!this.#stepGraph[stepKey]) this.#stepGraph[stepKey] = [];
3901
+ this.#stepGraph.initial.push(graphEntry);
3902
+ this.#serializedStepGraph.initial.push(graphEntry);
3903
+ }
3904
+ this.#lastStepStack.push(stepKey);
3905
+ this.#lastBuilderType = "step";
3906
+ return this;
3907
+ }
3908
+ #makeStepKey(step) {
3909
+ return `${step.id ?? step.name}`;
3910
+ }
3911
+ then(next, config) {
3912
+ if (Array.isArray(next)) {
3913
+ const lastStep = this.#steps[this.#lastStepStack[this.#lastStepStack.length - 1] ?? ""];
3914
+ if (!lastStep) {
3915
+ throw new Error("Condition requires a step to be executed after");
3916
+ }
3917
+ this.after(lastStep);
3918
+ const nextSteps = next.map(step2 => {
3919
+ if (isWorkflow(step2)) {
3920
+ return workflowToStep(step2, {
3921
+ mastra: this.#mastra
3922
+ });
3923
+ }
3924
+ if (isAgent(step2)) {
3925
+ return agentToStep(step2);
3926
+ }
3927
+ return step2;
3928
+ });
3929
+ nextSteps.forEach(step2 => this.step(step2, config));
3930
+ this.step(new Step({
3931
+ // @ts-ignore
3932
+ id: `__after_${next.map(step2 => step2?.id ?? step2?.name).join("_")}`,
3933
+ execute: async () => {
3934
+ return {
3935
+ success: true
3936
+ };
3937
+ }
3938
+ }));
3939
+ return this;
3940
+ }
3941
+ const {
3942
+ variables = {}
3943
+ } = config || {};
3944
+ const requiredData = {};
3945
+ for (const [key, variable] of Object.entries(variables)) {
3946
+ if (variable && isVariableReference(variable)) {
3947
+ requiredData[key] = variable;
3948
+ }
3949
+ }
3950
+ const lastStepKey = this.#lastStepStack[this.#lastStepStack.length - 1];
3951
+ const step = isWorkflow(next) ? workflowToStep(next, {
3952
+ mastra: this.#mastra
3953
+ }) : isAgent(next) ? agentToStep(next) : next;
3954
+ const stepKey = this.#makeStepKey(step);
3955
+ const when = config?.["#internal"]?.when || config?.when;
3956
+ const graphEntry = {
3957
+ step,
3958
+ config: {
3959
+ ...this.#makeStepDef(stepKey),
3960
+ ...config,
3961
+ loopLabel: config?.["#internal"]?.loopLabel,
3962
+ loopType: config?.["#internal"]?.loopType,
3963
+ serializedWhen: typeof when === "function" ? when.toString() : when,
3964
+ data: requiredData
3965
+ }
3966
+ };
3967
+ this.#steps[stepKey] = step;
3968
+ if (!lastStepKey) return this;
3969
+ const parentStepKey = this.#afterStepStack[this.#afterStepStack.length - 1];
3970
+ const stepGraph = this.#stepSubscriberGraph[parentStepKey || ""];
3971
+ const serializedStepGraph = this.#serializedStepSubscriberGraph[parentStepKey || ""];
3972
+ if (parentStepKey && this.#lastBuilderType === "after") {
3973
+ return this.step(step, config);
3974
+ }
3975
+ if (parentStepKey && stepGraph && stepGraph[lastStepKey]) {
3976
+ stepGraph[lastStepKey].push(graphEntry);
3977
+ if (serializedStepGraph && serializedStepGraph[lastStepKey]) serializedStepGraph[lastStepKey].push(graphEntry);
3978
+ } else {
3979
+ if (!this.#stepGraph[lastStepKey]) this.#stepGraph[lastStepKey] = [];
3980
+ if (!this.#serializedStepGraph[lastStepKey]) this.#serializedStepGraph[lastStepKey] = [];
3981
+ this.#stepGraph[lastStepKey].push(graphEntry);
3982
+ this.#serializedStepGraph[lastStepKey].push(graphEntry);
3983
+ }
3984
+ this.#lastBuilderType = "then";
3985
+ return this;
3986
+ }
3987
+ loop(applyOperator, condition, fallbackStep, loopType) {
3988
+ const lastStepKey = this.#lastStepStack[this.#lastStepStack.length - 1];
3989
+ if (!lastStepKey) return this;
3990
+ const fallbackStepKey = this.#makeStepKey(fallbackStep);
3991
+ this.#steps[fallbackStepKey] = fallbackStep;
3992
+ const checkStepKey = `__${fallbackStepKey}_${loopType}_loop_check`;
3993
+ const checkStep = {
3994
+ id: checkStepKey,
3995
+ execute: async ({
3996
+ context
3997
+ }) => {
3998
+ if (typeof condition === "function") {
3999
+ const result = await condition({
4000
+ context
4001
+ });
4002
+ switch (loopType) {
4003
+ case "while":
4004
+ return {
4005
+ status: result ? "continue" : "complete"
4006
+ };
4007
+ case "until":
4008
+ return {
4009
+ status: result ? "complete" : "continue"
4010
+ };
4011
+ default:
4012
+ throw new Error(`Invalid loop type: ${loopType}`);
4013
+ }
4014
+ }
4015
+ if (condition && "ref" in condition) {
4016
+ const {
4017
+ ref,
4018
+ query
4019
+ } = condition;
4020
+ const stepId = typeof ref.step === "string" ? ref.step : "id" in ref.step ? ref.step.id : null;
4021
+ if (!stepId) {
4022
+ return {
4023
+ status: "continue"
4024
+ };
4025
+ }
4026
+ const stepOutput = context.steps?.[stepId]?.output;
4027
+ if (!stepOutput) {
4028
+ return {
4029
+ status: "continue"
4030
+ };
4031
+ }
4032
+ const value = ref.path.split(".").reduce((obj, key) => obj?.[key], stepOutput);
4033
+ const operator = Object.keys(query)[0];
4034
+ const target = query[operator];
4035
+ return applyOperator(operator, value, target);
4036
+ }
4037
+ return {
4038
+ status: "continue"
4039
+ };
4040
+ },
4041
+ outputSchema: zod.z.object({
4042
+ status: zod.z.enum(["continue", "complete"])
4043
+ })
4044
+ };
4045
+ this.#steps[checkStepKey] = checkStep;
4046
+ const loopFinishedStepKey = `__${fallbackStepKey}_${loopType}_loop_finished`;
4047
+ const loopFinishedStep = {
4048
+ id: loopFinishedStepKey,
4049
+ execute: async () => {
4050
+ return {
4051
+ success: true
4052
+ };
4053
+ }
4054
+ };
4055
+ this.#steps[checkStepKey] = checkStep;
4056
+ this.then(checkStep, {
4057
+ "#internal": {
4058
+ loopLabel: `${fallbackStepKey} ${loopType} loop check`
4059
+ }
4060
+ });
4061
+ this.after(checkStep);
4062
+ this.#__internalStep(fallbackStep, {
4063
+ when: async ({
4064
+ context
4065
+ }) => {
4066
+ const checkStepResult = context.steps?.[checkStepKey];
4067
+ if (checkStepResult?.status !== "success") {
4068
+ return "abort" /* ABORT */;
4069
+ }
4070
+ const status = checkStepResult?.output?.status;
4071
+ return status === "continue" ? "continue" /* CONTINUE */ : "continue_failed" /* CONTINUE_FAILED */;
4072
+ },
4073
+ "#internal": {
4074
+ // @ts-ignore
4075
+ when: condition,
4076
+ loopType
4077
+ }
4078
+ }).then(checkStep, {
4079
+ "#internal": {
4080
+ loopLabel: `${fallbackStepKey} ${loopType} loop check`
4081
+ }
4082
+ });
4083
+ this.#__internalStep(loopFinishedStep, {
4084
+ when: async ({
4085
+ context
4086
+ }) => {
4087
+ const checkStepResult = context.steps?.[checkStepKey];
4088
+ if (checkStepResult?.status !== "success") {
4089
+ return "continue_failed" /* CONTINUE_FAILED */;
4090
+ }
4091
+ const status = checkStepResult?.output?.status;
4092
+ return status === "complete" ? "continue" /* CONTINUE */ : "continue_failed" /* CONTINUE_FAILED */;
4093
+ },
4094
+ "#internal": {
4095
+ loopLabel: `${fallbackStepKey} ${loopType} loop finished`,
4096
+ //@ts-ignore
4097
+ loopType
4098
+ }
4099
+ });
4100
+ return this;
4101
+ }
4102
+ while(condition, fallbackStep) {
4103
+ const applyOperator = (operator, value, target) => {
4104
+ switch (operator) {
4105
+ case "$eq":
4106
+ return {
4107
+ status: value !== target ? "complete" : "continue"
4108
+ };
4109
+ case "$ne":
4110
+ return {
4111
+ status: value === target ? "complete" : "continue"
4112
+ };
4113
+ case "$gt":
4114
+ return {
4115
+ status: value <= target ? "complete" : "continue"
4116
+ };
4117
+ case "$gte":
4118
+ return {
4119
+ status: value < target ? "complete" : "continue"
4120
+ };
4121
+ case "$lt":
4122
+ return {
4123
+ status: value >= target ? "complete" : "continue"
4124
+ };
4125
+ case "$lte":
4126
+ return {
4127
+ status: value > target ? "complete" : "continue"
4128
+ };
4129
+ default:
4130
+ return {
4131
+ status: "continue"
4132
+ };
4133
+ }
4134
+ };
4135
+ const res = this.loop(applyOperator, condition, fallbackStep, "while");
4136
+ this.#lastBuilderType = "while";
4137
+ return res;
4138
+ }
4139
+ until(condition, fallbackStep) {
4140
+ const applyOperator = (operator, value, target) => {
4141
+ switch (operator) {
4142
+ case "$eq":
4143
+ return {
4144
+ status: value === target ? "complete" : "continue"
4145
+ };
4146
+ case "$ne":
4147
+ return {
4148
+ status: value !== target ? "complete" : "continue"
4149
+ };
4150
+ case "$gt":
4151
+ return {
4152
+ status: value > target ? "complete" : "continue"
4153
+ };
4154
+ case "$gte":
4155
+ return {
4156
+ status: value >= target ? "complete" : "continue"
4157
+ };
4158
+ case "$lt":
4159
+ return {
4160
+ status: value < target ? "complete" : "continue"
4161
+ };
4162
+ case "$lte":
4163
+ return {
4164
+ status: value <= target ? "complete" : "continue"
4165
+ };
4166
+ default:
4167
+ return {
4168
+ status: "continue"
4169
+ };
4170
+ }
4171
+ };
4172
+ const res = this.loop(applyOperator, condition, fallbackStep, "until");
4173
+ this.#lastBuilderType = "until";
4174
+ return res;
4175
+ }
4176
+ if(condition, ifStep, elseStep) {
4177
+ const lastStep = this.#steps[this.#lastStepStack[this.#lastStepStack.length - 1] ?? ""];
4178
+ if (!lastStep) {
4179
+ throw new Error("Condition requires a step to be executed after");
4180
+ }
4181
+ this.after(lastStep);
4182
+ if (ifStep) {
4183
+ const _ifStep = isWorkflow(ifStep) ? workflowToStep(ifStep, {
4184
+ mastra: this.#mastra
4185
+ }) : ifStep;
4186
+ this.step(_ifStep, {
4187
+ when: condition
4188
+ });
4189
+ if (elseStep) {
4190
+ const _elseStep = isWorkflow(elseStep) ? workflowToStep(elseStep, {
4191
+ mastra: this.#mastra
4192
+ }) : elseStep;
4193
+ this.step(_elseStep, {
4194
+ when: typeof condition === "function" ? async payload => {
4195
+ const result = await condition(payload);
4196
+ return !result;
4197
+ } : {
4198
+ not: condition
4199
+ }
4200
+ });
4201
+ this.after([_ifStep, _elseStep]);
4202
+ } else {
4203
+ this.after(_ifStep);
4204
+ }
4205
+ this.step(new Step({
4206
+ id: `${lastStep.id}_if_else`,
4207
+ execute: async () => {
4208
+ return {
4209
+ executed: true
4210
+ };
4211
+ }
4212
+ }));
4213
+ return this;
4214
+ }
4215
+ const ifStepKey = `__${lastStep.id}_if`;
4216
+ this.step({
4217
+ id: ifStepKey,
4218
+ execute: async () => {
4219
+ return {
4220
+ executed: true
4221
+ };
4222
+ }
4223
+ }, {
4224
+ when: condition
4225
+ });
4226
+ const elseStepKey = `__${lastStep.id}_else`;
4227
+ this.#ifStack.push({
4228
+ condition,
4229
+ elseStepKey,
4230
+ condStep: lastStep
4231
+ });
4232
+ this.#lastBuilderType = "if";
4233
+ return this;
4234
+ }
4235
+ else() {
4236
+ const activeCondition = this.#ifStack.pop();
4237
+ if (!activeCondition) {
4238
+ throw new Error("No active condition found");
4239
+ }
4240
+ this.after(activeCondition.condStep).step({
4241
+ id: activeCondition.elseStepKey,
4242
+ execute: async () => {
4243
+ return {
4244
+ executed: true
4245
+ };
4246
+ }
4247
+ }, {
4248
+ when: typeof activeCondition.condition === "function" ? async payload => {
4249
+ const result = await activeCondition.condition(payload);
4250
+ return !result;
4251
+ } : {
4252
+ not: activeCondition.condition
4253
+ }
4254
+ });
4255
+ this.#lastBuilderType = "else";
4256
+ return this;
4257
+ }
4258
+ after(steps) {
4259
+ const stepsArray = Array.isArray(steps) ? steps : [steps];
4260
+ const stepKeys = stepsArray.map(step => this.#makeStepKey(step));
4261
+ const compoundKey = stepKeys.join("&&");
4262
+ this.#afterStepStack.push(compoundKey);
4263
+ if (!this.#stepSubscriberGraph[compoundKey]) {
4264
+ this.#stepSubscriberGraph[compoundKey] = {
4265
+ initial: []
4266
+ };
4267
+ this.#serializedStepSubscriberGraph[compoundKey] = {
4268
+ initial: []
4269
+ };
4270
+ }
4271
+ this.#lastBuilderType = "after";
4272
+ return this;
4273
+ }
4274
+ afterEvent(eventName) {
4275
+ const event = this.events?.[eventName];
4276
+ if (!event) {
4277
+ throw new Error(`Event ${eventName} not found`);
4278
+ }
4279
+ const lastStep = this.#steps[this.#lastStepStack[this.#lastStepStack.length - 1] ?? ""];
4280
+ if (!lastStep) {
4281
+ throw new Error("Condition requires a step to be executed after");
4282
+ }
4283
+ const eventStepKey = `__${eventName}_event`;
4284
+ const eventStep = new Step({
4285
+ id: eventStepKey,
4286
+ execute: async ({
4287
+ context,
4288
+ suspend
4289
+ }) => {
4290
+ if (context.inputData?.resumedEvent) {
4291
+ return {
4292
+ executed: true,
4293
+ resumedEvent: context.inputData?.resumedEvent
4294
+ };
4295
+ }
4296
+ await suspend();
4297
+ return {
4298
+ executed: false
4299
+ };
4300
+ }
4301
+ });
4302
+ this.after(lastStep).step(eventStep).after(eventStep);
4303
+ this.#lastBuilderType = "afterEvent";
4304
+ return this;
4305
+ }
4306
+ /**
4307
+ * Executes the workflow with the given trigger data
4308
+ * @param triggerData - Initial data to start the workflow with
4309
+ * @returns Promise resolving to workflow results or rejecting with error
4310
+ * @throws Error if trigger schema validation fails
4311
+ */
4312
+ createRun({
4313
+ runId,
4314
+ events
4315
+ } = {}) {
4316
+ const run = new WorkflowInstance({
4317
+ logger: this.logger,
4318
+ name: this.name,
4319
+ mastra: this.#mastra,
4320
+ retryConfig: this.#retryConfig,
4321
+ steps: this.#steps,
4322
+ runId,
4323
+ stepGraph: this.#stepGraph,
4324
+ stepSubscriberGraph: this.#stepSubscriberGraph,
4325
+ onStepTransition: this.#onStepTransition,
4326
+ resultMapping: this.resultMapping,
4327
+ onFinish: () => {
4328
+ this.#runs.delete(run.runId);
4329
+ },
4330
+ events
4331
+ });
4332
+ this.#runs.set(run.runId, run);
4333
+ return {
4334
+ start: run.start.bind(run),
4335
+ runId: run.runId,
4336
+ watch: run.watch.bind(run),
4337
+ resume: run.resume.bind(run),
4338
+ resumeWithEvent: run.resumeWithEvent.bind(run)
4339
+ };
4340
+ }
4341
+ /**
4342
+ * Gets a workflow run instance by ID
4343
+ * @param runId - ID of the run to retrieve
4344
+ * @returns The workflow run instance if found, undefined otherwise
4345
+ */
4346
+ getRun(runId) {
4347
+ return this.#runs.get(runId);
4348
+ }
4349
+ /**
4350
+ * Rebuilds the machine with the current steps configuration and validates the workflow
4351
+ *
4352
+ * This is the last step of a workflow builder method chain
4353
+ * @throws Error if validation fails
4354
+ *
4355
+ * @returns this instance for method chaining
4356
+ */
4357
+ commit() {
4358
+ return this;
4359
+ }
4360
+ // record all object paths that leads to a suspended state
4361
+ #getSuspendedPaths({
4362
+ value,
4363
+ path,
4364
+ suspendedPaths
4365
+ }) {
4366
+ if (typeof value === "string") {
4367
+ if (value === "suspended") {
4368
+ suspendedPaths.add(path);
4369
+ }
4370
+ } else {
4371
+ Object.keys(value).forEach(key => this.#getSuspendedPaths({
4372
+ value: value[key],
4373
+ path: path ? `${path}.${key}` : key,
4374
+ suspendedPaths
4375
+ }));
4376
+ }
4377
+ }
4378
+ getExecutionSpan(runId) {
4379
+ return this.#runs.get(runId)?.executionSpan;
4380
+ }
4381
+ #getParentStepKey({
4382
+ loop_check
4383
+ } = {
4384
+ loop_check: false
4385
+ }) {
4386
+ let parentStepKey = void 0;
4387
+ for (let i = this.#afterStepStack.length - 1; i >= 0; i--) {
4388
+ const stepKey = this.#afterStepStack[i];
4389
+ if (stepKey && this.#stepSubscriberGraph[stepKey] && (loop_check ? !stepKey.includes("loop_check") : true)) {
4390
+ parentStepKey = stepKey;
4391
+ break;
4392
+ }
4393
+ }
4394
+ return parentStepKey;
4395
+ }
4396
+ #makeStepDef(stepId) {
4397
+ const executeStep = (handler2, spanName, attributes) => {
4398
+ return async data => {
4399
+ return await api.context.with(api.trace.setSpan(api.context.active(), this.getExecutionSpan(attributes?.runId ?? data?.runId)), async () => {
4400
+ if (this?.telemetry) {
4401
+ return this.telemetry.traceMethod(handler2, {
4402
+ spanName,
4403
+ attributes
4404
+ })(data);
4405
+ } else {
4406
+ return handler2(data);
4407
+ }
4408
+ });
4409
+ };
4410
+ };
4411
+ const handler = async ({
4412
+ context,
4413
+ ...rest
4414
+ }) => {
4415
+ const targetStep = this.#steps[stepId];
4416
+ if (!targetStep) throw new Error(`Step not found`);
4417
+ const {
4418
+ payload = {},
4419
+ execute = async () => {}
4420
+ } = targetStep;
4421
+ const finalAction = this.telemetry ? executeStep(execute, `workflow.${this.name}.action.${stepId}`, {
4422
+ componentName: this.name,
4423
+ runId: rest.runId
4424
+ }) : execute;
4425
+ return finalAction ? await finalAction({
4426
+ context: {
4427
+ ...context,
4428
+ inputData: {
4429
+ ...(context?.inputData || {}),
4430
+ ...payload
4431
+ }
4432
+ },
4433
+ ...rest
4434
+ }) : {};
4435
+ };
4436
+ const finalHandler = ({
4437
+ context,
4438
+ ...rest
4439
+ }) => {
4440
+ if (this.getExecutionSpan(rest?.runId)) {
4441
+ return executeStep(handler, `workflow.${this.name}.step.${stepId}`, {
4442
+ componentName: this.name,
4443
+ runId: rest?.runId
4444
+ })({
4445
+ context,
4446
+ ...rest
4447
+ });
4448
+ }
4449
+ return handler({
4450
+ context,
4451
+ ...rest
4452
+ });
4453
+ };
4454
+ return {
4455
+ handler: finalHandler,
4456
+ data: {}
4457
+ };
4458
+ }
4459
+ #getActivePathsAndStatus(value) {
4460
+ const paths = [];
4461
+ const traverse = (current, path = []) => {
4462
+ for (const [key, value2] of Object.entries(current)) {
4463
+ const currentPath = [...path, key];
4464
+ if (typeof value2 === "string") {
4465
+ paths.push({
4466
+ stepPath: currentPath,
4467
+ stepId: key,
4468
+ status: value2
4469
+ });
4470
+ } else if (typeof value2 === "object" && value2 !== null) {
4471
+ traverse(value2, currentPath);
4472
+ }
4473
+ }
4474
+ };
4475
+ traverse(value);
4476
+ return paths;
4477
+ }
4478
+ async getState(runId) {
4479
+ const run = this.#runs.get(runId);
4480
+ if (run) {
4481
+ return run.getState();
4482
+ }
4483
+ const storage = this.#mastra?.getStorage();
4484
+ const storedSnapshot = await storage?.loadWorkflowSnapshot({
4485
+ runId,
4486
+ workflowName: this.name
4487
+ });
4488
+ if (storedSnapshot) {
4489
+ const parsed = storedSnapshot;
4490
+ const m = this.#getActivePathsAndStatus(parsed.value);
4491
+ return {
4492
+ runId,
4493
+ value: parsed.value,
4494
+ context: parsed.context,
4495
+ activePaths: m,
4496
+ timestamp: Date.now()
4497
+ };
4498
+ }
4499
+ return null;
4500
+ }
4501
+ async resume({
4502
+ runId,
4503
+ stepId,
4504
+ context: resumeContext
4505
+ }) {
4506
+ this.logger.warn(`Please use 'resume' on the 'createRun' call instead, resume is deprecated`);
4507
+ const activeRun = this.#runs.get(runId);
4508
+ if (activeRun) {
4509
+ return activeRun.resume({
4510
+ stepId,
4511
+ context: resumeContext
4512
+ });
4513
+ }
4514
+ const run = this.createRun({
4515
+ runId
4516
+ });
4517
+ return run.resume({
4518
+ stepId,
4519
+ context: resumeContext
4520
+ });
4521
+ }
4522
+ watch(onTransition) {
4523
+ this.logger.warn(`Please use 'watch' on the 'createRun' call instead, watch is deprecated`);
4524
+ this.#onStepTransition.add(onTransition);
4525
+ return () => {
4526
+ this.#onStepTransition.delete(onTransition);
4527
+ };
4528
+ }
4529
+ async resumeWithEvent(runId, eventName, data) {
4530
+ this.logger.warn(`Please use 'resumeWithEvent' on the 'createRun' call instead, resumeWithEvent is deprecated`);
4531
+ const event = this.events?.[eventName];
4532
+ if (!event) {
4533
+ throw new Error(`Event ${eventName} not found`);
4534
+ }
4535
+ const results = await this.resume({
4536
+ runId,
4537
+ stepId: `__${eventName}_event`,
4538
+ context: {
4539
+ resumedEvent: data
4540
+ }
4541
+ });
4542
+ return results;
4543
+ }
4544
+ __registerMastra(mastra) {
4545
+ this.#mastra = mastra;
4546
+ }
4547
+ __registerPrimitives(p) {
4548
+ if (p.telemetry) {
4549
+ this.__setTelemetry(p.telemetry);
4550
+ }
4551
+ if (p.logger) {
4552
+ this.__setLogger(p.logger);
4553
+ }
4554
+ }
4555
+ get stepGraph() {
4556
+ return this.#stepGraph;
4557
+ }
4558
+ get stepSubscriberGraph() {
4559
+ return this.#stepSubscriberGraph;
4560
+ }
4561
+ get serializedStepGraph() {
4562
+ return this.#serializedStepGraph;
4563
+ }
4564
+ get serializedStepSubscriberGraph() {
4565
+ return this.#serializedStepSubscriberGraph;
4566
+ }
4567
+ get steps() {
4568
+ return this.#steps;
4569
+ }
4570
+ setNested(isNested) {
4571
+ this.#isNested = isNested;
4572
+ }
4573
+ get isNested() {
4574
+ return this.#isNested;
4575
+ }
4576
+ toStep() {
4577
+ const x = workflowToStep(this, {
4578
+ mastra: this.#mastra
4579
+ });
4580
+ return new Step(x);
4581
+ }
4582
+ };
4583
+
4584
+ exports.Step = Step;
4585
+ exports.WhenConditionReturnValue = WhenConditionReturnValue;
4586
+ exports.Workflow = Workflow;
4587
+ exports.agentToStep = agentToStep;
4588
+ exports.createStep = createStep;
4589
+ exports.getActivePathsAndStatus = getActivePathsAndStatus;
4590
+ exports.getResultActivePaths = getResultActivePaths;
4591
+ exports.getStepResult = getStepResult;
4592
+ exports.getSuspendedPaths = getSuspendedPaths;
4593
+ exports.isAgent = isAgent;
4594
+ exports.isErrorEvent = isErrorEvent;
4595
+ exports.isFinalState = isFinalState;
4596
+ exports.isLimboState = isLimboState;
4597
+ exports.isTransitionEvent = isTransitionEvent;
4598
+ exports.isVariableReference = isVariableReference;
4599
+ exports.isWorkflow = isWorkflow;
4600
+ exports.mergeChildValue = mergeChildValue;
4601
+ exports.recursivelyCheckForFinalState = recursivelyCheckForFinalState;
4602
+ exports.resolveVariables = resolveVariables;
4603
+ exports.updateStepInHierarchy = updateStepInHierarchy;
4604
+ exports.workflowToStep = workflowToStep;