@mastra/mcp-docs-server 0.0.3 → 0.0.4-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.
- package/.docs/organized/changelogs/%40mastra%2Fastra.md +27 -27
- package/.docs/organized/changelogs/%40mastra%2Fchroma.md +27 -27
- package/.docs/organized/changelogs/%40mastra%2Fclient-js.md +29 -29
- package/.docs/organized/changelogs/%40mastra%2Fcomposio.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fcore.md +23 -23
- package/.docs/organized/changelogs/%40mastra%2Fdeployer-cloudflare.md +36 -36
- package/.docs/organized/changelogs/%40mastra%2Fdeployer-netlify.md +35 -35
- package/.docs/organized/changelogs/%40mastra%2Fdeployer-vercel.md +35 -35
- package/.docs/organized/changelogs/%40mastra%2Fdeployer.md +32 -32
- package/.docs/organized/changelogs/%40mastra%2Fevals.md +27 -27
- package/.docs/organized/changelogs/%40mastra%2Ffirecrawl.md +29 -29
- package/.docs/organized/changelogs/%40mastra%2Fgithub.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Floggers.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fmcp-docs-server.md +26 -0
- package/.docs/organized/changelogs/%40mastra%2Fmcp.md +27 -27
- package/.docs/organized/changelogs/%40mastra%2Fmemory.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fpg.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fpinecone.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fplayground-ui.md +35 -35
- package/.docs/organized/changelogs/%40mastra%2Fqdrant.md +27 -27
- package/.docs/organized/changelogs/%40mastra%2Frag.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fragie.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fspeech-azure.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fspeech-deepgram.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fspeech-elevenlabs.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fspeech-google.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fspeech-ibm.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fspeech-murf.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fspeech-openai.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fspeech-playai.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fspeech-replicate.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fspeech-speechify.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fstabilityai.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fturbopuffer.md +25 -0
- package/.docs/organized/changelogs/%40mastra%2Fupstash.md +31 -31
- package/.docs/organized/changelogs/%40mastra%2Fvectorize.md +30 -30
- package/.docs/organized/changelogs/%40mastra%2Fvoice-azure.md +9 -0
- package/.docs/organized/changelogs/%40mastra%2Fvoice-cloudflare.md +9 -0
- package/.docs/organized/changelogs/%40mastra%2Fvoice-deepgram.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fvoice-elevenlabs.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fvoice-google.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fvoice-murf.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fvoice-openai-realtime.md +25 -0
- package/.docs/organized/changelogs/%40mastra%2Fvoice-openai.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fvoice-playai.md +26 -26
- package/.docs/organized/changelogs/%40mastra%2Fvoice-sarvam.md +27 -0
- package/.docs/organized/changelogs/%40mastra%2Fvoice-speechify.md +26 -26
- package/.docs/organized/changelogs/create-mastra.md +22 -22
- package/.docs/organized/changelogs/mastra.md +47 -47
- package/.docs/organized/code-examples/ai-sdk-useChat.md +2 -1
- package/.docs/raw/agents/02-adding-tools.mdx +6 -0
- package/.docs/raw/agents/02a-mcp-guide.mdx +192 -0
- package/.docs/raw/agents/03-adding-voice.mdx +8 -8
- package/.docs/raw/deployment/deployment.mdx +5 -42
- package/.docs/raw/deployment/server.mdx +45 -3
- package/.docs/raw/evals/00-overview.mdx +2 -2
- package/.docs/raw/evals/03-running-in-ci.mdx +7 -4
- package/.docs/raw/getting-started/mcp-docs-server.mdx +5 -2
- package/.docs/raw/guides/04-research-assistant.mdx +273 -0
- package/.docs/raw/local-dev/mastra-dev.mdx +2 -2
- package/.docs/raw/observability/logging.mdx +38 -0
- package/.docs/raw/observability/nextjs-tracing.mdx +102 -0
- package/.docs/raw/observability/tracing.mdx +110 -0
- package/.docs/raw/rag/overview.mdx +3 -3
- package/.docs/raw/rag/retrieval.mdx +7 -4
- package/.docs/raw/rag/vector-databases.mdx +107 -40
- package/.docs/raw/reference/client-js/memory.mdx +6 -3
- package/.docs/raw/reference/client-js/workflows.mdx +1 -0
- package/.docs/raw/reference/observability/providers/langsmith.mdx +2 -0
- package/.docs/raw/reference/rag/libsql.mdx +3 -3
- package/.docs/raw/reference/rag/upstash.mdx +50 -1
- package/.docs/raw/reference/rag/vectorize.mdx +48 -3
- package/.docs/raw/reference/tools/client.mdx +10 -2
- package/.docs/raw/reference/tools/vector-query-tool.mdx +1 -1
- package/.docs/raw/reference/voice/sarvam.mdx +260 -0
- package/.docs/raw/reference/workflows/afterEvent.mdx +76 -0
- package/.docs/raw/reference/workflows/events.mdx +305 -0
- package/.docs/raw/reference/workflows/resumeWithEvent.mdx +134 -0
- package/.docs/raw/reference/workflows/snapshots.mdx +204 -0
- package/.docs/raw/reference/workflows/step-retries.mdx +203 -0
- package/.docs/raw/voice/overview.mdx +135 -0
- package/.docs/raw/voice/speech-to-text.mdx +45 -0
- package/.docs/raw/voice/text-to-speech.mdx +52 -0
- package/.docs/raw/voice/voice-to-voice.mdx +310 -0
- package/.docs/raw/workflows/dynamic-workflows.mdx +4 -0
- package/.docs/raw/workflows/error-handling.mdx +183 -0
- package/.docs/raw/workflows/steps.mdx +12 -2
- package/.docs/raw/workflows/suspend-and-resume.mdx +207 -2
- package/.docs/raw/workflows/variables.mdx +23 -3
- package/dist/_tsup-dts-rollup.d.ts +83 -0
- package/dist/chunk-YEOOTUPA.js +191 -0
- package/dist/prepare-docs/prepare.d.ts +1 -1
- package/dist/prepare-docs/prepare.js +1 -13
- package/dist/stdio.d.ts +0 -1
- package/dist/stdio.js +352 -5
- package/package.json +9 -15
- package/.docs/raw/deployment/logging-and-tracing.mdx +0 -242
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -19
- package/dist/prepare-docs/code-examples.d.ts +0 -4
- package/dist/prepare-docs/code-examples.js +0 -91
- package/dist/prepare-docs/copy-raw.d.ts +0 -1
- package/dist/prepare-docs/copy-raw.js +0 -41
- package/dist/prepare-docs/index.d.ts +0 -1
- package/dist/prepare-docs/index.js +0 -8
- package/dist/prepare-docs/package-changes.d.ts +0 -4
- package/dist/prepare-docs/package-changes.js +0 -92
- package/dist/sse.d.ts +0 -1
- package/dist/sse.js +0 -9
- package/dist/tools/__tests__/blog.test.d.ts +0 -1
- package/dist/tools/__tests__/blog.test.js +0 -48
- package/dist/tools/__tests__/changes.test.d.ts +0 -1
- package/dist/tools/__tests__/changes.test.js +0 -37
- package/dist/tools/__tests__/docs.test.d.ts +0 -1
- package/dist/tools/__tests__/docs.test.js +0 -46
- package/dist/tools/__tests__/examples.test.d.ts +0 -1
- package/dist/tools/__tests__/examples.test.js +0 -53
- package/dist/tools/blog.d.ts +0 -15
- package/dist/tools/blog.js +0 -73
- package/dist/tools/changes.d.ts +0 -11
- package/dist/tools/changes.js +0 -69
- package/dist/tools/docs.d.ts +0 -11
- package/dist/tools/docs.js +0 -176
- package/dist/tools/examples.d.ts +0 -11
- package/dist/tools/examples.js +0 -61
- package/dist/utils.d.ts +0 -6
- package/dist/utils.js +0 -9
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Reference: Sarvam Voice | Voice Providers | Mastra Docs"
|
|
3
|
+
description: "Documentation for the Sarvam class, providing text-to-speech and speech-to-text capabilities."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Sarvam
|
|
7
|
+
|
|
8
|
+
The SarvamVoice class in Mastra provides text-to-speech and speech-to-text capabilities using Sarvam AI models.
|
|
9
|
+
|
|
10
|
+
## Usage Example
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
import { SarvamVoice } from "@mastra/voice-sarvam";
|
|
14
|
+
|
|
15
|
+
// Initialize with default configuration using environment variables
|
|
16
|
+
const voice = new SarvamVoice();
|
|
17
|
+
|
|
18
|
+
// Or initialize with specific configuration
|
|
19
|
+
const voiceWithConfig = new SarvamVoice({
|
|
20
|
+
speechModel: {
|
|
21
|
+
model: "bulbul:v1",
|
|
22
|
+
apiKey: process.env.SARVAM_API_KEY!,
|
|
23
|
+
language: "en-IN",
|
|
24
|
+
properties: {
|
|
25
|
+
pitch: 0,
|
|
26
|
+
pace: 1.65,
|
|
27
|
+
loudness: 1.5,
|
|
28
|
+
speech_sample_rate: 8000,
|
|
29
|
+
enable_preprocessing: false,
|
|
30
|
+
eng_interpolation_wt: 123,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
listeningModel: {
|
|
34
|
+
model: "saarika:v2",
|
|
35
|
+
apiKey: process.env.SARVAM_API_KEY!,
|
|
36
|
+
languageCode: "en-IN",
|
|
37
|
+
filetype?: 'wav';
|
|
38
|
+
},
|
|
39
|
+
speaker: "meera", // Default voice
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
// Convert text to speech
|
|
44
|
+
const audioStream = await voice.speak("Hello, how can I help you?");
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
// Convert speech to text
|
|
48
|
+
const text = await voice.listen(audioStream, {
|
|
49
|
+
filetype: "wav",
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Sarvam API Docs -
|
|
54
|
+
|
|
55
|
+
https://docs.sarvam.ai/api-reference-docs/endpoints/text-to-speech
|
|
56
|
+
|
|
57
|
+
## Configuration
|
|
58
|
+
|
|
59
|
+
### Constructor Options
|
|
60
|
+
|
|
61
|
+
<PropertiesTable
|
|
62
|
+
content={[
|
|
63
|
+
{
|
|
64
|
+
name: "speechModel",
|
|
65
|
+
type: "SarvamVoiceConfig",
|
|
66
|
+
description: "Configuration for text-to-speech synthesis.",
|
|
67
|
+
isOptional: true,
|
|
68
|
+
defaultValue: "{ model: 'bulbul:v1', language: 'en-IN' }",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: "speaker",
|
|
72
|
+
type: "SarvamVoiceId",
|
|
73
|
+
description:
|
|
74
|
+
"The speaker to be used for the output audio. If not provided, Meera will be used as default. AvailableOptions - meera, pavithra, maitreyi, arvind, amol, amartya, diya, neel, misha, vian, arjun, maya",
|
|
75
|
+
isOptional: true,
|
|
76
|
+
defaultValue: "'meera'",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: "listeningModel",
|
|
80
|
+
type: "SarvamListenOptions",
|
|
81
|
+
description: "Configuration for speech-to-text recognition.",
|
|
82
|
+
isOptional: true,
|
|
83
|
+
defaultValue: "{ model: 'saarika:v2', language_code: 'unknown' }",
|
|
84
|
+
},
|
|
85
|
+
]}
|
|
86
|
+
/>
|
|
87
|
+
|
|
88
|
+
### SarvamVoiceConfig
|
|
89
|
+
|
|
90
|
+
<PropertiesTable
|
|
91
|
+
content={[
|
|
92
|
+
{
|
|
93
|
+
name: "apiKey",
|
|
94
|
+
type: "string",
|
|
95
|
+
description:
|
|
96
|
+
"Sarvam API key. Falls back to SARVAM_API_KEY environment variable.",
|
|
97
|
+
isOptional: true,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "model",
|
|
101
|
+
type: "SarvamTTSModel",
|
|
102
|
+
description: "Specifies the model to use for text-to-speech conversion.",
|
|
103
|
+
isOptional: true,
|
|
104
|
+
defaultValue: "'bulbul:v1'",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: "language",
|
|
108
|
+
type: "SarvamTTSLanguage",
|
|
109
|
+
description:
|
|
110
|
+
"Target language for speech synthesis. Available options: hi-IN, bn-IN, kn-IN, ml-IN, mr-IN, od-IN, pa-IN, ta-IN, te-IN, en-IN, gu-IN",
|
|
111
|
+
isOptional: false,
|
|
112
|
+
defaultValue: "'en-IN'",
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: "properties",
|
|
116
|
+
type: "object",
|
|
117
|
+
description: "Additional voice properties for customization.",
|
|
118
|
+
isOptional: true,
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "properties.pitch",
|
|
122
|
+
type: "number",
|
|
123
|
+
description:
|
|
124
|
+
"Controls the pitch of the audio. Lower values result in a deeper voice, while higher values make it sharper. The suitable range is between -0.75 and 0.75.",
|
|
125
|
+
isOptional: true,
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: "properties.pace",
|
|
129
|
+
type: "number",
|
|
130
|
+
description:
|
|
131
|
+
"Controls the speed of the audio. Lower values result in slower speech, while higher values make it faster. The suitable range is between 0.5 and 2.0. Default is 1.0. Required range: 0.3 <= x <= 3",
|
|
132
|
+
isOptional: true,
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: "properties.loudness",
|
|
136
|
+
type: "number",
|
|
137
|
+
description:
|
|
138
|
+
"Controls the loudness of the audio. Lower values result in quieter audio, while higher values make it louder. The suitable range is between 0.3 and 3.0. Required range: 0 <= x <= 3",
|
|
139
|
+
isOptional: true,
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: "properties.speech_sample_rate",
|
|
143
|
+
type: "8000 | 16000 | 22050",
|
|
144
|
+
description: "Audio sample rate in Hz.",
|
|
145
|
+
isOptional: true,
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: "properties.enable_preprocessing",
|
|
149
|
+
type: "boolean",
|
|
150
|
+
description:
|
|
151
|
+
"Controls whether normalization of English words and numeric entities (e.g., numbers, dates) is performed. Set to true for better handling of mixed-language text. Default is false.",
|
|
152
|
+
isOptional: true,
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: "properties.eng_interpolation_wt",
|
|
156
|
+
type: "number",
|
|
157
|
+
description: "Weight for interpolating with English speaker at encoder.",
|
|
158
|
+
isOptional: true,
|
|
159
|
+
},
|
|
160
|
+
]}
|
|
161
|
+
/>
|
|
162
|
+
|
|
163
|
+
### SarvamListenOptions
|
|
164
|
+
|
|
165
|
+
<PropertiesTable
|
|
166
|
+
content={[
|
|
167
|
+
{
|
|
168
|
+
name: "apiKey",
|
|
169
|
+
type: "string",
|
|
170
|
+
description:
|
|
171
|
+
"Sarvam API key. Falls back to SARVAM_API_KEY environment variable.",
|
|
172
|
+
isOptional: true,
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: "model",
|
|
176
|
+
type: "SarvamSTTModel",
|
|
177
|
+
description:
|
|
178
|
+
"Specifies the model to use for speech-to-text conversion. Note:- Default model is saarika:v2 . Available options: saarika:v1, saarika:v2, saarika:flash ",
|
|
179
|
+
isOptional: true,
|
|
180
|
+
defaultValue: "'saarika:v2'",
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: "languageCode",
|
|
184
|
+
type: "SarvamSTTLanguage",
|
|
185
|
+
description:
|
|
186
|
+
"Specifies the language of the input audio. This parameter is required to ensure accurate transcription. For the saarika:v1 model, this parameter is mandatory. For the saarika:v2 model, it is optional. unknown: Use this when the language is not known; the API will detect it automatically. Note:- that the saarika:v1 model does not support unknown language code. Available options: unknown, hi-IN, bn-IN, kn-IN, ml-IN, mr-IN, od-IN, pa-IN, ta-IN, te-IN, en-IN, gu-IN ",
|
|
187
|
+
isOptional: true,
|
|
188
|
+
defaultValue: "'unknown'",
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: "filetype",
|
|
192
|
+
type: "'mp3' | 'wav'",
|
|
193
|
+
description: "Audio format of the input stream.",
|
|
194
|
+
isOptional: true,
|
|
195
|
+
},
|
|
196
|
+
]}
|
|
197
|
+
/>
|
|
198
|
+
|
|
199
|
+
## Methods
|
|
200
|
+
|
|
201
|
+
### speak()
|
|
202
|
+
|
|
203
|
+
Converts text to speech using Sarvam's text-to-speech models.
|
|
204
|
+
|
|
205
|
+
<PropertiesTable
|
|
206
|
+
content={[
|
|
207
|
+
{
|
|
208
|
+
name: "input",
|
|
209
|
+
type: "string | NodeJS.ReadableStream",
|
|
210
|
+
description: "Text or text stream to convert to speech.",
|
|
211
|
+
isOptional: false,
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
name: "options.speaker",
|
|
215
|
+
type: "SarvamVoiceId",
|
|
216
|
+
description: "Voice ID to use for speech synthesis.",
|
|
217
|
+
isOptional: true,
|
|
218
|
+
defaultValue: "Constructor's speaker value",
|
|
219
|
+
},
|
|
220
|
+
]}
|
|
221
|
+
/>
|
|
222
|
+
|
|
223
|
+
Returns: `Promise<NodeJS.ReadableStream>`
|
|
224
|
+
|
|
225
|
+
### listen()
|
|
226
|
+
|
|
227
|
+
Transcribes audio using Sarvam's speech recognition models.
|
|
228
|
+
|
|
229
|
+
<PropertiesTable
|
|
230
|
+
content={[
|
|
231
|
+
{
|
|
232
|
+
name: "input",
|
|
233
|
+
type: "NodeJS.ReadableStream",
|
|
234
|
+
description: "Audio stream to transcribe.",
|
|
235
|
+
isOptional: false,
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
name: "options",
|
|
239
|
+
type: "SarvamListenOptions",
|
|
240
|
+
description: "Configuration options for speech recognition.",
|
|
241
|
+
isOptional: true,
|
|
242
|
+
},
|
|
243
|
+
]}
|
|
244
|
+
/>
|
|
245
|
+
|
|
246
|
+
Returns: `Promise<string>`
|
|
247
|
+
|
|
248
|
+
### getSpeakers()
|
|
249
|
+
|
|
250
|
+
Returns an array of available voice options.
|
|
251
|
+
|
|
252
|
+
Returns: `Promise<Array<{voiceId: SarvamVoiceId}>>`
|
|
253
|
+
|
|
254
|
+
## Notes
|
|
255
|
+
|
|
256
|
+
- API key can be provided via constructor options or the `SARVAM_API_KEY` environment variable
|
|
257
|
+
- If no API key is provided, the constructor will throw an error
|
|
258
|
+
- The service communicates with the Sarvam AI API at `https://api.sarvam.ai`
|
|
259
|
+
- Audio is returned as a stream containing binary audio data
|
|
260
|
+
- Speech recognition supports mp3 and wav audio formats
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: ".afterEvent() Method | Mastra Docs"
|
|
3
|
+
description: "Reference for the afterEvent method in Mastra workflows that creates event-based suspension points."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# afterEvent()
|
|
7
|
+
|
|
8
|
+
The `afterEvent()` method creates a suspension point in your workflow that waits for a specific event to occur before continuing execution.
|
|
9
|
+
|
|
10
|
+
## Syntax
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
workflow.afterEvent(eventName: string): Workflow
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Parameters
|
|
17
|
+
|
|
18
|
+
| Parameter | Type | Description |
|
|
19
|
+
|-----------|------|-------------|
|
|
20
|
+
| eventName | string | The name of the event to wait for. Must match an event defined in the workflow's `events` configuration. |
|
|
21
|
+
|
|
22
|
+
## Return Value
|
|
23
|
+
|
|
24
|
+
Returns the workflow instance for method chaining.
|
|
25
|
+
|
|
26
|
+
## Description
|
|
27
|
+
|
|
28
|
+
The `afterEvent()` method is used to create an automatic suspension point in your workflow that waits for a specific named event. It's essentially a declarative way to define a point where your workflow should pause and wait for an external event to occur.
|
|
29
|
+
|
|
30
|
+
When you call `afterEvent()`, Mastra:
|
|
31
|
+
|
|
32
|
+
1. Creates a special step with ID `__eventName_event`
|
|
33
|
+
2. This step automatically suspends the workflow execution
|
|
34
|
+
3. The workflow remains suspended until the specified event is triggered via `resumeWithEvent()`
|
|
35
|
+
4. When the event occurs, execution continues with the step following the `afterEvent()` call
|
|
36
|
+
|
|
37
|
+
This method is part of Mastra's event-driven workflow capabilities, allowing you to create workflows that coordinate with external systems or user interactions without manually implementing suspension logic.
|
|
38
|
+
|
|
39
|
+
## Usage Notes
|
|
40
|
+
|
|
41
|
+
- The event specified in `afterEvent()` must be defined in the workflow's `events` configuration with a schema
|
|
42
|
+
- The special step created has a predictable ID format: `__eventName_event` (e.g., `__approvalReceived_event`)
|
|
43
|
+
- Any step following `afterEvent()` can access the event data via `context.inputData.resumedEvent`
|
|
44
|
+
- Event data is validated against the schema defined for that event when `resumeWithEvent()` is called
|
|
45
|
+
|
|
46
|
+
## Examples
|
|
47
|
+
|
|
48
|
+
### Basic Usage
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
// Define workflow with events
|
|
52
|
+
const workflow = new Workflow({
|
|
53
|
+
name: 'approval-workflow',
|
|
54
|
+
events: {
|
|
55
|
+
approval: {
|
|
56
|
+
schema: z.object({
|
|
57
|
+
approved: z.boolean(),
|
|
58
|
+
approverName: z.string(),
|
|
59
|
+
}),
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Build workflow with event suspension point
|
|
65
|
+
workflow
|
|
66
|
+
.step(submitRequest)
|
|
67
|
+
.afterEvent('approval') // Workflow suspends here
|
|
68
|
+
.step(processApproval) // This step runs after the event occurs
|
|
69
|
+
.commit();
|
|
70
|
+
```
|
|
71
|
+
## Related
|
|
72
|
+
|
|
73
|
+
- [Event-Driven Workflows](./events.mdx)
|
|
74
|
+
- [resumeWithEvent()](./resumeWithEvent.mdx)
|
|
75
|
+
- [Suspend and Resume](../../workflows/suspend-and-resume.mdx)
|
|
76
|
+
- [Workflow Class](./workflow.mdx)
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Event-Driven Workflows | Mastra Docs"
|
|
3
|
+
description: "Learn how to create event-driven workflows using afterEvent and resumeWithEvent methods in Mastra."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Event-Driven Workflows
|
|
7
|
+
|
|
8
|
+
Mastra provides built-in support for event-driven workflows through the `afterEvent` and `resumeWithEvent` methods. These methods allow you to create workflows that pause execution while waiting for specific events to occur, then resume with the event data when it's available.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Event-driven workflows are useful for scenarios where:
|
|
13
|
+
|
|
14
|
+
- You need to wait for external systems to complete processing
|
|
15
|
+
- User approval or input is required at specific points
|
|
16
|
+
- Asynchronous operations need to be coordinated
|
|
17
|
+
- Long-running processes need to break up execution across different services
|
|
18
|
+
|
|
19
|
+
## Defining Events
|
|
20
|
+
|
|
21
|
+
Before using event-driven methods, you must define the events your workflow will listen for in the workflow configuration:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { Workflow } from '@mastra/core/workflows';
|
|
25
|
+
import { z } from 'zod';
|
|
26
|
+
|
|
27
|
+
const workflow = new Workflow({
|
|
28
|
+
name: 'approval-workflow',
|
|
29
|
+
triggerSchema: z.object({ requestId: z.string() }),
|
|
30
|
+
events: {
|
|
31
|
+
// Define events with their validation schemas
|
|
32
|
+
approvalReceived: {
|
|
33
|
+
schema: z.object({
|
|
34
|
+
approved: z.boolean(),
|
|
35
|
+
approverName: z.string(),
|
|
36
|
+
comment: z.string().optional(),
|
|
37
|
+
}),
|
|
38
|
+
},
|
|
39
|
+
documentUploaded: {
|
|
40
|
+
schema: z.object({
|
|
41
|
+
documentId: z.string(),
|
|
42
|
+
documentType: z.enum(['invoice', 'receipt', 'contract']),
|
|
43
|
+
metadata: z.record(z.string()).optional(),
|
|
44
|
+
}),
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Each event must have a name and a schema that defines the structure of data expected when the event occurs.
|
|
51
|
+
|
|
52
|
+
## afterEvent()
|
|
53
|
+
|
|
54
|
+
The `afterEvent` method creates a suspension point in your workflow that automatically waits for a specific event.
|
|
55
|
+
|
|
56
|
+
### Syntax
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
workflow.afterEvent(eventName: string): Workflow
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Parameters
|
|
63
|
+
|
|
64
|
+
- `eventName`: The name of the event to wait for (must be defined in the workflow's `events` configuration)
|
|
65
|
+
|
|
66
|
+
### Return Value
|
|
67
|
+
|
|
68
|
+
Returns the workflow instance for method chaining.
|
|
69
|
+
|
|
70
|
+
### How It Works
|
|
71
|
+
|
|
72
|
+
When `afterEvent` is called, Mastra:
|
|
73
|
+
|
|
74
|
+
1. Creates a special step with ID `__eventName_event`
|
|
75
|
+
2. Configures this step to automatically suspend workflow execution
|
|
76
|
+
3. Sets up the continuation point after the event is received
|
|
77
|
+
|
|
78
|
+
### Usage Example
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
workflow
|
|
82
|
+
.step(initialProcessStep)
|
|
83
|
+
.afterEvent('approvalReceived') // Workflow suspends here
|
|
84
|
+
.step(postApprovalStep) // This runs after event is received
|
|
85
|
+
.then(finalStep)
|
|
86
|
+
.commit();
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## resumeWithEvent()
|
|
90
|
+
|
|
91
|
+
The `resumeWithEvent` method resumes a suspended workflow by providing data for a specific event.
|
|
92
|
+
|
|
93
|
+
### Syntax
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
run.resumeWithEvent(eventName: string, data: any): Promise<WorkflowRunResult>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Parameters
|
|
100
|
+
|
|
101
|
+
- `eventName`: The name of the event being triggered
|
|
102
|
+
- `data`: The event data (must conform to the schema defined for this event)
|
|
103
|
+
|
|
104
|
+
### Return Value
|
|
105
|
+
|
|
106
|
+
Returns a Promise that resolves to the workflow execution results after resumption.
|
|
107
|
+
|
|
108
|
+
### How It Works
|
|
109
|
+
|
|
110
|
+
When `resumeWithEvent` is called, Mastra:
|
|
111
|
+
|
|
112
|
+
1. Validates the event data against the schema defined for that event
|
|
113
|
+
2. Loads the workflow snapshot
|
|
114
|
+
3. Updates the context with the event data
|
|
115
|
+
4. Resumes execution from the event step
|
|
116
|
+
5. Continues workflow execution with the subsequent steps
|
|
117
|
+
|
|
118
|
+
### Usage Example
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// Create a workflow run
|
|
122
|
+
const run = workflow.createRun();
|
|
123
|
+
|
|
124
|
+
// Start the workflow
|
|
125
|
+
await run.start({ triggerData: { requestId: 'req-123' } });
|
|
126
|
+
|
|
127
|
+
// Later, when the event occurs:
|
|
128
|
+
const result = await run.resumeWithEvent('approvalReceived', {
|
|
129
|
+
approved: true,
|
|
130
|
+
approverName: 'John Doe',
|
|
131
|
+
comment: 'Looks good to me!'
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
console.log(result.results);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Accessing Event Data
|
|
138
|
+
|
|
139
|
+
When a workflow is resumed with event data, that data is available in the step context as `context.inputData.resumedEvent`:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
const processApprovalStep = new Step({
|
|
143
|
+
id: 'processApproval',
|
|
144
|
+
execute: async ({ context }) => {
|
|
145
|
+
// Access the event data
|
|
146
|
+
const eventData = context.inputData.resumedEvent;
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
processingResult: `Processed approval from ${eventData.approverName}`,
|
|
150
|
+
wasApproved: eventData.approved,
|
|
151
|
+
};
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Multiple Events
|
|
157
|
+
|
|
158
|
+
You can create workflows that wait for multiple different events at various points:
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
workflow
|
|
162
|
+
.step(createRequest)
|
|
163
|
+
.afterEvent('approvalReceived')
|
|
164
|
+
.step(processApproval)
|
|
165
|
+
.afterEvent('documentUploaded')
|
|
166
|
+
.step(processDocument)
|
|
167
|
+
.commit();
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
When resuming a workflow with multiple event suspension points, you need to provide the correct event name and data for the current suspension point.
|
|
171
|
+
|
|
172
|
+
## Practical Example
|
|
173
|
+
|
|
174
|
+
This example shows a complete workflow that requires both approval and document upload:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { Workflow, Step } from '@mastra/core/workflows';
|
|
178
|
+
import { z } from 'zod';
|
|
179
|
+
|
|
180
|
+
// Define steps
|
|
181
|
+
const createRequest = new Step({
|
|
182
|
+
id: 'createRequest',
|
|
183
|
+
execute: async () => ({ requestId: `req-${Date.now()}` }),
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const processApproval = new Step({
|
|
187
|
+
id: 'processApproval',
|
|
188
|
+
execute: async ({ context }) => {
|
|
189
|
+
const approvalData = context.inputData.resumedEvent;
|
|
190
|
+
return {
|
|
191
|
+
approved: approvalData.approved,
|
|
192
|
+
approver: approvalData.approverName,
|
|
193
|
+
};
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const processDocument = new Step({
|
|
198
|
+
id: 'processDocument',
|
|
199
|
+
execute: async ({ context }) => {
|
|
200
|
+
const documentData = context.inputData.resumedEvent;
|
|
201
|
+
return {
|
|
202
|
+
documentId: documentData.documentId,
|
|
203
|
+
processed: true,
|
|
204
|
+
type: documentData.documentType,
|
|
205
|
+
};
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
const finalizeRequest = new Step({
|
|
210
|
+
id: 'finalizeRequest',
|
|
211
|
+
execute: async ({ context }) => {
|
|
212
|
+
const requestId = context.steps.createRequest.output.requestId;
|
|
213
|
+
const approved = context.steps.processApproval.output.approved;
|
|
214
|
+
const documentId = context.steps.processDocument.output.documentId;
|
|
215
|
+
|
|
216
|
+
return {
|
|
217
|
+
finalized: true,
|
|
218
|
+
summary: `Request ${requestId} was ${approved ? 'approved' : 'rejected'} with document ${documentId}`
|
|
219
|
+
};
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Create workflow
|
|
224
|
+
const requestWorkflow = new Workflow({
|
|
225
|
+
name: 'document-request-workflow',
|
|
226
|
+
events: {
|
|
227
|
+
approvalReceived: {
|
|
228
|
+
schema: z.object({
|
|
229
|
+
approved: z.boolean(),
|
|
230
|
+
approverName: z.string(),
|
|
231
|
+
}),
|
|
232
|
+
},
|
|
233
|
+
documentUploaded: {
|
|
234
|
+
schema: z.object({
|
|
235
|
+
documentId: z.string(),
|
|
236
|
+
documentType: z.enum(['invoice', 'receipt', 'contract']),
|
|
237
|
+
}),
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// Build workflow
|
|
243
|
+
requestWorkflow
|
|
244
|
+
.step(createRequest)
|
|
245
|
+
.afterEvent('approvalReceived')
|
|
246
|
+
.step(processApproval)
|
|
247
|
+
.afterEvent('documentUploaded')
|
|
248
|
+
.step(processDocument)
|
|
249
|
+
.then(finalizeRequest)
|
|
250
|
+
.commit();
|
|
251
|
+
|
|
252
|
+
// Export workflow
|
|
253
|
+
export { requestWorkflow };
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Running the Example Workflow
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
import { requestWorkflow } from './workflows';
|
|
260
|
+
import { mastra } from './mastra';
|
|
261
|
+
|
|
262
|
+
async function runWorkflow() {
|
|
263
|
+
// Get the workflow
|
|
264
|
+
const workflow = mastra.getWorkflow('document-request-workflow');
|
|
265
|
+
const run = workflow.createRun();
|
|
266
|
+
|
|
267
|
+
// Start the workflow
|
|
268
|
+
const initialResult = await run.start();
|
|
269
|
+
console.log('Workflow started:', initialResult.results);
|
|
270
|
+
|
|
271
|
+
// Simulate receiving approval
|
|
272
|
+
const afterApprovalResult = await run.resumeWithEvent('approvalReceived', {
|
|
273
|
+
approved: true,
|
|
274
|
+
approverName: 'Jane Smith',
|
|
275
|
+
});
|
|
276
|
+
console.log('After approval:', afterApprovalResult.results);
|
|
277
|
+
|
|
278
|
+
// Simulate document upload
|
|
279
|
+
const finalResult = await run.resumeWithEvent('documentUploaded', {
|
|
280
|
+
documentId: 'doc-456',
|
|
281
|
+
documentType: 'invoice',
|
|
282
|
+
});
|
|
283
|
+
console.log('Final result:', finalResult.results);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
runWorkflow().catch(console.error);
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Best Practices
|
|
290
|
+
|
|
291
|
+
1. **Define Clear Event Schemas**: Use Zod to create precise schemas for event data validation
|
|
292
|
+
2. **Use Descriptive Event Names**: Choose event names that clearly communicate their purpose
|
|
293
|
+
3. **Handle Missing Events**: Ensure your workflow can handle cases where events don't occur or time out
|
|
294
|
+
4. **Include Monitoring**: Use the `watch` method to monitor suspended workflows waiting for events
|
|
295
|
+
5. **Consider Timeouts**: Implement timeout mechanisms for events that may never occur
|
|
296
|
+
6. **Document Events**: Clearly document the events your workflow depends on for other developers
|
|
297
|
+
|
|
298
|
+
## Related
|
|
299
|
+
|
|
300
|
+
- [Suspend and Resume in Workflows](../../workflows/suspend-and-resume.mdx)
|
|
301
|
+
- [Workflow Class Reference](./workflow.mdx)
|
|
302
|
+
- [Resume Method Reference](./resume.mdx)
|
|
303
|
+
- [Watch Method Reference](./watch.mdx)
|
|
304
|
+
- [After Event Reference](./afterEvent.mdx)
|
|
305
|
+
- [Resume With Event Reference](./resumeWithEvent.mdx)
|