@mastra/mcp-docs-server 0.13.38 → 0.13.39-alpha.0

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 (135) hide show
  1. package/.docs/organized/changelogs/%40mastra%2Fagent-builder.md +11 -11
  2. package/.docs/organized/changelogs/%40mastra%2Fai-sdk.md +16 -16
  3. package/.docs/organized/changelogs/%40mastra%2Fastra.md +10 -10
  4. package/.docs/organized/changelogs/%40mastra%2Fauth.md +6 -0
  5. package/.docs/organized/changelogs/%40mastra%2Fchroma.md +11 -11
  6. package/.docs/organized/changelogs/%40mastra%2Fclickhouse.md +10 -10
  7. package/.docs/organized/changelogs/%40mastra%2Fclient-js.md +16 -16
  8. package/.docs/organized/changelogs/%40mastra%2Fcloud.md +10 -10
  9. package/.docs/organized/changelogs/%40mastra%2Fcloudflare-d1.md +10 -10
  10. package/.docs/organized/changelogs/%40mastra%2Fcloudflare.md +10 -10
  11. package/.docs/organized/changelogs/%40mastra%2Fcore.md +20 -20
  12. package/.docs/organized/changelogs/%40mastra%2Fcouchbase.md +11 -11
  13. package/.docs/organized/changelogs/%40mastra%2Fdeployer-cloud.md +12 -12
  14. package/.docs/organized/changelogs/%40mastra%2Fdeployer-cloudflare.md +11 -11
  15. package/.docs/organized/changelogs/%40mastra%2Fdeployer-netlify.md +11 -11
  16. package/.docs/organized/changelogs/%40mastra%2Fdeployer-vercel.md +11 -11
  17. package/.docs/organized/changelogs/%40mastra%2Fdeployer.md +35 -35
  18. package/.docs/organized/changelogs/%40mastra%2Fdynamodb.md +11 -11
  19. package/.docs/organized/changelogs/%40mastra%2Fevals.md +11 -11
  20. package/.docs/organized/changelogs/%40mastra%2Ffastembed.md +6 -0
  21. package/.docs/organized/changelogs/%40mastra%2Flance.md +10 -10
  22. package/.docs/organized/changelogs/%40mastra%2Flibsql.md +11 -11
  23. package/.docs/organized/changelogs/%40mastra%2Floggers.md +11 -11
  24. package/.docs/organized/changelogs/%40mastra%2Fmcp-docs-server.md +11 -11
  25. package/.docs/organized/changelogs/%40mastra%2Fmcp-registry-registry.md +10 -10
  26. package/.docs/organized/changelogs/%40mastra%2Fmcp.md +11 -11
  27. package/.docs/organized/changelogs/%40mastra%2Fmemory.md +11 -11
  28. package/.docs/organized/changelogs/%40mastra%2Fmongodb.md +10 -10
  29. package/.docs/organized/changelogs/%40mastra%2Fmssql.md +11 -11
  30. package/.docs/organized/changelogs/%40mastra%2Fopensearch.md +10 -10
  31. package/.docs/organized/changelogs/%40mastra%2Fpg.md +10 -10
  32. package/.docs/organized/changelogs/%40mastra%2Fpinecone.md +10 -10
  33. package/.docs/organized/changelogs/%40mastra%2Fplayground-ui.md +22 -22
  34. package/.docs/organized/changelogs/%40mastra%2Fqdrant.md +11 -11
  35. package/.docs/organized/changelogs/%40mastra%2Frag.md +10 -10
  36. package/.docs/organized/changelogs/%40mastra%2Freact.md +10 -10
  37. package/.docs/organized/changelogs/%40mastra%2Fs3vectors.md +9 -0
  38. package/.docs/organized/changelogs/%40mastra%2Fschema-compat.md +6 -0
  39. package/.docs/organized/changelogs/%40mastra%2Fserver.md +18 -18
  40. package/.docs/organized/changelogs/%40mastra%2Fturbopuffer.md +10 -10
  41. package/.docs/organized/changelogs/%40mastra%2Fupstash.md +10 -10
  42. package/.docs/organized/changelogs/%40mastra%2Fvectorize.md +10 -10
  43. package/.docs/organized/changelogs/%40mastra%2Fvoice-azure.md +10 -10
  44. package/.docs/organized/changelogs/%40mastra%2Fvoice-cloudflare.md +11 -11
  45. package/.docs/organized/changelogs/%40mastra%2Fvoice-deepgram.md +11 -11
  46. package/.docs/organized/changelogs/%40mastra%2Fvoice-elevenlabs.md +11 -11
  47. package/.docs/organized/changelogs/%40mastra%2Fvoice-gladia.md +11 -11
  48. package/.docs/organized/changelogs/%40mastra%2Fvoice-google-gemini-live.md +11 -1
  49. package/.docs/organized/changelogs/%40mastra%2Fvoice-google.md +10 -10
  50. package/.docs/organized/changelogs/%40mastra%2Fvoice-murf.md +11 -11
  51. package/.docs/organized/changelogs/%40mastra%2Fvoice-openai-realtime.md +10 -10
  52. package/.docs/organized/changelogs/%40mastra%2Fvoice-openai.md +10 -10
  53. package/.docs/organized/changelogs/%40mastra%2Fvoice-playai.md +11 -11
  54. package/.docs/organized/changelogs/%40mastra%2Fvoice-sarvam.md +11 -11
  55. package/.docs/organized/changelogs/%40mastra%2Fvoice-speechify.md +10 -10
  56. package/.docs/organized/changelogs/create-mastra.md +7 -7
  57. package/.docs/organized/changelogs/mastra.md +18 -18
  58. package/.docs/raw/agents/overview.mdx +2 -2
  59. package/.docs/raw/auth/jwt.mdx +2 -2
  60. package/.docs/raw/auth/supabase.mdx +2 -2
  61. package/.docs/raw/auth/workos.mdx +2 -2
  62. package/.docs/raw/course/02-agent-tools-mcp/04-initializing-mcp-tools.md +2 -2
  63. package/.docs/raw/course/03-agent-memory/18-advanced-configuration-semantic-recall.md +1 -1
  64. package/.docs/raw/frameworks/agentic-uis/ai-sdk.mdx +24 -8
  65. package/.docs/raw/frameworks/agentic-uis/openrouter.mdx +1 -1
  66. package/.docs/raw/frameworks/servers/express.mdx +1 -1
  67. package/.docs/raw/frameworks/web-frameworks/sveltekit.mdx +34 -18
  68. package/.docs/raw/getting-started/installation.mdx +7 -7
  69. package/.docs/raw/getting-started/mcp-docs-server.mdx +1 -1
  70. package/.docs/raw/getting-started/studio.mdx +27 -17
  71. package/.docs/raw/getting-started/templates.mdx +12 -4
  72. package/.docs/raw/index.mdx +1 -1
  73. package/.docs/raw/mastra-cloud/dashboard.mdx +6 -6
  74. package/.docs/raw/mastra-cloud/observability.mdx +2 -2
  75. package/.docs/raw/mastra-cloud/overview.mdx +1 -1
  76. package/.docs/raw/mastra-cloud/setting-up.mdx +1 -1
  77. package/.docs/raw/memory/overview.mdx +1 -1
  78. package/.docs/raw/memory/semantic-recall.mdx +2 -4
  79. package/.docs/raw/memory/threads-and-resources.mdx +1 -1
  80. package/.docs/raw/memory/working-memory.mdx +1 -1
  81. package/.docs/raw/observability/ai-tracing/exporters/default.mdx +6 -6
  82. package/.docs/raw/observability/ai-tracing/overview.mdx +7 -7
  83. package/.docs/raw/observability/overview.mdx +1 -1
  84. package/.docs/raw/reference/agents/agent.mdx +2 -2
  85. package/.docs/raw/reference/agents/listScorers.mdx +69 -0
  86. package/.docs/raw/reference/agents/listTools.mdx +69 -0
  87. package/.docs/raw/reference/agents/listWorkflows.mdx +69 -0
  88. package/.docs/raw/reference/cli/mastra.mdx +1 -1
  89. package/.docs/raw/reference/client-js/agents.mdx +1 -1
  90. package/.docs/raw/reference/client-js/logs.mdx +1 -1
  91. package/.docs/raw/reference/client-js/mastra-client.mdx +7 -7
  92. package/.docs/raw/reference/client-js/memory.mdx +1 -1
  93. package/.docs/raw/reference/client-js/tools.mdx +1 -1
  94. package/.docs/raw/reference/client-js/workflows.mdx +1 -1
  95. package/.docs/raw/reference/core/getScorerByName.mdx +1 -1
  96. package/.docs/raw/reference/core/listAgents.mdx +35 -0
  97. package/.docs/raw/reference/core/listLogs.mdx +96 -0
  98. package/.docs/raw/reference/core/listLogsByRunId.mdx +87 -0
  99. package/.docs/raw/reference/core/listScorers.mdx +43 -0
  100. package/.docs/raw/reference/core/listWorkflows.mdx +45 -0
  101. package/.docs/raw/reference/memory/memory-class.mdx +2 -1
  102. package/.docs/raw/reference/observability/ai-tracing/ai-tracing.mdx +0 -1
  103. package/.docs/raw/reference/observability/ai-tracing/interfaces.mdx +1 -1
  104. package/.docs/raw/reference/observability/otel-tracing/providers/keywordsai.mdx +1 -1
  105. package/.docs/raw/reference/processors/batch-parts-processor.mdx +10 -14
  106. package/.docs/raw/reference/processors/language-detector.mdx +20 -32
  107. package/.docs/raw/reference/processors/moderation-processor.mdx +46 -30
  108. package/.docs/raw/reference/processors/pii-detector.mdx +47 -32
  109. package/.docs/raw/reference/processors/prompt-injection-detector.mdx +20 -30
  110. package/.docs/raw/reference/processors/system-prompt-scrubber.mdx +24 -29
  111. package/.docs/raw/reference/processors/token-limiter-processor.mdx +14 -23
  112. package/.docs/raw/reference/processors/unicode-normalizer.mdx +12 -14
  113. package/.docs/raw/reference/rag/document.mdx +1 -1
  114. package/.docs/raw/reference/scorers/run-experiment.mdx +1 -1
  115. package/.docs/raw/reference/storage/mssql.mdx +3 -3
  116. package/.docs/raw/reference/streaming/workflows/resumeStreamVNext.mdx +1 -1
  117. package/.docs/raw/reference/streaming/workflows/stream.mdx +1 -1
  118. package/.docs/raw/reference/streaming/workflows/streamVNext.mdx +1 -1
  119. package/.docs/raw/reference/tools/mcp-client.mdx +8 -8
  120. package/.docs/raw/reference/voice/google-gemini-live.mdx +1 -1
  121. package/.docs/raw/reference/workflows/step.mdx +1 -1
  122. package/.docs/raw/reference/workflows/workflow-methods/foreach.mdx +1 -1
  123. package/.docs/raw/reference/workflows/workflow-methods/map.mdx +72 -2
  124. package/.docs/raw/reference/workflows/workflow.mdx +0 -14
  125. package/.docs/raw/scorers/overview.mdx +5 -5
  126. package/.docs/raw/server-db/middleware.mdx +4 -4
  127. package/.docs/raw/tools-mcp/overview.mdx +2 -2
  128. package/.docs/raw/workflows/agents-and-tools.mdx +2 -6
  129. package/.docs/raw/workflows/control-flow.mdx +208 -165
  130. package/.docs/raw/workflows/inngest-workflow.mdx +2 -2
  131. package/.docs/raw/workflows/overview.mdx +106 -54
  132. package/.docs/raw/workflows/suspend-and-resume.mdx +1 -9
  133. package/CHANGELOG.md +10 -0
  134. package/package.json +4 -4
  135. package/.docs/raw/workflows/input-data-mapping.mdx +0 -107
@@ -5,261 +5,304 @@ description: "Control flow in Mastra workflows allows you to manage branching, m
5
5
 
6
6
  # Control Flow
7
7
 
8
- When you build a workflow, you typically break down operations into smaller tasks that can be linked and reused. **Steps** provide a structured way to manage these tasks by defining inputs, outputs, and execution logic.
8
+ Workflows run a sequence of predefined tasks, and you can control how that flow is executed. Tasks are divided into **steps**, which can be executed in different ways depending on your requirements. They can run sequentially, in parallel, or follow different paths based on conditions.
9
9
 
10
- - If the schemas match, the `outputSchema` from each step is automatically passed to the `inputSchema` of the next step.
11
- - If the schemas don't match, use [Input data mapping](./input-data-mapping) to transform the `outputSchema` into the expected `inputSchema`.
10
+ Each step connects to the next in the workflow through defined schemas that keep data controlled and consistent.
11
+
12
+ ## Core principles
13
+
14
+ - The first step’s `inputSchema` must match the workflow’s `inputSchema`.
15
+ - The final step’s `outputSchema` must match the workflow’s `outputSchema`.
16
+ - Each step’s `outputSchema` must match the next step’s `inputSchema`.
17
+ - If it doesn’t, use [Input data mapping](#input-data-mapping) to transform the data into the required shape.
12
18
 
13
19
  ## Chaining steps with `.then()`
14
20
 
15
- Chain steps to execute sequentially using `.then()`:
21
+ Use `.then()` to run steps in order, allowing each step to access the result of the step before it.
16
22
 
17
23
  ![Chaining steps with .then()](/img/workflows/workflows-control-flow-then.jpg)
18
24
 
19
- ```typescript {8-9,4-5} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
20
- import { createWorkflow, createStep } from "@mastra/core/workflows";
21
- import { z } from "zod";
25
+ ```typescript {30-31} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
26
+ const step1 = createStep({
27
+ //...
28
+ inputSchema: z.object({
29
+ message: z.string()
30
+ }),
31
+ outputSchema: z.object({
32
+ formatted: z.string()
33
+ })
34
+ });
22
35
 
23
- const step1 = createStep({...});
24
- const step2 = createStep({...});
36
+ const step2 = createStep({
37
+ // ...
38
+ inputSchema: z.object({
39
+ formatted: z.string()
40
+ }),
41
+ outputSchema: z.object({
42
+ emphasized: z.string()
43
+ })
44
+ });
25
45
 
26
- export const testWorkflow = createWorkflow({...})
46
+ export const testWorkflow = createWorkflow({
47
+ // ...
48
+ inputSchema: z.object({
49
+ message: z.string()
50
+ }),
51
+ outputSchema: z.object({
52
+ emphasized: z.string()
53
+ })
54
+ })
27
55
  .then(step1)
28
56
  .then(step2)
29
57
  .commit();
30
58
  ```
31
59
 
32
- This does what you'd expect: it executes `step1`, then it executes `step2`.
33
-
34
60
  ## Simultaneous steps with `.parallel()`
35
61
 
36
- Execute steps simultaneously using `.parallel()`:
62
+ Use `.parallel()` to run steps at the same time. Each step's `id` is used when defining a following step's `inputSchema` and becomes the key on the `inputData` object used to access the previous step's values. The outputs of parallel steps can then be referenced or combined by a following step.
37
63
 
38
64
  ![Concurrent steps with .parallel()](/img/workflows/workflows-control-flow-parallel.jpg)
39
65
 
40
- ```typescript {9,4-5} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
41
- import { createWorkflow, createStep } from "@mastra/core/workflows";
42
- import { z } from "zod";
66
+ ```typescript {42} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
67
+ const step1 = createStep({
68
+ id: "step-1",
69
+ // ...
70
+ });
43
71
 
44
- const step1 = createStep({...});
45
- const step2 = createStep({...});
46
- const step3 = createStep({...});
72
+ const step2 = createStep({
73
+ id: "step-2",
74
+ // ...
75
+ });
47
76
 
48
- export const testWorkflow = createWorkflow({...})
77
+ const step3 = createStep({
78
+ id: "step-3",
79
+ inputSchema: z.object({
80
+ "step-1": z.object({
81
+ formatted: z.string()
82
+ }),
83
+ "step-2": z.object({
84
+ emphasized: z.string()
85
+ })
86
+ }),
87
+ outputSchema: z.object({
88
+ combined: z.string()
89
+ }),
90
+ execute: async ({ inputData }) => {
91
+ const { formatted } = inputData["step-1"];
92
+ const { emphasized } = inputData["step-2"];
93
+ return {
94
+ combined: `${formatted} | ${emphasized}`
95
+ };
96
+ }
97
+ });
98
+
99
+ export const testWorkflow = createWorkflow({
100
+ // ...
101
+ inputSchema: z.object({
102
+ message: z.string()
103
+ }),
104
+ outputSchema: z.object({
105
+ combined: z.string()
106
+ })
107
+ })
49
108
  .parallel([step1, step2])
50
109
  .then(step3)
51
110
  .commit();
52
111
  ```
53
112
 
54
- This executes `step1` and `step2` concurrently, then continues to `step3` after both complete.
55
-
56
- > See [Parallel Execution with Steps](/examples/workflows_legacy/parallel-steps) for more information.
57
-
58
113
  > 📹 Watch: How to run steps in parallel and optimize your Mastra workflow → [YouTube (3 minutes)](https://youtu.be/GQJxve5Hki4)
59
114
 
60
115
  ## Conditional logic with `.branch()`
61
116
 
62
- Execute steps conditionally using `.branch()`:
117
+ Use `.branch()` to choose which step to run based on a condition. All steps in a branch need the same `inputSchema` and `outputSchema` because branching requires consistent schemas so workflows can follow different paths.
63
118
 
64
119
  ![Conditional branching with .branch()](/img/workflows/workflows-control-flow-branch.jpg)
65
120
 
66
- ```typescript {8-11,4-5} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
67
- import { createWorkflow, createStep } from "@mastra/core/workflows";
68
- import { z } from "zod";
121
+ ```typescript {33-36} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
122
+ const step1 = createStep({...})
123
+
124
+ const stepA = createStep({
125
+ // ...
126
+ inputSchema: z.object({
127
+ value: z.number()
128
+ }),
129
+ outputSchema: z.object({
130
+ result: z.string()
131
+ })
132
+ });
69
133
 
70
- const lessThanStep = createStep({...});
71
- const greaterThanStep = createStep({...});
134
+ const stepB = createStep({
135
+ // ...
136
+ inputSchema: z.object({
137
+ value: z.number()
138
+ }),
139
+ outputSchema: z.object({
140
+ result: z.string()
141
+ })
142
+ });
72
143
 
73
- export const testWorkflow = createWorkflow({...})
144
+ export const testWorkflow = createWorkflow({
145
+ // ...
146
+ inputSchema: z.object({
147
+ value: z.number()
148
+ }),
149
+ outputSchema: z.object({
150
+ result: z.string()
151
+ })
152
+ })
153
+ .then(step1)
74
154
  .branch([
75
- [async ({ inputData: { value } }) => value <= 10, lessThanStep],
76
- [async ({ inputData: { value } }) => value > 10, greaterThanStep]
155
+ [async ({ inputData: { value } }) => value > 10, stepA],
156
+ [async ({ inputData: { value } }) => value <= 10, stepB]
77
157
  ])
78
158
  .commit();
79
159
  ```
80
160
 
81
- Branch conditions are evaluated sequentially, but steps with matching conditions are executed in parallel.
82
-
83
- > See [Workflow with Conditional Branching](/examples/workflows_legacy/conditional-branching) for more information.
84
-
85
- ## Looping steps
86
-
87
- Workflows support two types of loops. When looping a step, or any step-compatible construct like a nested workflow, the initial `inputData` is sourced from the output of the previous step.
88
-
89
- To ensure compatibility, the loop’s initial input must either match the shape of the previous step’s output, or be explicitly transformed using the `map` function.
90
-
91
- - Match the shape of the previous step’s output, or
92
- - Be explicitly transformed using the `map` function.
93
-
94
- ### Repeating with `.dowhile()`
95
-
96
- Executes step repeatedly while a condition is true.
97
-
98
- ![Repeating with .dowhile()](/img/workflows/workflows-control-flow-dowhile.jpg)
99
-
100
- ```typescript {7} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
101
- import { createWorkflow, createStep } from "@mastra/core/workflows";
102
- import { z } from "zod";
103
-
104
- const counterStep = createStep({...});
105
-
106
- export const testWorkflow = createWorkflow({...})
107
- .dowhile(counterStep, async ({ inputData: { number } }) => number < 10)
108
- .commit();
109
- ```
110
-
111
- ### Repeating with `.dountil()`
161
+ ## Input data mapping
112
162
 
113
- Executes step repeatedly until a condition becomes true.
163
+ When using `.then()`, `.parallel()`, or `.branch()`, it is sometimes necessary to transform the output of a previous step to match the input of the next. In these cases you can use `.map()` to access the `inputData` and transform it to create a suitable data shape for the next step.
114
164
 
115
- ![Repeating with .dountil()](/img/workflows/workflows-control-flow-dountil.jpg)
116
-
117
- ```typescript {7} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
118
- import { createWorkflow, createStep } from "@mastra/core/workflows";
119
- import { z } from "zod";
165
+ ![Mapping with .map()](/img/workflows/workflows-data-mapping-map.jpg)
120
166
 
121
- const counterStep = createStep({...});
167
+ ```typescript {9} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
168
+ const step1 = createStep({...});
169
+ const step2 = createStep({...});
122
170
 
123
171
  export const testWorkflow = createWorkflow({...})
124
- .dountil(counterStep, async ({ inputData: { number } }) => number > 10)
172
+ .then(step1)
173
+ .map(async ({ inputData }) => {
174
+ const { foo } = inputData;
175
+ return {
176
+ bar: `new ${foo}`,
177
+ };
178
+ })
179
+ .then(step2)
125
180
  .commit();
126
181
  ```
127
182
 
128
- ### Loop management
183
+ The `.map()` method provides additional helper functions for more complex mapping scenarios.
129
184
 
130
- Loop conditions can be implemented in different ways depending on how you want the loop to end. Common patterns include checking values returned in `inputData`, setting a maximum number of iterations, or aborting execution when a limit is reached.
131
-
132
- #### Conditional loops
185
+ **Available helper functions:**
133
186
 
134
- The `inputData` for a loop step is the output of a previous step. Use the values in `inputData` to determine whether the loop should continue or stop.
187
+ - [`getStepResult()`](/reference/workflows/workflow-methods/map#using-getstepresult): Access a specific step's full output
188
+ - [`getInitData()`](/reference/workflows/workflow-methods/map#using-getinitdata): Access the workflow's initial input data
189
+ - [`mapVariable()`](/reference/workflows/workflow-methods/map#using-mapvariable): Use declarative object syntax to extract and rename fields
135
190
 
136
- ```typescript {7} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
137
- import { createWorkflow, createStep } from "@mastra/core/workflows";
138
- import { z } from "zod";
191
+ ## Looping steps
139
192
 
140
- const counterStep = createStep({...});
193
+ Workflows support different looping methods that let you repeat steps until or while a condition is met, or iterate over arrays. Loops can be combined with other control methods like `.then()`.
141
194
 
142
- export const testWorkflow = createWorkflow({...})
143
- .dountil(nestedWorkflowStep, async ({ inputData: { userResponse } }) => userResponse === "yes")
144
- .commit();
145
- ```
195
+ ### Looping with `.dountil()`
146
196
 
147
- #### Limiting loops
197
+ Use `.dountil()` to run a step repeatedly until a condition becomes true.
148
198
 
149
- The `iterationCount` tracks how many times the loop step has run. You can use this to limit the number of iterations and prevent infinite loops. Combine it with `inputData` values to stop the loop after a set number of attempts.
199
+ ![Repeating with .dountil()](/img/workflows/workflows-control-flow-dountil.jpg)
150
200
 
151
- ```typescript {7} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
152
- import { createWorkflow, createStep } from "@mastra/core/workflows";
153
- import { z } from "zod";
201
+ ```typescript {17} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
202
+ const step1 = createStep({...});
154
203
 
155
- const counterStep = createStep({...});
204
+ const step2 = createStep({
205
+ // ...
206
+ execute: async ({ inputData }) => {
207
+ const { number } = inputData;
208
+ return {
209
+ number: number + 1
210
+ };
211
+ }
212
+ });
156
213
 
157
- export const testWorkflow = createWorkflow({...})
158
- .dountil(nestedWorkflowStep, async ({ inputData: { userResponse, iterationCount } }) => userResponse === "yes" || iterationCount >= 10)
159
- .commit();
214
+ export const testWorkflow = createWorkflow({
215
+ // ...
216
+ })
217
+ .then(step1)
218
+ .dountil(step2, async ({ inputData: { number } }) => number > 10)
219
+ .commit();
160
220
  ```
161
221
 
162
- #### Aborting loops
222
+ ### Looping with `.dowhile()`
163
223
 
164
- Use `iterationCount` to limit how many times a loop runs. If the count exceeds your threshold, throw an error to fail the step and stop the workflow.
224
+ Use `.dowhile()` to run a step repeatedly while a condition remains true.
165
225
 
166
- ```typescript {7} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
167
- import { createWorkflow, createStep } from "@mastra/core/workflows";
168
- import { z } from "zod";
226
+ ![Repeating with .dowhile()](/img/workflows/workflows-control-flow-dowhile.jpg)
169
227
 
170
- const counterStep = createStep({...});
228
+ ```typescript {17} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
229
+ const step1 = createStep({...});
171
230
 
172
- export const testWorkflow = createWorkflow({...})
173
- .dountil(nestedWorkflowStep, async ({ inputData: { userResponse, iterationCount } }) => {
174
- if (iterationCount >= 10) {
175
- throw new Error("Maximum iterations reached");
231
+ const step2 = createStep({
232
+ // ...
233
+ execute: async ({ inputData }) => {
234
+ const { number } = inputData;
235
+ return {
236
+ number: number + 1
237
+ };
176
238
  }
177
- return userResponse === "yes";
239
+ });
240
+
241
+ export const testWorkflow = createWorkflow({
242
+ // ...
178
243
  })
179
- .commit();
244
+ .then(step1)
245
+ .dowhile(step2, async ({ inputData: { number } }) => number < 10)
246
+ .commit();
180
247
  ```
181
248
 
182
- ### Repeating with `.foreach()`
249
+ ### Looping with `.foreach()`
183
250
 
184
- Sequentially executes the same step for each item from the `inputSchema`.
251
+ Use `.foreach()` to run the same step for each item in an array. The input must be of type `array` so the loop can iterate over its values, applying the step’s logic to each one.
185
252
 
186
253
  ![Repeating with .foreach()](/img/workflows/workflows-control-flow-foreach.jpg)
187
254
 
188
- ```typescript {7} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
189
- import { createWorkflow, createStep } from "@mastra/core/workflows";
190
- import { z } from "zod";
255
+ ```typescript {17} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
256
+ const step1 = createStep({
257
+ // ...
258
+ inputSchema: z.string(),
259
+ outputSchema: z.string(),
260
+ execute: async ({ inputData }) => {
261
+ return inputData.toUpperCase();
262
+ }
263
+ });
191
264
 
192
- const mapStep = createStep({...});
265
+ const step2 = createStep({...});
193
266
 
194
- export const testWorkflow = createWorkflow({...})
195
- .foreach(mapStep)
267
+ export const testWorkflow = createWorkflow({
268
+ // ...
269
+ inputSchema: z.array(z.string()),
270
+ outputSchema: z.array(z.string())
271
+ })
272
+ .foreach(step1)
273
+ .then(step2)
196
274
  .commit();
197
275
  ```
198
276
 
199
- #### Setting concurrency limits
277
+ #### Concurrency limits
200
278
 
201
- Use `concurrency` to execute steps in parallel with a limit on the number of concurrent executions.
279
+ Use `concurrency` to control the number of array items processed at the same time. The default is `1`, which runs steps sequentially. Increasing the value allows `.foreach()` to process multiple items simultaneously.
202
280
 
203
- ```typescript {7} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
204
- import { createWorkflow, createStep } from "@mastra/core/workflows";
205
- import { z } from "zod";
206
-
207
- const mapStep = createStep({...})
281
+ ```typescript title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
282
+ const step1 = createStep({...})
208
283
 
209
284
  export const testWorkflow = createWorkflow({...})
210
- .foreach(mapStep, { concurrency: 2 })
285
+ .foreach(step1, { concurrency: 4 })
211
286
  .commit();
212
287
  ```
213
288
 
214
- ## Using a nested workflow
215
-
216
- Use a nested workflow as a step by passing it to `.then()`. This runs each of its steps in sequence as part of the parent workflow.
217
-
218
- ```typescript {4,7} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
219
- import { createWorkflow, createStep } from "@mastra/core/workflows";
220
- import { z } from "zod";
289
+ ## Loop management
221
290
 
222
- export const nestedWorkflow = createWorkflow({...})
223
-
224
- export const testWorkflow = createWorkflow({...})
225
- .then(nestedWorkflow)
226
- .commit();
227
- ```
228
-
229
- ## Cloning a workflow
291
+ Loop conditions can be implemented in different ways depending on how you want the loop to end. Common patterns include checking values returned in `inputData`, setting a maximum number of iterations, or aborting execution when a limit is reached.
230
292
 
231
- Use `cloneWorkflow` to duplicate an existing workflow. This lets you reuse its structure while overriding parameters like `id`.
293
+ ### Aborting loops
232
294
 
233
- ```typescript {6,10} title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
234
- import { createWorkflow, createStep, cloneWorkflow } from "@mastra/core/workflows";
235
- import { z } from "zod";
295
+ Use `iterationCount` to limit how many times a loop runs. If the count exceeds your threshold, throw an error to fail the step and stop the workflow.
236
296
 
297
+ ```typescript title="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
237
298
  const step1 = createStep({...});
238
- const parentWorkflow = createWorkflow({...})
239
- const clonedWorkflow = cloneWorkflow(parentWorkflow, { id: "cloned-workflow" });
240
299
 
241
300
  export const testWorkflow = createWorkflow({...})
242
- .then(step1)
243
- .then(clonedWorkflow)
301
+ .dountil(step1, async ({ inputData: { userResponse, iterationCount } }) => {
302
+ if (iterationCount >= 10) {
303
+ throw new Error("Maximum iterations reached");
304
+ }
305
+ return userResponse === "yes";
306
+ })
244
307
  .commit();
245
308
  ```
246
-
247
- ## Example Run Instance
248
-
249
- The following example demonstrates how to start a run with multiple inputs. Each input will pass through the `mapStep` sequentially.
250
-
251
- ```typescript {6} title="src/test-workflow.ts" showLineNumbers copy
252
- import { mastra } from "./mastra";
253
-
254
- const run = await mastra.getWorkflow("testWorkflow").createRunAsync();
255
-
256
- const result = await run.start({
257
- inputData: [{ number: 10 }, { number: 100 }, { number: 200 }],
258
- });
259
- ```
260
-
261
- To execute this run from your terminal:
262
-
263
- ```bash copy
264
- npx tsx src/test-workflow.ts
265
- ```
@@ -35,7 +35,7 @@ In development
35
35
 
36
36
  ```ts showLineNumbers copy title="src/mastra/inngest/index.ts"
37
37
  import { Inngest } from "inngest";
38
- import { realtimeMiddleware } from "@inngest/realtime";
38
+ import { realtimeMiddleware } from "@inngest/realtime/middleware";
39
39
 
40
40
  export const inngest = new Inngest({
41
41
  id: "mastra",
@@ -49,7 +49,7 @@ In production
49
49
 
50
50
  ```ts showLineNumbers copy title="src/mastra/inngest/index.ts"
51
51
  import { Inngest } from "inngest";
52
- import { realtimeMiddleware } from "@inngest/realtime";
52
+ import { realtimeMiddleware } from "@inngest/realtime/middleware";
53
53
 
54
54
  export const inngest = new Inngest({
55
55
  id: "mastra",