@mastra/mcp-docs-server 1.2.13 → 1.2.14-alpha.3
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/docs/agents/a2a.md +1 -1
- package/.docs/docs/agents/acp.md +1 -1
- package/.docs/docs/agents/agent-approval.md +1 -1
- package/.docs/docs/agents/networks.md +2 -2
- package/.docs/docs/agents/overview.md +2 -2
- package/.docs/docs/agents/using-tools.md +2 -2
- package/.docs/docs/capabilities/channels/overview.md +1 -1
- package/.docs/docs/{agents/supervisor-agents.md → capabilities/subagents.md} +58 -58
- package/.docs/docs/deployment/sandbox.md +95 -1
- package/.docs/docs/getting-started/develop.md +2 -0
- package/.docs/docs/harness/agent-controller.md +370 -0
- package/.docs/docs/long-running-agents/background-tasks.md +1 -1
- package/.docs/docs/long-running-agents/goals.md +3 -3
- package/.docs/docs/mcp/overview.md +222 -281
- package/.docs/docs/memory/overview.md +2 -2
- package/.docs/docs/observability/integrations/exporters/confident-ai.md +140 -0
- package/.docs/docs/observability/integrations/overview.md +1 -1
- package/.docs/docs/observability/overview.md +122 -8
- package/.docs/docs/observability/tracing/overview.md +2 -2
- package/.docs/docs/server/mastra-client.md +1 -1
- package/.docs/docs/server/server-adapters.md +2 -0
- package/.docs/docs/storage/overview.md +2 -2
- package/.docs/guides/build-your-ui/copilotkit/channels.md +49 -39
- package/.docs/guides/concepts/multi-agent-systems.md +7 -7
- package/.docs/guides/guide/coding-agent.md +2 -2
- package/.docs/guides/guide/research-coordinator.md +1 -1
- package/.docs/guides/migrations/network-to-supervisor.md +1 -1
- package/.docs/models/index.md +1 -1
- package/.docs/models/providers/cortecs.md +2 -1
- package/.docs/models/providers/digitalocean.md +9 -9
- package/.docs/models/providers/kilo.md +1 -1
- package/.docs/models/providers/llmgateway.md +1 -1
- package/.docs/models/providers/opencode.md +2 -1
- package/.docs/reference/acp/acp-agent.md +1 -1
- package/.docs/reference/agent-controller/agent-controller-class.md +195 -506
- package/.docs/reference/agent-controller/session.md +274 -111
- package/.docs/reference/agents/network.md +1 -1
- package/.docs/reference/ai-sdk/handle-network-stream.md +1 -1
- package/.docs/reference/ai-sdk/network-route.md +1 -1
- package/.docs/reference/cli/create-mastra.md +1 -1
- package/.docs/reference/editor/versioning.md +1 -1
- package/.docs/reference/evals/rubric.md +1 -1
- package/.docs/reference/file-based-agents/observability.md +2 -2
- package/.docs/reference/file-based-agents/storage.md +1 -1
- package/.docs/reference/file-based-agents/subagents.md +1 -1
- package/.docs/reference/file-based-agents/tools.md +1 -1
- package/.docs/reference/observability/tracing/configuration.md +1 -1
- package/.docs/reference/observability/tracing/exporters/confident-ai.md +138 -0
- package/.docs/reference/observability/tracing/interfaces.md +29 -0
- package/.docs/reference/signals/signal-provider.md +2 -0
- package/.docs/reference/tools/mcp-server.md +1 -1
- package/.docs/reference/tools/submit-plan-tool.md +1 -1
- package/.docs/reference/workspace/railway-sandbox.md +5 -5
- package/CHANGELOG.md +14 -0
- package/package.json +3 -3
- package/.docs/docs/agent-controller/channels.md +0 -111
- package/.docs/docs/agent-controller/modes.md +0 -147
- package/.docs/docs/agent-controller/overview.md +0 -136
- package/.docs/docs/agent-controller/session.md +0 -161
- package/.docs/docs/agent-controller/subagents.md +0 -110
- package/.docs/docs/agent-controller/threads-and-state.md +0 -148
- package/.docs/docs/agent-controller/tool-approvals.md +0 -147
- package/.docs/docs/mcp/mcp-apps.md +0 -306
- package/.docs/docs/observability/config.md +0 -140
- package/.docs/docs/observability/storage.md +0 -81
package/.docs/docs/agents/a2a.md
CHANGED
|
@@ -68,7 +68,7 @@ Use `A2AAgent` when another Mastra agent should delegate work to a remote agent.
|
|
|
68
68
|
|
|
69
69
|
## Consume A2A agents as subagents
|
|
70
70
|
|
|
71
|
-
Use `A2AAgent` to wrap a remote A2A agent, then add it to a parent agent with the [supervisor agents](https://mastra.ai/docs/
|
|
71
|
+
Use `A2AAgent` to wrap a remote A2A agent, then add it to a parent agent with the [supervisor agents](https://mastra.ai/docs/capabilities/subagents) pattern. Pass an explicit agent card URL when the remote server hosts multiple agents or uses a custom well-known path.
|
|
72
72
|
|
|
73
73
|
```typescript
|
|
74
74
|
import { Agent } from '@mastra/core/agent'
|
package/.docs/docs/agents/acp.md
CHANGED
|
@@ -151,6 +151,6 @@ See the [AcpAgent workspace integration](https://mastra.ai/reference/acp/acp-age
|
|
|
151
151
|
- [AcpAgent reference](https://mastra.ai/reference/acp/acp-agent)
|
|
152
152
|
- [createACPTool() reference](https://mastra.ai/reference/acp/create-acp-tool)
|
|
153
153
|
- [Agent reference](https://mastra.ai/reference/agents/agent)
|
|
154
|
-
- [Subagents](https://mastra.ai/docs/
|
|
154
|
+
- [Subagents](https://mastra.ai/docs/capabilities/subagents)
|
|
155
155
|
- [Agent Client Protocol introduction](https://agentclientprotocol.com/overview/introduction)
|
|
156
156
|
- [Agent Client Protocol schema](https://agentclientprotocol.com/protocol/schema)
|
|
@@ -498,7 +498,7 @@ The same discovery is available over HTTP as `GET /agents/:agentId/suspended-run
|
|
|
498
498
|
|
|
499
499
|
## Tool approval: Supervisor agents
|
|
500
500
|
|
|
501
|
-
A [supervisor agent](https://mastra.ai/docs/
|
|
501
|
+
A [supervisor agent](https://mastra.ai/docs/capabilities/subagents) coordinates multiple subagents using `.stream()` or `.generate()`. When a subagent calls a tool that requires approval, the request propagates up through the delegation chain and surfaces at the supervisor level:
|
|
502
502
|
|
|
503
503
|
1. The supervisor delegates a task to a subagent.
|
|
504
504
|
2. The subagent calls a tool that has `requireApproval: true` or uses `suspend()`.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Agent networks
|
|
4
4
|
|
|
5
|
-
> **Deprecated:** Agent networks are deprecated and will be removed in a future major release. [Supervisor agents](https://mastra.ai/docs/
|
|
5
|
+
> **Deprecated:** Agent networks are deprecated and will be removed in a future major release. [Supervisor agents](https://mastra.ai/docs/capabilities/subagents) using `agent.stream()` or `agent.generate()` are now the recommended approach. It provides the same multi-agent coordination with better control, a simpler API, and easier debugging.
|
|
6
6
|
>
|
|
7
7
|
> See the [migration guide](https://mastra.ai/guides/migrations/network-to-supervisor) to upgrade.
|
|
8
8
|
|
|
@@ -180,5 +180,5 @@ Requirements for automatic resumption:
|
|
|
180
180
|
|
|
181
181
|
## Related
|
|
182
182
|
|
|
183
|
-
- [Supervisor agents](https://mastra.ai/docs/
|
|
183
|
+
- [Supervisor agents](https://mastra.ai/docs/capabilities/subagents)
|
|
184
184
|
- [Migration: `.network()` to supervisor agents](https://mastra.ai/guides/migrations/network-to-supervisor)
|
|
@@ -204,11 +204,11 @@ Once your agent is running, use this table to find the right page for what you w
|
|
|
204
204
|
| Keep context and preferences across conversations | [Memory](https://mastra.ai/docs/memory/overview) |
|
|
205
205
|
| Get typed objects back instead of plain text | [Structured output](https://mastra.ai/docs/agents/structured-output) |
|
|
206
206
|
| Human-in-the-loop: Pause execution and wait for human approval | [Approval](https://mastra.ai/docs/agents/agent-approval) |
|
|
207
|
-
| Build a multi-agent network | [Supervisor agents](https://mastra.ai/docs/
|
|
207
|
+
| Build a multi-agent network | [Supervisor agents](https://mastra.ai/docs/capabilities/subagents) |
|
|
208
208
|
| Register subagents | [Tools](https://mastra.ai/docs/agents/using-tools) |
|
|
209
209
|
| Intercept or transform messages before and after generation | [Processors](https://mastra.ai/docs/agents/processors) |
|
|
210
210
|
| Keep your agent safe | [Guardrails](https://mastra.ai/docs/agents/guardrails) |
|
|
211
|
-
| Build agents that correct their work | [Rubric scorer](https://mastra.ai/docs/
|
|
211
|
+
| Build agents that correct their work | [Rubric scorer](https://mastra.ai/docs/capabilities/subagents) |
|
|
212
212
|
| Swap instructions or models based on request context | [Dynamic configuration](https://mastra.ai/docs/server/request-context) |
|
|
213
213
|
| Add speech-to-text or text-to-speech | [Voice](https://mastra.ai/guides/voice/overview) |
|
|
214
214
|
| Connect to Slack, Discord, or Telegram | [Channels](https://mastra.ai/docs/capabilities/channels/overview) |
|
|
@@ -166,7 +166,7 @@ export const weatherAgent = new Agent({
|
|
|
166
166
|
|
|
167
167
|
## Agents as tools
|
|
168
168
|
|
|
169
|
-
Add subagents through the `agents` configuration to create a [supervisor](https://mastra.ai/docs/
|
|
169
|
+
Add subagents through the `agents` configuration to create a [supervisor](https://mastra.ai/docs/capabilities/subagents). Mastra converts each subagent to an `agent-<key>` tool. Include a `description` on each subagent so the supervisor knows when to delegate.
|
|
170
170
|
|
|
171
171
|
```typescript
|
|
172
172
|
import { Agent } from '@mastra/core/agent'
|
|
@@ -606,7 +606,7 @@ const agent = new Agent({
|
|
|
606
606
|
|
|
607
607
|
Only one task can be `in_progress` at a time. The list is stored in the thread-scoped `threadState` storage domain and projected onto the agent's [state-signal](https://mastra.ai/docs/long-running-agents/signals) lane, so it survives observational-memory truncation. See the [Task tools reference](https://mastra.ai/reference/tools/task-tools) for full schemas.
|
|
608
608
|
|
|
609
|
-
The [AgentController](https://mastra.ai/docs/agent-controller
|
|
609
|
+
The [AgentController](https://mastra.ai/docs/harness/agent-controller) automatically includes all built-in tools in every mode, you don't need to add them manually. See [Tool approvals](https://mastra.ai/docs/harness/agent-controller) for AgentController-specific behavior.
|
|
610
610
|
|
|
611
611
|
## Related
|
|
612
612
|
|
|
@@ -258,5 +258,5 @@ Vercel's managed Redis integration and Upstash Redis both work well. For more on
|
|
|
258
258
|
## Related
|
|
259
259
|
|
|
260
260
|
- [Channels reference](https://mastra.ai/reference/agents/channels)
|
|
261
|
-
- [AgentController channels](https://mastra.ai/docs/agent-controller
|
|
261
|
+
- [AgentController channels](https://mastra.ai/docs/harness/agent-controller)
|
|
262
262
|
- 📹 [Mastra channels workshop](https://www.youtube.com/watch?v=E9KFsZEnQO8\&t=5s)
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
> Discover all available pages from the documentation index: https://mastra.ai/llms.txt
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# Subagents
|
|
4
4
|
|
|
5
5
|
**Added in:** `@mastra/core@1.8.0`
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Subagents are specialized agents that another agent can delegate tasks to. Add them to the parent agent's `agents` property, then call [`Agent.stream()`](https://mastra.ai/reference/streaming/agents/stream) or [`Agent.generate()`](https://mastra.ai/reference/agents/generate). The parent agent uses its instructions and each subagent's `description` to decide when and how to delegate tasks.
|
|
8
8
|
|
|
9
|
-
## When to use
|
|
9
|
+
## When to use subagents
|
|
10
10
|
|
|
11
|
-
Use
|
|
11
|
+
Use subagents when a task requires agents with different specializations to work together. The parent agent decides when to delegate and passes context to each subagent. It then synthesizes their results.
|
|
12
12
|
|
|
13
13
|
Common use cases:
|
|
14
14
|
|
|
@@ -16,11 +16,11 @@ Common use cases:
|
|
|
16
16
|
- Multi-step tasks that need different expertise at each stage
|
|
17
17
|
- Tasks where you need fine-grained control over delegation behavior
|
|
18
18
|
|
|
19
|
-
> **Note:**
|
|
19
|
+
> **Note:** A parent agent that coordinates subagents is often called a supervisor. The supervisor pattern is one approach to building multi-agent systems in Mastra. For other patterns, read the [conceptual overview](https://mastra.ai/guides/concepts/multi-agent-systems).
|
|
20
20
|
|
|
21
21
|
## Quickstart
|
|
22
22
|
|
|
23
|
-
Define subagents with clear descriptions, then
|
|
23
|
+
Define subagents with clear descriptions, then add them to a parent agent:
|
|
24
24
|
|
|
25
25
|
```typescript
|
|
26
26
|
import { Agent } from '@mastra/core/agent'
|
|
@@ -39,8 +39,8 @@ const writingAgent = new Agent({
|
|
|
39
39
|
model: 'openai/gpt-5-mini',
|
|
40
40
|
})
|
|
41
41
|
|
|
42
|
-
const
|
|
43
|
-
id: '
|
|
42
|
+
const parentAgent = new Agent({
|
|
43
|
+
id: 'parent-agent',
|
|
44
44
|
instructions: `You coordinate research and writing using specialized agents.
|
|
45
45
|
Delegate to research-agent for facts, then writing-agent for content.`,
|
|
46
46
|
model: 'openai/gpt-5.6-sol',
|
|
@@ -50,7 +50,7 @@ const supervisor = new Agent({
|
|
|
50
50
|
}),
|
|
51
51
|
})
|
|
52
52
|
|
|
53
|
-
const stream = await
|
|
53
|
+
const stream = await parentAgent.stream('Research AI in education and write an article', {
|
|
54
54
|
maxSteps: 10,
|
|
55
55
|
})
|
|
56
56
|
|
|
@@ -65,7 +65,7 @@ Delegation hooks let you intercept, modify, or reject delegations as they happen
|
|
|
65
65
|
|
|
66
66
|
### `onDelegationStart`
|
|
67
67
|
|
|
68
|
-
Called before the
|
|
68
|
+
Called before the parent agent delegates to a subagent. Return an object to control the delegation:
|
|
69
69
|
|
|
70
70
|
- `proceed: true`: Allow the delegation (default behavior)
|
|
71
71
|
- `proceed: false`: Reject the delegation with a `rejectionReason`
|
|
@@ -73,7 +73,7 @@ Called before the supervisor delegates to a subagent. Return an object to contro
|
|
|
73
73
|
- `modifiedMaxSteps`: Limit the subagent's iteration count
|
|
74
74
|
|
|
75
75
|
```typescript
|
|
76
|
-
const stream = await
|
|
76
|
+
const stream = await parentAgent.stream('Research AI trends', {
|
|
77
77
|
maxSteps: 10,
|
|
78
78
|
delegation: {
|
|
79
79
|
onDelegationStart: async context => {
|
|
@@ -107,18 +107,18 @@ The `context` object includes:
|
|
|
107
107
|
| Property | Description |
|
|
108
108
|
| ------------- | ----------------------------------------- |
|
|
109
109
|
| `primitiveId` | The ID of the subagent being delegated to |
|
|
110
|
-
| `prompt` | The prompt the
|
|
110
|
+
| `prompt` | The prompt the parent agent is sending |
|
|
111
111
|
| `iteration` | Current iteration number |
|
|
112
112
|
|
|
113
113
|
### `onDelegationComplete`
|
|
114
114
|
|
|
115
115
|
Called after a delegation finishes. Use it to inspect results or provide feedback, or alternatively stop execution:
|
|
116
116
|
|
|
117
|
-
- `context.bail()`: Stop the
|
|
118
|
-
- Return `{ feedback: '...' }`: Add feedback that gets saved to the
|
|
117
|
+
- `context.bail()`: Stop the parent agent's loop immediately
|
|
118
|
+
- Return `{ feedback: '...' }`: Add feedback that gets saved to the parent agent's memory and is visible to subsequent iterations
|
|
119
119
|
|
|
120
120
|
```typescript
|
|
121
|
-
const stream = await
|
|
121
|
+
const stream = await parentAgent.stream('Research AI trends', {
|
|
122
122
|
maxSteps: 10,
|
|
123
123
|
delegation: {
|
|
124
124
|
onDelegationComplete: async context => {
|
|
@@ -138,19 +138,19 @@ const stream = await supervisor.stream('Research AI trends', {
|
|
|
138
138
|
|
|
139
139
|
The `context` object includes:
|
|
140
140
|
|
|
141
|
-
| Property | Description
|
|
142
|
-
| ------------- |
|
|
143
|
-
| `primitiveId` | The ID of the subagent that ran
|
|
144
|
-
| `result` | The subagent's response
|
|
145
|
-
| `error` | Error if the delegation failed
|
|
146
|
-
| `bail()` | Function to stop the
|
|
141
|
+
| Property | Description |
|
|
142
|
+
| ------------- | ---------------------------------------- |
|
|
143
|
+
| `primitiveId` | The ID of the subagent that ran |
|
|
144
|
+
| `result` | The subagent's response |
|
|
145
|
+
| `error` | Error if the delegation failed |
|
|
146
|
+
| `bail()` | Function to stop the parent agent's loop |
|
|
147
147
|
|
|
148
148
|
## Message filtering
|
|
149
149
|
|
|
150
|
-
By default, subagents receive the full conversation context from the
|
|
150
|
+
By default, subagents receive the full conversation context from the parent agent. Use `messageFilter` to control what messages are shared, for example, to remove sensitive data or limit context size.
|
|
151
151
|
|
|
152
152
|
```typescript
|
|
153
|
-
const stream = await
|
|
153
|
+
const stream = await parentAgent.stream('Research AI trends', {
|
|
154
154
|
maxSteps: 10,
|
|
155
155
|
delegation: {
|
|
156
156
|
messageFilter: ({ messages, primitiveId, prompt }) => {
|
|
@@ -171,16 +171,16 @@ The callback receives `messages` (the full conversation history), `primitiveId`
|
|
|
171
171
|
|
|
172
172
|
## Subagent result context
|
|
173
173
|
|
|
174
|
-
When a subagent completes, the
|
|
174
|
+
When a subagent completes, the parent agent's model receives the subagent's text response in later iterations. Nested tool calls and subagent metadata, such as thread and resource IDs, aren't added to the parent agent's model context.
|
|
175
175
|
|
|
176
176
|
Application code and UI integrations can still inspect `subAgentToolResults` and the rest of the raw delegation result in the tool result payload.
|
|
177
177
|
|
|
178
|
-
This keeps debugging and display data available without sending nested tool arguments or outputs back into the
|
|
178
|
+
This keeps debugging and display data available without sending nested tool arguments or outputs back into the parent agent's next model call.
|
|
179
179
|
|
|
180
|
-
Set `includeSubAgentToolResultsInModelContext` to include the full subagent result, including nested tool results and subagent metadata, in the
|
|
180
|
+
Set `includeSubAgentToolResultsInModelContext` to include the full subagent result, including nested tool results and subagent metadata, in the parent agent's model context.
|
|
181
181
|
|
|
182
182
|
```typescript
|
|
183
|
-
await
|
|
183
|
+
await parentAgent.generate('Research AI trends', {
|
|
184
184
|
delegation: {
|
|
185
185
|
includeSubAgentToolResultsInModelContext: true,
|
|
186
186
|
},
|
|
@@ -189,10 +189,10 @@ await supervisor.generate('Research AI trends', {
|
|
|
189
189
|
|
|
190
190
|
## Iteration monitoring
|
|
191
191
|
|
|
192
|
-
`onIterationComplete` is called after each iteration of the
|
|
192
|
+
`onIterationComplete` is called after each iteration of the parent agent's loop. Use it to monitor execution or guide the next iteration. You can also stop execution early.
|
|
193
193
|
|
|
194
194
|
```typescript
|
|
195
|
-
const stream = await
|
|
195
|
+
const stream = await parentAgent.stream('Research AI trends', {
|
|
196
196
|
maxSteps: 10,
|
|
197
197
|
onIterationComplete: async context => {
|
|
198
198
|
console.log(`Iteration ${context.iteration}/${context.maxIterations}`)
|
|
@@ -220,19 +220,19 @@ Return `{ continue: true }` to keep iterating, or `{ continue: false }` to stop.
|
|
|
220
220
|
|
|
221
221
|
## Memory isolation
|
|
222
222
|
|
|
223
|
-
|
|
223
|
+
Mastra isolates subagent memory during delegation. Subagents receive the full conversation context for better decision-making, but only their specific delegation prompt and response are saved to their memory.
|
|
224
224
|
|
|
225
225
|
How it works:
|
|
226
226
|
|
|
227
|
-
1. **Full context forwarded**: When the
|
|
227
|
+
1. **Full context forwarded**: When the parent agent delegates, the subagent receives all messages from the parent agent's conversation
|
|
228
228
|
2. **Scoped memory saves**: Only the delegation prompt and the subagent's response are saved to the subagent's memory
|
|
229
229
|
3. **Fresh thread per invocation**: Each delegation uses a unique thread ID, ensuring clean separation
|
|
230
230
|
|
|
231
|
-
As a result, subagents have the context they need without cluttering their memory with the entire
|
|
231
|
+
As a result, subagents have the context they need without cluttering their memory with the parent agent's entire conversation. Visit [memory in multi-agent systems](https://mastra.ai/docs/memory/overview) for more details.
|
|
232
232
|
|
|
233
233
|
## Tool approval propagation
|
|
234
234
|
|
|
235
|
-
Tool approvals propagate through the delegation chain. When a subagent uses a tool with `requireApproval: true` or calls `suspend()`, the approval request surfaces
|
|
235
|
+
Tool approvals propagate through the delegation chain. When a subagent uses a tool with `requireApproval: true` or calls `suspend()`, the approval request surfaces in the parent agent's stream.
|
|
236
236
|
|
|
237
237
|
```typescript
|
|
238
238
|
const sensitiveDataTool = createTool({
|
|
@@ -248,13 +248,13 @@ const dataAgent = new Agent({
|
|
|
248
248
|
tools: { sensitiveDataTool },
|
|
249
249
|
})
|
|
250
250
|
|
|
251
|
-
const
|
|
252
|
-
id: '
|
|
251
|
+
const parentAgent = new Agent({
|
|
252
|
+
id: 'parent-agent',
|
|
253
253
|
agents: { dataAgent },
|
|
254
254
|
memory: new Memory(),
|
|
255
255
|
})
|
|
256
256
|
|
|
257
|
-
const stream = await
|
|
257
|
+
const stream = await parentAgent.stream('Get data for user 123')
|
|
258
258
|
|
|
259
259
|
for await (const chunk of stream.fullStream) {
|
|
260
260
|
if (chunk.type === 'tool-call-approval') {
|
|
@@ -265,22 +265,22 @@ for await (const chunk of stream.fullStream) {
|
|
|
265
265
|
|
|
266
266
|
## Cancellation
|
|
267
267
|
|
|
268
|
-
When you pass an `abortSignal` to the
|
|
268
|
+
When you pass an `abortSignal` to the parent agent's [`stream()`](https://mastra.ai/reference/streaming/agents/stream) or [`generate()`](https://mastra.ai/reference/agents/generate) call, Mastra forwards that same signal to delegated subagents. Calling `AbortController.abort()` cancels in-flight subagent runs at their next step instead of letting them run to completion.
|
|
269
269
|
|
|
270
270
|
```typescript
|
|
271
271
|
const controller = new AbortController()
|
|
272
272
|
|
|
273
|
-
const stream = await
|
|
273
|
+
const stream = await parentAgent.stream('Research AI trends', {
|
|
274
274
|
abortSignal: controller.signal,
|
|
275
275
|
})
|
|
276
276
|
|
|
277
|
-
// Cancel the
|
|
277
|
+
// Cancel the parent agent and any in-flight subagents
|
|
278
278
|
controller.abort()
|
|
279
279
|
```
|
|
280
280
|
|
|
281
281
|
## Task completion scoring
|
|
282
282
|
|
|
283
|
-
Agents don't always produce a complete, correct output on the first try. Task completion scorers can help
|
|
283
|
+
Agents don't always produce a complete, correct output on the first try. Task completion scorers can help by validating whether the task is complete after each iteration. If validation fails, the parent agent continues iterating. Feedback from failed scorers is included in the conversation context so subagents can see what was missing.
|
|
284
284
|
|
|
285
285
|
```typescript
|
|
286
286
|
import { createScorer } from '@mastra/core/evals'
|
|
@@ -295,7 +295,7 @@ const taskCompleteScorer = createScorer({
|
|
|
295
295
|
return hasAnalysis && hasRecommendations ? 1 : 0
|
|
296
296
|
})
|
|
297
297
|
|
|
298
|
-
const stream = await
|
|
298
|
+
const stream = await parentAgent.stream('Research AI in education', {
|
|
299
299
|
maxSteps: 10,
|
|
300
300
|
isTaskComplete: {
|
|
301
301
|
scorers: [taskCompleteScorer],
|
|
@@ -319,8 +319,8 @@ This is most effective for tasks with clear, verifiable success criteria. You ca
|
|
|
319
319
|
import { Agent } from '@mastra/core/agent'
|
|
320
320
|
import { createRubricScorer } from '@mastra/evals/scorers/prebuilt'
|
|
321
321
|
|
|
322
|
-
const
|
|
323
|
-
id: '
|
|
322
|
+
const parentAgent = new Agent({
|
|
323
|
+
id: 'parent-agent',
|
|
324
324
|
instructions: 'You coordinate research and writing using specialized agents.',
|
|
325
325
|
model: 'openai/gpt-5.6-sol',
|
|
326
326
|
agents: { researchAgent, writingAgent },
|
|
@@ -334,7 +334,7 @@ const rubricScorer = createRubricScorer({
|
|
|
334
334
|
],
|
|
335
335
|
})
|
|
336
336
|
|
|
337
|
-
const stream = await
|
|
337
|
+
const stream = await parentAgent.stream('Research AI in education', {
|
|
338
338
|
maxSteps: 10,
|
|
339
339
|
isTaskComplete: {
|
|
340
340
|
scorers: [rubricScorer],
|
|
@@ -349,15 +349,15 @@ For full API details, see the [rubric scorer reference](https://mastra.ai/refere
|
|
|
349
349
|
|
|
350
350
|
Clear instructions are essential for effective delegation.
|
|
351
351
|
|
|
352
|
-
|
|
352
|
+
The parent agent's `instructions` should specify the available resources and when to use each one. They should also define coordination behavior and success criteria.
|
|
353
353
|
|
|
354
|
-
Each subagent should have a clear `description` that explains its purpose and return format, including when the
|
|
354
|
+
Each subagent should have a clear `description` that explains its purpose and return format, including when the parent agent should use it.
|
|
355
355
|
|
|
356
|
-
The
|
|
356
|
+
The parent agent uses these descriptions to make delegation decisions.
|
|
357
357
|
|
|
358
358
|
```typescript
|
|
359
|
-
const
|
|
360
|
-
id: '
|
|
359
|
+
const parentAgent = new Agent({
|
|
360
|
+
id: 'parent-agent',
|
|
361
361
|
instructions: `You coordinate research and writing tasks.
|
|
362
362
|
|
|
363
363
|
Available resources:
|
|
@@ -378,13 +378,13 @@ Success criteria:
|
|
|
378
378
|
|
|
379
379
|
## Running subagents in the background
|
|
380
380
|
|
|
381
|
-
Subagent invocations are dispatched as tool calls, so they can run as [background tasks](https://mastra.ai/docs/long-running-agents/background-tasks). This is useful when one or more delegations are long-running and you don't want them to block the
|
|
381
|
+
Subagent invocations are dispatched as tool calls, so they can run as [background tasks](https://mastra.ai/docs/long-running-agents/background-tasks). This is useful when one or more delegations are long-running and you don't want them to block the parent agent's response.
|
|
382
382
|
|
|
383
|
-
Enable the [backgroundTasks manager](https://mastra.ai/reference/configuration) on the Mastra instance, then opt subagents in on the
|
|
383
|
+
Enable the [backgroundTasks manager](https://mastra.ai/reference/configuration) on the Mastra instance, then opt subagents in on the parent agent:
|
|
384
384
|
|
|
385
385
|
```typescript
|
|
386
|
-
const
|
|
387
|
-
id: '
|
|
386
|
+
const parentAgent = new Agent({
|
|
387
|
+
id: 'parent-agent',
|
|
388
388
|
instructions: 'Coordinate research and writing using the available agents.',
|
|
389
389
|
model: 'openai/gpt-5.6-sol',
|
|
390
390
|
agents: { researchAgent, writingAgent },
|
|
@@ -396,21 +396,21 @@ const supervisor = new Agent({
|
|
|
396
396
|
},
|
|
397
397
|
})
|
|
398
398
|
|
|
399
|
-
const stream = await
|
|
399
|
+
const stream = await parentAgent.streamUntilIdle('Research AI in education and write an article', {
|
|
400
400
|
memory: { thread: 't1', resource: 'u1' },
|
|
401
401
|
})
|
|
402
402
|
```
|
|
403
403
|
|
|
404
|
-
Use [`streamUntilIdle()`](https://mastra.ai/reference/streaming/agents/streamUntilIdle) instead of `stream()` so the stream stays open until the subagents complete and the
|
|
404
|
+
Use [`streamUntilIdle()`](https://mastra.ai/reference/streaming/agents/streamUntilIdle) instead of `stream()` so the stream stays open until the subagents complete and the parent agent has had a chance to respond to their results.
|
|
405
405
|
|
|
406
|
-
If a subagent isn't listed
|
|
406
|
+
If a subagent isn't listed under the parent agent's `backgroundTasks.tools` but has its own background-eligible tools, the parent agent still dispatches the subagent as a background task and inherits its config. See [Inheriting from the subagent](https://mastra.ai/docs/long-running-agents/background-tasks) for details.
|
|
407
407
|
|
|
408
408
|
## Subagent versioning
|
|
409
409
|
|
|
410
|
-
When using the [editor](https://mastra.ai/docs/editor/overview), you can control which stored version of each subagent the
|
|
410
|
+
When using the [editor](https://mastra.ai/docs/editor/overview), you can control which stored version of each subagent the parent agent uses at runtime. Set version overrides on the Mastra instance or per invocation:
|
|
411
411
|
|
|
412
412
|
```typescript
|
|
413
|
-
const result = await
|
|
413
|
+
const result = await parentAgent.generate('Research and write about AI safety', {
|
|
414
414
|
versions: {
|
|
415
415
|
agents: {
|
|
416
416
|
'research-agent': { status: 'published' },
|
|
@@ -62,13 +62,18 @@ export const mastra = new Mastra({
|
|
|
62
62
|
deployer: new SandboxDeployer({
|
|
63
63
|
sandbox: new VercelSandbox({
|
|
64
64
|
sandboxName: 'my-preview',
|
|
65
|
-
timeout:
|
|
65
|
+
timeout: 2_400_000, // 40 minutes
|
|
66
66
|
ports: [4111],
|
|
67
67
|
}),
|
|
68
68
|
}),
|
|
69
69
|
})
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
+
Two Vercel-specific requirements:
|
|
73
|
+
|
|
74
|
+
- `timeout` can't exceed the maximum sandbox lifetime of your plan, 45 minutes on Pro. A higher value fails the deploy with a 400 from the Vercel API.
|
|
75
|
+
- Declare the server port in `ports`. Vercel exposes only ports declared at creation, unlike E2B and Daytona.
|
|
76
|
+
|
|
72
77
|
Build and deploy in one command:
|
|
73
78
|
|
|
74
79
|
```bash
|
|
@@ -86,6 +91,83 @@ The manifest includes `expiresAt` when the sandbox provider reports an expiratio
|
|
|
86
91
|
|
|
87
92
|
Redeploys to the same sandbox skip the dependency install when its inputs are unchanged. These inputs are `package.json`, the bundled lockfiles, and the install command.
|
|
88
93
|
|
|
94
|
+
### What the URLs serve
|
|
95
|
+
|
|
96
|
+
The Studio URL is the sandbox root, without `/api`. Open it in a browser to use Studio. When the deploy runs with `studio: false`, the root serves the Mastra welcome page instead.
|
|
97
|
+
|
|
98
|
+
The API URL is only a prefix for the endpoints below it, such as `/api/agents`. `/api` has no handler of its own, so opening it in a browser returns a "Not Found" response even though the server is healthy.
|
|
99
|
+
|
|
100
|
+
To check a deployment, call an endpoint directly:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
curl -s -X POST https://4111-<sandbox-id>.e2b.app/api/agents/weatherAgent/generate \
|
|
104
|
+
-H "Content-Type: application/json" \
|
|
105
|
+
-d '{"messages":[{"role":"user","content":"Weather in London"}]}' | jq -r '.text'
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Provider credentials
|
|
109
|
+
|
|
110
|
+
Each provider authenticates with its own credentials. Set the ones for the sandbox you deploy to:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# E2B
|
|
114
|
+
E2B_API_KEY=
|
|
115
|
+
|
|
116
|
+
# Daytona
|
|
117
|
+
DAYTONA_API_KEY=
|
|
118
|
+
|
|
119
|
+
# Vercel
|
|
120
|
+
VERCEL_TOKEN=
|
|
121
|
+
VERCEL_TEAM_ID=
|
|
122
|
+
VERCEL_PROJECT_ID=
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Every provider also accepts these as constructor options. Self-hosted E2B and Daytona installations take `E2B_DOMAIN` or `DAYTONA_API_URL`.
|
|
126
|
+
|
|
127
|
+
Unlike `mastra dev`, `mastra build` doesn't load `.env` files. The deploy happens inside the build, so a sandbox provider that reads its credentials from the environment, such as E2B with `E2B_API_KEY`, sees an empty value and the deploy fails with an authentication error.
|
|
128
|
+
|
|
129
|
+
Adding `import 'dotenv/config'` to `src/mastra/index.ts` doesn't fix this. To find the deployer, the build extracts only the `deployer` option from your entry file and tree-shakes everything else away, including that import.
|
|
130
|
+
|
|
131
|
+
Load the `.env` file into the shell environment before the build runs. [`dotenv-cli`](https://www.npmjs.com/package/dotenv-cli) is one way to do that:
|
|
132
|
+
|
|
133
|
+
**npm**:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npm install --save-dev dotenv-cli
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**pnpm**:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
pnpm add --save-dev dotenv-cli
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Yarn**:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
yarn add --dev dotenv-cli
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**Bun**:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
bun add --dev dotenv-cli
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"scripts": {
|
|
160
|
+
"deploy": "dotenv -e .env -- mastra build"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Then run `npm run deploy`. The script is named for what it does, since `mastra build` deploys once a `SandboxDeployer()` is configured. Keep it separate from a plain `build` script so a hosting platform or CI job that runs `npm run build` doesn't deploy a sandbox by accident.
|
|
166
|
+
|
|
167
|
+
In continuous integration (CI), export the credentials as secrets instead. Whatever mechanism you use, the variables must exist in the shell environment, not only in the `.env` file.
|
|
168
|
+
|
|
169
|
+
This applies to credentials the deployer needs on your machine. Variables the deployed server needs are handled separately: the deployer reads `.env`, `.env.production`, and `.env.local` and injects them into the sandbox. See [Security](#security).
|
|
170
|
+
|
|
89
171
|
### Using E2B
|
|
90
172
|
|
|
91
173
|
For E2B, the `id` identifies the deployment, so subsequent deployments with the same value reconnect to the existing sandbox, whether it's running or paused.
|
|
@@ -124,6 +206,18 @@ const deployer = new SandboxDeployer({
|
|
|
124
206
|
|
|
125
207
|
Stopping a Daytona sandbox persists its filesystem but not running processes, so waking works like Vercel: the resolver relaunches the server on `wake: true`.
|
|
126
208
|
|
|
209
|
+
Daytona filters outbound traffic per destination. Requests to some hosts connect over Transport Layer Security (TLS) normally, while others are reset during the handshake, which surfaces in an agent or a tool as Node's generic `fetch failed`. Rule out your code before debugging it, by running `curl` against the same host from inside the sandbox:
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
const sandbox = new DaytonaSandbox({ id: 'my-preview' })
|
|
213
|
+
await sandbox.start()
|
|
214
|
+
|
|
215
|
+
const result = await sandbox.executeCommand('curl -v --max-time 10 https://api.example.com')
|
|
216
|
+
console.info(result.stdout, result.stderr)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
A `Connection reset by peer` during the TLS handshake points at the filtering rather than your agent. Ask Daytona support to allow the destination. Restricted Daytona tiers also block cloud storage endpoints, which the mount helpers report with a dedicated error.
|
|
220
|
+
|
|
127
221
|
## Deploying programmatically
|
|
128
222
|
|
|
129
223
|
`deployToSandbox()` deploys a prebuilt output directory without the bundler. Unlike `SandboxDeployer()`, it doesn't include Studio unless you pass `studio: true`. Use it in CI or from agent code:
|
|
@@ -139,6 +139,8 @@ See the [project structure reference](https://mastra.ai/reference/project-struct
|
|
|
139
139
|
## File-based agents
|
|
140
140
|
|
|
141
141
|
> **Beta:** File-based agents are in beta and may change before they're stable.
|
|
142
|
+
>
|
|
143
|
+
> File-based discovery only runs through `mastra dev` or `mastra build`. If your app imports `mastra` directly, including through a web framework or server adapter, file-based agents aren't discovered. Register those agents in code or run Mastra as a separate server.
|
|
142
144
|
|
|
143
145
|
> **📹 Watch:** [How to create your first file-based agent](https://www.youtube.com/watch?v=5Kfn-oYkJNg\&t=18s)
|
|
144
146
|
|