@mastra/core 0.7.0 → 0.8.0-alpha.1

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