@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
|
@@ -1,738 +1,427 @@
|
|
|
1
1
|
> Discover all available pages from the documentation index: https://mastra.ai/llms.txt
|
|
2
2
|
|
|
3
|
-
# AgentController
|
|
3
|
+
# AgentController
|
|
4
4
|
|
|
5
5
|
> **Beta:** The `AgentController` feature is in beta stage and subject to breaking changes in minor versions until it graduates from its beta status.
|
|
6
6
|
|
|
7
|
-
The `AgentController` class
|
|
7
|
+
The `AgentController` class is a shared host for one or more [`Session`](https://mastra.ai/reference/agent-controller/session) instances. Initialize the controller, create a session, then use `session.*` APIs for conversation state and run control.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
For a conceptual introduction, see the [AgentController overview](https://mastra.ai/docs/agent-controller/overview).
|
|
9
|
+
For a guided introduction, see the [AgentController overview](https://mastra.ai/docs/harness/agent-controller).
|
|
12
10
|
|
|
13
11
|
## Usage example
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
The following example initializes a controller and creates a session. It subscribes to session events before sending a message.
|
|
16
14
|
|
|
17
15
|
```typescript
|
|
16
|
+
import { Agent } from '@mastra/core/agent'
|
|
18
17
|
import { AgentController } from '@mastra/core/agent-controller'
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
stateSchema: z.object({
|
|
27
|
-
currentModelId: z.string().optional(),
|
|
28
|
-
}),
|
|
29
|
-
modes: [
|
|
30
|
-
{
|
|
31
|
-
id: 'plan',
|
|
32
|
-
name: 'Plan',
|
|
33
|
-
metadata: { default: true },
|
|
34
|
-
instructions: 'Reason about changes before making them.',
|
|
35
|
-
},
|
|
36
|
-
{ id: 'build', name: 'Build', transitionsTo: 'plan' },
|
|
37
|
-
],
|
|
18
|
+
import { Workspace } from '@mastra/core/workspace'
|
|
19
|
+
|
|
20
|
+
const agent = new Agent({
|
|
21
|
+
id: 'coding-agent',
|
|
22
|
+
name: 'Coding agent',
|
|
23
|
+
instructions: 'Help with software engineering tasks.',
|
|
24
|
+
model: 'anthropic/claude-sonnet-4-6',
|
|
38
25
|
})
|
|
39
26
|
|
|
40
|
-
|
|
27
|
+
const controller = new AgentController({
|
|
28
|
+
id: 'coding-controller',
|
|
29
|
+
agent,
|
|
30
|
+
workspace: new Workspace({ id: 'coding-workspace' }),
|
|
31
|
+
modes: [{ id: 'build', name: 'Build', metadata: { default: true } }],
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
await controller.init()
|
|
35
|
+
|
|
36
|
+
const session = await controller.createSession({ resourceId: 'project-42' })
|
|
37
|
+
const unsubscribe = session.subscribe(event => {
|
|
41
38
|
if (event.type === 'message_update') {
|
|
42
|
-
|
|
39
|
+
console.log(event.message)
|
|
43
40
|
}
|
|
44
41
|
})
|
|
45
42
|
|
|
46
|
-
await
|
|
47
|
-
|
|
48
|
-
await agentController.sendMessage({ content: 'Hello!' })
|
|
43
|
+
await session.sendMessage({ content: 'Review the project structure.' })
|
|
44
|
+
unsubscribe()
|
|
49
45
|
```
|
|
50
46
|
|
|
51
47
|
## Constructor parameters
|
|
52
48
|
|
|
53
|
-
**id** (`string`): Unique identifier
|
|
54
|
-
|
|
55
|
-
**resourceId** (`string`): Resource ID for grouping threads (e.g., project identifier). Threads are scoped to this resource ID. Defaults to id.
|
|
49
|
+
**id** (`string`): Unique controller identifier. It is also the default session and resource identifier.
|
|
56
50
|
|
|
57
|
-
**
|
|
51
|
+
**modes** (`AgentControllerMode[]`): Mode definitions available to every session. At least one mode is required.
|
|
58
52
|
|
|
59
|
-
**
|
|
53
|
+
**modes.id** (`string`): Unique mode identifier.
|
|
60
54
|
|
|
61
|
-
**
|
|
55
|
+
**modes.name** (`string`): Display name.
|
|
62
56
|
|
|
63
|
-
**
|
|
57
|
+
**modes.defaultModelId** (`string`): Model selected when a session enters this mode without a stored selection.
|
|
64
58
|
|
|
65
|
-
**modes** (`
|
|
59
|
+
**modes.description** (`string`): Text shown in mode selectors.
|
|
66
60
|
|
|
67
|
-
**modes.
|
|
61
|
+
**modes.instructions** (`string`): Instructions layered above the backing agent instructions for this mode.
|
|
68
62
|
|
|
69
|
-
**modes.
|
|
63
|
+
**modes.transitionsTo** (`string`): Mode entered after an approved submit\_plan suspension.
|
|
70
64
|
|
|
71
|
-
**modes.
|
|
65
|
+
**modes.availableTools** (`string[]`): Allowlist of exposed tool names. An empty array hides every tool in this mode.
|
|
72
66
|
|
|
73
|
-
**modes.
|
|
67
|
+
**modes.metadata** (`Record<string, unknown>`): Pass-through mode metadata. metadata.default: true marks the default mode.
|
|
74
68
|
|
|
75
|
-
**modes.
|
|
69
|
+
**modes.tools** (`ToolsInput`): Mode tools. Mutually exclusive with additionalTools.
|
|
76
70
|
|
|
77
|
-
**modes.
|
|
71
|
+
**modes.additionalTools** (`ToolsInput`): Tools added to the backing agent tools. Mutually exclusive with tools.
|
|
78
72
|
|
|
79
|
-
**modes.
|
|
73
|
+
**modes.agent** (`Agent`): Deprecated mode-specific agent. Use the top-level agent parameter.
|
|
80
74
|
|
|
81
|
-
**modes.
|
|
75
|
+
**modes.default** (`boolean`): Deprecated default marker. Use metadata.default or defaultModeId.
|
|
82
76
|
|
|
83
|
-
**
|
|
77
|
+
**agent** (`Agent`): Shared backing agent used by the configured modes.
|
|
84
78
|
|
|
85
|
-
**
|
|
79
|
+
**resourceId** (`string`): Default resource identifier for sessions and threads. Defaults to id.
|
|
86
80
|
|
|
87
|
-
**
|
|
81
|
+
**storage** (`MastraCompositeStore`): Storage used for persistent threads, messages, settings, and resumable run data.
|
|
88
82
|
|
|
89
|
-
**
|
|
83
|
+
**stateSchema** (`PublicSchema<TState, any>`): Schema used to validate session.state updates.
|
|
90
84
|
|
|
91
|
-
**
|
|
85
|
+
**initialState** (`Partial<TState>`): Initial state merged with schema defaults for each new session.
|
|
92
86
|
|
|
93
|
-
**
|
|
87
|
+
**memory** (`DynamicArgument<MastraMemory>`): Memory instance shared with backing agents that do not define their own memory.
|
|
94
88
|
|
|
95
|
-
**
|
|
89
|
+
**defaultModeId** (`string`): Default mode identifier. It takes precedence over mode metadata.
|
|
96
90
|
|
|
97
|
-
**
|
|
91
|
+
**instructions** (`string`): Controller instructions layered with the current mode instructions.
|
|
98
92
|
|
|
99
|
-
**
|
|
93
|
+
**tools** (`DynamicArgument<ToolsInput | undefined>`): Tools shared by controller runs and available to configured subagents.
|
|
100
94
|
|
|
101
|
-
**
|
|
95
|
+
**workspace** (`DynamicArgument<Workspace | undefined>`): Static workspace or per-session workspace factory. A session must resolve a valid workspace.
|
|
102
96
|
|
|
103
|
-
**
|
|
97
|
+
**browser** (`DynamicArgument<MastraBrowser | undefined>`): Static browser or per-session browser factory.
|
|
104
98
|
|
|
105
|
-
**
|
|
99
|
+
**channels** (`AgentControllerChannelsConfig`): Chat channel configuration used to route channel threads into controller sessions.
|
|
106
100
|
|
|
107
|
-
**
|
|
101
|
+
**intervalHandlers** (`IntervalHandler[]`): Periodic handlers started by init() and stopped by stopIntervals() or destroy().
|
|
108
102
|
|
|
109
|
-
**
|
|
103
|
+
**idGenerator** (`() => string`): Custom identifier generator for threads, messages, and signals.
|
|
110
104
|
|
|
111
|
-
**
|
|
105
|
+
**modelUseCountProvider** (`ModelUseCountProvider`): Returns model usage counts used to sort available models.
|
|
112
106
|
|
|
113
|
-
**
|
|
107
|
+
**modelUseCountTracker** (`ModelUseCountTracker`): Records a model selection after session.model.switch().
|
|
114
108
|
|
|
115
|
-
**subagents
|
|
109
|
+
**subagents** (`AgentControllerSubagent[]`): Subagent types exposed through the built-in subagent tool.
|
|
116
110
|
|
|
117
|
-
**subagents.
|
|
111
|
+
**subagents.id** (`string`): Unique subagent type identifier.
|
|
118
112
|
|
|
119
|
-
**subagents.
|
|
113
|
+
**subagents.name** (`string`): Display name.
|
|
120
114
|
|
|
121
|
-
**subagents.
|
|
115
|
+
**subagents.description** (`string`): Description used by the generated tool.
|
|
122
116
|
|
|
123
|
-
**subagents.
|
|
117
|
+
**subagents.instructions** (`DynamicArgument<AgentInstructions>`): Subagent instructions.
|
|
124
118
|
|
|
125
|
-
**subagents.
|
|
119
|
+
**subagents.tools** (`ToolsInput`): Tools owned by the subagent.
|
|
126
120
|
|
|
127
|
-
**
|
|
121
|
+
**subagents.allowedControllerTools** (`string[]`): Controller tool IDs added to the subagent tools.
|
|
128
122
|
|
|
129
|
-
**
|
|
123
|
+
**subagents.allowedWorkspaceTools** (`string[]`): Workspace tool names visible to the subagent.
|
|
130
124
|
|
|
131
|
-
**
|
|
125
|
+
**subagents.defaultModelId** (`string`): Default subagent model.
|
|
132
126
|
|
|
133
|
-
**
|
|
127
|
+
**subagents.maxSteps** (`number`): Maximum execution steps.
|
|
134
128
|
|
|
135
|
-
**
|
|
129
|
+
**subagents.stopWhen** (`LoopOptions["stopWhen"]`): Loop stop condition.
|
|
136
130
|
|
|
137
|
-
**
|
|
131
|
+
**subagents.forked** (`boolean`): Whether the subagent inherits a cloned parent thread by default.
|
|
138
132
|
|
|
139
|
-
**
|
|
133
|
+
**gateways** (`MastraModelGatewayInterface[]`): Custom model gateways merged with the built-in gateways.
|
|
140
134
|
|
|
141
|
-
**
|
|
135
|
+
**omConfig** (`AgentControllerOMConfig`): Default observational memory models and thresholds.
|
|
142
136
|
|
|
143
|
-
**
|
|
137
|
+
**disableBuiltinTools** (`BuiltinToolId[]`): Built-in controller tools to omit from runs.
|
|
144
138
|
|
|
145
|
-
**
|
|
139
|
+
**toolCategoryResolver** (`(toolName: string) => ToolCategory | null`): Maps tool names to permission categories.
|
|
146
140
|
|
|
147
|
-
**
|
|
141
|
+
**pubsub** (`PubSub`): PubSub implementation propagated to backing agents.
|
|
148
142
|
|
|
149
|
-
**
|
|
143
|
+
**threadLock** (`{ acquire: (threadId: string) => void | Promise<void>; release: (threadId: string) => void | Promise<void> }`): Lock implementation used to coordinate thread ownership.
|
|
150
144
|
|
|
151
|
-
**
|
|
152
|
-
|
|
153
|
-
**observability** (`ObservabilityEntrypoint`): Observability entrypoint for tracing, scoring, and feedback. When provided, the internal Mastra instance produces trace spans for agent runs.
|
|
145
|
+
**observability** (`ObservabilityEntrypoint`): Observability configuration for a standalone controller Mastra instance.
|
|
154
146
|
|
|
155
147
|
## Properties
|
|
156
148
|
|
|
157
|
-
**id** (`string`):
|
|
158
|
-
|
|
159
|
-
**session** (`Session`): The per-conversation state for the active conversation: identity, the active thread binding and reads, mode and model selection, run and abort state, the live stream, tool suspensions, follow-ups, approvals, permission grants, token usage, and the display-state snapshot. See the Session reference for the full API.
|
|
149
|
+
**id** (`string`): The controller identifier passed to the constructor.
|
|
160
150
|
|
|
161
151
|
## Methods
|
|
162
152
|
|
|
163
|
-
###
|
|
164
|
-
|
|
165
|
-
#### `init()`
|
|
166
|
-
|
|
167
|
-
Initialize the agentController. Loads storage, initializes a static workspace (runtime-defined factory workspaces are resolved per-session during `createSession`), propagates memory and workspace to mode agents, and starts interval handlers. Call this before using the agentController.
|
|
168
|
-
|
|
169
|
-
```typescript
|
|
170
|
-
await agentController.init()
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
#### `createSession({ id, ownerId, resourceId?, tags?, workspace?, browser?, requestContext? })`
|
|
174
|
-
|
|
175
|
-
Create a new, fully-wired `Session` and bring it online. The session starts in the default mode with the seeded model, connects to the AgentController's shared machinery (agent, storage/lock, config catalog), and has a current thread (the most recent thread for the resource, or a freshly created one). Call `init()` once before creating sessions so shared storage is ready.
|
|
153
|
+
### Sessions
|
|
176
154
|
|
|
177
|
-
|
|
155
|
+
#### `createSession(options)`
|
|
178
156
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
Each session owns its own `Workspace` and `Browser` instance. When `workspace` is omitted, the AgentController resolves its configured workspace (a static instance or a runtime-defined factory) and passes it to the session. Pass a `workspace` override to give a specific session a different workspace than the AgentController default. The workspace is initialized during session creation; `workspace_ready` and `workspace_status_changed` events are emitted on the session bus after `init()` completes, and late subscribers receive a replay of the last workspace status.
|
|
182
|
-
|
|
183
|
-
```typescript
|
|
184
|
-
const session = await agentController.createSession({
|
|
185
|
-
id: 'session-xyz',
|
|
186
|
-
ownerId: 'user-123',
|
|
187
|
-
})
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
You can also override the resource:
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
const session = await agentController.createSession({
|
|
194
|
-
id: 'session-xyz',
|
|
195
|
-
ownerId: 'user-123',
|
|
196
|
-
resourceId: 'project-abc',
|
|
197
|
-
})
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
Override the workspace and browser for a specific session:
|
|
157
|
+
Get or create the live session registered for the `(resourceId, scope)` pair. Call `init()` before this method.
|
|
201
158
|
|
|
202
159
|
```typescript
|
|
203
|
-
const session = await
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
browser: myBrowser,
|
|
160
|
+
const session = await controller.createSession({
|
|
161
|
+
resourceId: 'project-42',
|
|
162
|
+
scope: 'editor-window-1',
|
|
163
|
+
threadId: 'thread-7',
|
|
208
164
|
})
|
|
209
165
|
```
|
|
210
166
|
|
|
211
|
-
`
|
|
212
|
-
|
|
213
|
-
Switching the resource ID via `agentController.setResourceId()` changes only the resource ID, not `id` or `ownerId`. Read them through `session.identity.getId()` and `session.identity.getOwnerId()`.
|
|
167
|
+
The same `resourceId` and `scope` return the same `Session` instance. A different scope creates an isolated session for the same resource. When `threadId` is supplied, the method switches a cached session to that thread or creates the thread when it doesn't exist.
|
|
214
168
|
|
|
215
|
-
|
|
169
|
+
**resourceId** (`string`): Memory resource and live-session registry key. Defaults to the configured resourceId or controller id.
|
|
216
170
|
|
|
217
|
-
|
|
171
|
+
**scope** (`string`): Optional registry namespace that allows multiple live sessions for one resource.
|
|
218
172
|
|
|
219
|
-
|
|
220
|
-
const thread = await agentController.selectOrCreateThread()
|
|
221
|
-
```
|
|
173
|
+
**threadId** (`string`): Exact thread to bind. Missing threads are created with this identifier.
|
|
222
174
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
Stop all interval handlers and clean up resources.
|
|
226
|
-
|
|
227
|
-
```typescript
|
|
228
|
-
await agentController.destroy()
|
|
229
|
-
```
|
|
175
|
+
**id** (`string`): Stable session identifier. Defaults to the controller id.
|
|
230
176
|
|
|
231
|
-
|
|
177
|
+
**ownerId** (`string`): Stable session owner identifier. Defaults to id.
|
|
232
178
|
|
|
233
|
-
|
|
179
|
+
**tags** (`Record<string, string>`): Tags copied to threads created by the session.
|
|
234
180
|
|
|
235
|
-
|
|
236
|
-
await agentController.removeInterval({ id: 'gateway-sync' })
|
|
237
|
-
```
|
|
181
|
+
**workspace** (`Workspace`): Workspace override for this session.
|
|
238
182
|
|
|
239
|
-
|
|
183
|
+
**browser** (`MastraBrowser`): Browser override for this session.
|
|
240
184
|
|
|
241
|
-
|
|
185
|
+
**requestContext** (`RequestContext`): Context used to resolve dynamic workspace and browser factories.
|
|
242
186
|
|
|
243
|
-
|
|
244
|
-
await agentController.stopIntervals()
|
|
245
|
-
```
|
|
187
|
+
Returns: `Promise<Session<TState>>`
|
|
246
188
|
|
|
247
|
-
#### `
|
|
189
|
+
#### `getSessionByResource(resourceId, scope?)`
|
|
248
190
|
|
|
249
|
-
Return the
|
|
191
|
+
Return the live session registered for a resource and optional scope.
|
|
250
192
|
|
|
251
193
|
```typescript
|
|
252
|
-
const
|
|
194
|
+
const session = await controller.getSessionByResource('project-42', 'editor-window-1')
|
|
253
195
|
```
|
|
254
196
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
Return the resolved memory instance, or `null` if no memory is configured.
|
|
258
|
-
|
|
259
|
-
```typescript
|
|
260
|
-
const memory = await agentController.getResolvedMemory()
|
|
261
|
-
```
|
|
197
|
+
Returns: `Promise<Session<TState> | undefined>`
|
|
262
198
|
|
|
263
|
-
#### `
|
|
199
|
+
#### `setResourceId(session, { resourceId })`
|
|
264
200
|
|
|
265
|
-
|
|
201
|
+
Move a live session to another resource and clear its active thread binding.
|
|
266
202
|
|
|
267
203
|
```typescript
|
|
268
|
-
|
|
204
|
+
await controller.setResourceId(session, { resourceId: 'project-43' })
|
|
269
205
|
```
|
|
270
206
|
|
|
271
|
-
#### `
|
|
207
|
+
#### `getKnownResourceIds(session)`
|
|
272
208
|
|
|
273
|
-
|
|
209
|
+
List resource identifiers present in stored threads.
|
|
274
210
|
|
|
275
211
|
```typescript
|
|
276
|
-
const
|
|
212
|
+
const resourceIds = await controller.getKnownResourceIds(session)
|
|
277
213
|
```
|
|
278
214
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
Eagerly resolve and cache the workspace. For runtime-defined workspaces (factory function), this triggers the factory against the session's request context and caches the result so `getWorkspace()` returns it. Returns the resolved workspace or `undefined` if none is configured.
|
|
282
|
-
|
|
283
|
-
```typescript
|
|
284
|
-
const workspace = await agentController.resolveWorkspace({ session })
|
|
285
|
-
```
|
|
215
|
+
Returns: `Promise<string[]>`
|
|
286
216
|
|
|
287
|
-
|
|
288
|
-
// With an explicit request context
|
|
289
|
-
const requestContext = new RequestContext()
|
|
290
|
-
const workspace = await agentController.resolveWorkspace({ session, requestContext })
|
|
291
|
-
```
|
|
217
|
+
### Lifecycle
|
|
292
218
|
|
|
293
|
-
#### `
|
|
219
|
+
#### `init()`
|
|
294
220
|
|
|
295
|
-
|
|
221
|
+
Initialize shared storage, workspace services, and configured interval handlers. Repeated calls reuse the same initialization promise.
|
|
296
222
|
|
|
297
223
|
```typescript
|
|
298
|
-
|
|
299
|
-
// ...
|
|
300
|
-
}
|
|
224
|
+
await controller.init()
|
|
301
225
|
```
|
|
302
226
|
|
|
303
|
-
#### `
|
|
227
|
+
#### `destroy()`
|
|
304
228
|
|
|
305
|
-
|
|
229
|
+
Stop controller-owned interval handlers. This doesn't destroy Sessions created by the controller.
|
|
306
230
|
|
|
307
231
|
```typescript
|
|
308
|
-
|
|
309
|
-
// ...
|
|
310
|
-
}
|
|
232
|
+
await controller.destroy()
|
|
311
233
|
```
|
|
312
234
|
|
|
313
|
-
### Modes
|
|
235
|
+
### Modes and agents
|
|
314
236
|
|
|
315
237
|
#### `listModes()`
|
|
316
238
|
|
|
317
|
-
Return
|
|
239
|
+
Return the configured mode definitions.
|
|
318
240
|
|
|
319
241
|
```typescript
|
|
320
|
-
const modes =
|
|
242
|
+
const modes = controller.listModes()
|
|
321
243
|
```
|
|
322
244
|
|
|
323
|
-
|
|
245
|
+
Returns: `AgentControllerMode[]`
|
|
324
246
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
To read the active model ID, use [`session.model.get()`](https://mastra.ai/reference/agent-controller/session); for a short display name, use [`session.model.displayName()`](https://mastra.ai/reference/agent-controller/session); to check whether a model is selected, use [`session.model.hasSelection()`](https://mastra.ai/reference/agent-controller/session).
|
|
328
|
-
|
|
329
|
-
#### `getCurrentModelAuthStatus()`
|
|
330
|
-
|
|
331
|
-
Check if the current model's provider has authentication configured. Uses `modelAuthChecker` if provided, falling back to environment variable checks from the provider registry.
|
|
332
|
-
|
|
333
|
-
```typescript
|
|
334
|
-
const status = await agentController.getCurrentModelAuthStatus()
|
|
335
|
-
// { hasAuth: true, apiKeyEnvVar: 'ANTHROPIC_API_KEY' }
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
#### `listAvailableModels()`
|
|
247
|
+
#### `getCurrentAgent(session)`
|
|
339
248
|
|
|
340
|
-
|
|
249
|
+
Return the backing agent for the session's active mode.
|
|
341
250
|
|
|
342
251
|
```typescript
|
|
343
|
-
const
|
|
344
|
-
// [{ id, provider, modelName, hasApiKey, apiKeyEnvVar, useCount }]
|
|
252
|
+
const agent = controller.getCurrentAgent(session)
|
|
345
253
|
```
|
|
346
254
|
|
|
347
|
-
|
|
255
|
+
Returns: `Agent`
|
|
348
256
|
|
|
349
|
-
|
|
257
|
+
### Workspace and browser
|
|
350
258
|
|
|
351
|
-
#### `
|
|
352
|
-
|
|
353
|
-
Creates a new thread and initializes its metadata. The method saves it to storage and acquires a thread lock before emitting a `thread_created` event.
|
|
354
|
-
|
|
355
|
-
```typescript
|
|
356
|
-
const thread = await agentController.createThread({ title: 'New conversation' })
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
#### `switchThread({ threadId })`
|
|
360
|
-
|
|
361
|
-
Switch to a different thread. This aborts in-progress operations and acquires a lock on the new thread. It releases the previous thread lock and loads the new thread metadata. It then emits a `thread_changed` event.
|
|
362
|
-
|
|
363
|
-
```typescript
|
|
364
|
-
await agentController.switchThread({ threadId: 'thread-abc123' })
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
To list threads from storage, use [`session.thread.list()`](https://mastra.ai/reference/agent-controller/session). By default it returns only threads for the current resource and hides transient [forked subagent](#forked-subagents) threads. Pass `includeForkedSubagents: true` to opt back into seeing them: e.g. for a debug panel.
|
|
368
|
-
|
|
369
|
-
#### `renameThread({ title })`
|
|
370
|
-
|
|
371
|
-
Update the title of the current thread.
|
|
372
|
-
|
|
373
|
-
```typescript
|
|
374
|
-
await agentController.renameThread({ title: 'Updated title' })
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
#### `cloneThread({ sourceThreadId?, title?, resourceId? })`
|
|
259
|
+
#### `hasWorkspace()`
|
|
378
260
|
|
|
379
|
-
|
|
261
|
+
Report whether the controller has a static, dynamic, or object-based workspace configuration.
|
|
380
262
|
|
|
381
263
|
```typescript
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
// Clone a specific thread with a custom title
|
|
386
|
-
const cloned = await agentController.cloneThread({
|
|
387
|
-
sourceThreadId: 'thread-abc123',
|
|
388
|
-
title: 'Alternative approach',
|
|
389
|
-
})
|
|
264
|
+
if (controller.hasWorkspace()) {
|
|
265
|
+
console.log('Workspace configured')
|
|
266
|
+
}
|
|
390
267
|
```
|
|
391
268
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
To read the current resource ID, use [`session.identity.getResourceId()`](https://mastra.ai/reference/agent-controller/session).
|
|
269
|
+
Returns: `boolean`
|
|
395
270
|
|
|
396
|
-
#### `
|
|
271
|
+
#### `isWorkspaceReady()`
|
|
397
272
|
|
|
398
|
-
|
|
273
|
+
Report whether the controller-level workspace is ready.
|
|
399
274
|
|
|
400
275
|
```typescript
|
|
401
|
-
|
|
276
|
+
const ready = controller.isWorkspaceReady()
|
|
402
277
|
```
|
|
403
278
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
Return the distinct resource IDs that have threads in storage.
|
|
279
|
+
Returns: `boolean`
|
|
407
280
|
|
|
408
|
-
|
|
409
|
-
const resourceIds = await agentController.getKnownResourceIds()
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
#### `getSession()`
|
|
281
|
+
#### `getWorkspace()`
|
|
413
282
|
|
|
414
|
-
Return
|
|
283
|
+
Return a static controller workspace. Dynamic workspace factories return `undefined` until resolved.
|
|
415
284
|
|
|
416
285
|
```typescript
|
|
417
|
-
const
|
|
418
|
-
// { currentThreadId, currentModeId, threads }
|
|
286
|
+
const workspace = controller.getWorkspace()
|
|
419
287
|
```
|
|
420
288
|
|
|
421
|
-
|
|
289
|
+
Returns: `Workspace | undefined`
|
|
422
290
|
|
|
423
|
-
#### `
|
|
291
|
+
#### `resolveWorkspace({ session, requestContext? })`
|
|
424
292
|
|
|
425
|
-
|
|
293
|
+
Resolve a dynamic workspace for a session and cache the result on the controller.
|
|
426
294
|
|
|
427
295
|
```typescript
|
|
428
|
-
await
|
|
296
|
+
const workspace = await controller.resolveWorkspace({ session, requestContext })
|
|
429
297
|
```
|
|
430
298
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
### Memory
|
|
434
|
-
|
|
435
|
-
The `memory` property bundles thread management operations into a single namespace. `memory.createThread`, `memory.switchThread`, and `memory.renameThread` delegate to the corresponding AgentController lifecycle methods documented above. `memory.listThreads` delegates to [`session.thread.list()`](https://mastra.ai/reference/agent-controller/session).
|
|
299
|
+
Returns: `Promise<Workspace | undefined>`
|
|
436
300
|
|
|
437
|
-
#### `
|
|
301
|
+
#### `setBrowser(browser)`
|
|
438
302
|
|
|
439
|
-
|
|
303
|
+
Replace the controller browser and propagate it to the backing agents.
|
|
440
304
|
|
|
441
305
|
```typescript
|
|
442
|
-
|
|
306
|
+
controller.setBrowser(browser)
|
|
443
307
|
```
|
|
444
308
|
|
|
445
|
-
###
|
|
309
|
+
### Mastra and channels
|
|
446
310
|
|
|
447
|
-
#### `
|
|
311
|
+
#### `getMastra()`
|
|
448
312
|
|
|
449
|
-
|
|
313
|
+
Return the parent Mastra instance or the internal instance created by `init()`.
|
|
450
314
|
|
|
451
315
|
```typescript
|
|
452
|
-
|
|
316
|
+
const mastra = controller.getMastra()
|
|
453
317
|
```
|
|
454
318
|
|
|
455
|
-
|
|
319
|
+
Returns: `Mastra | undefined`
|
|
456
320
|
|
|
457
|
-
|
|
321
|
+
#### `getChannels()`
|
|
458
322
|
|
|
459
|
-
|
|
460
|
-
agentController.steer({ content: 'Focus on security implications' })
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
#### `followUp({ content, requestContext? })`
|
|
464
|
-
|
|
465
|
-
Queue a follow-up message to be sent after the current generation completes. If no operation is running, sends the message immediately.
|
|
323
|
+
Return the configured chat channel integration.
|
|
466
324
|
|
|
467
325
|
```typescript
|
|
468
|
-
|
|
326
|
+
const channels = controller.getChannels()
|
|
469
327
|
```
|
|
470
328
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
Responding to a pending tool approval is owned by the session: see [`session.respondToToolApproval()`](https://mastra.ai/reference/agent-controller/session). The agentController owns the permission _policy_ that decides when approval is required, documented under [Permissions](#permissions) below.
|
|
329
|
+
Returns: `AgentControllerChannels | null`
|
|
474
330
|
|
|
475
|
-
###
|
|
476
|
-
|
|
477
|
-
#### `respondToToolSuspension({ resumeData, toolCallId?, requestContext? })`
|
|
331
|
+
### Models
|
|
478
332
|
|
|
479
|
-
|
|
333
|
+
#### `getCurrentModelAuthStatus(session)`
|
|
480
334
|
|
|
481
|
-
|
|
335
|
+
Return authentication status for the session's selected model.
|
|
482
336
|
|
|
483
337
|
```typescript
|
|
484
|
-
|
|
485
|
-
if (event.type === 'tool_suspended' && event.toolName === 'ask_user') {
|
|
486
|
-
const { question } = event.suspendPayload as { question: string }
|
|
487
|
-
// Show `question` to the user, then resume the tool with their answer.
|
|
488
|
-
agentController.respondToToolSuspension({
|
|
489
|
-
toolCallId: event.toolCallId,
|
|
490
|
-
resumeData: 'Yes, proceed with the refactor',
|
|
491
|
-
})
|
|
492
|
-
}
|
|
493
|
-
})
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
For multi-select questions, pass the selected option labels as a string array.
|
|
497
|
-
|
|
498
|
-
```typescript
|
|
499
|
-
agentController.respondToToolSuspension({
|
|
500
|
-
toolCallId: event.toolCallId,
|
|
501
|
-
resumeData: ['Add tests', 'Update docs'],
|
|
502
|
-
})
|
|
338
|
+
const status = await controller.getCurrentModelAuthStatus(session)
|
|
503
339
|
```
|
|
504
340
|
|
|
505
|
-
|
|
341
|
+
Returns: `Promise<ModelAuthStatus>`
|
|
506
342
|
|
|
507
|
-
|
|
343
|
+
#### `listAvailableModels()`
|
|
508
344
|
|
|
509
|
-
|
|
345
|
+
List models from the configured and built-in gateways. Results are cached briefly and sorted with usage data when `modelUseCountProvider` is configured.
|
|
510
346
|
|
|
511
347
|
```typescript
|
|
512
|
-
|
|
513
|
-
toolCallId: event.toolCallId,
|
|
514
|
-
resumeData: { action: 'approved' },
|
|
515
|
-
})
|
|
516
|
-
agentController.respondToToolSuspension({
|
|
517
|
-
toolCallId: event.toolCallId,
|
|
518
|
-
resumeData: { action: 'rejected', feedback: 'Needs more detail' },
|
|
519
|
-
})
|
|
348
|
+
const models = await controller.listAvailableModels()
|
|
520
349
|
```
|
|
521
350
|
|
|
522
|
-
|
|
351
|
+
Returns: `Promise<AvailableModel[]>`
|
|
523
352
|
|
|
524
|
-
#### `
|
|
353
|
+
#### `invalidateAvailableModelsCache()`
|
|
525
354
|
|
|
526
|
-
|
|
355
|
+
Clear the available-model cache.
|
|
527
356
|
|
|
528
357
|
```typescript
|
|
529
|
-
|
|
530
|
-
// 'edit'
|
|
358
|
+
controller.invalidateAvailableModelsCache()
|
|
531
359
|
```
|
|
532
360
|
|
|
533
|
-
### Observational
|
|
361
|
+
### Observational memory and permissions
|
|
534
362
|
|
|
535
|
-
#### `loadOMProgress()`
|
|
363
|
+
#### `loadOMProgress(session)`
|
|
536
364
|
|
|
537
|
-
Load observational memory
|
|
365
|
+
Load stored observational memory progress for the active thread and emit an `om_status` event.
|
|
538
366
|
|
|
539
367
|
```typescript
|
|
540
|
-
await
|
|
368
|
+
await controller.loadOMProgress(session)
|
|
541
369
|
```
|
|
542
370
|
|
|
543
|
-
#### `getObservationalMemoryRecord()`
|
|
371
|
+
#### `getObservationalMemoryRecord(session)`
|
|
544
372
|
|
|
545
|
-
Return the
|
|
373
|
+
Return the observational memory record for the active thread.
|
|
546
374
|
|
|
547
375
|
```typescript
|
|
548
|
-
const record = await
|
|
549
|
-
|
|
550
|
-
if (record) {
|
|
551
|
-
console.log(record.activeObservations)
|
|
552
|
-
console.log(record.generationCount)
|
|
553
|
-
console.log(record.observationTokenCount)
|
|
554
|
-
}
|
|
376
|
+
const record = await controller.getObservationalMemoryRecord(session)
|
|
555
377
|
```
|
|
556
378
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
### Forked subagents
|
|
379
|
+
Returns: `Promise<ObservationalMemoryRecord | null>`
|
|
560
380
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
#### Enabling forked mode
|
|
381
|
+
#### `getToolCategory({ toolName })`
|
|
564
382
|
|
|
565
|
-
|
|
383
|
+
Resolve the permission category for a tool.
|
|
566
384
|
|
|
567
385
|
```typescript
|
|
568
|
-
|
|
569
|
-
const subagents: AgentControllerSubagent[] = [
|
|
570
|
-
{
|
|
571
|
-
id: 'collaborator',
|
|
572
|
-
name: 'Collaborator',
|
|
573
|
-
description: 'Continues the conversation in a fork to try a different angle.',
|
|
574
|
-
instructions: '...',
|
|
575
|
-
forked: true,
|
|
576
|
-
},
|
|
577
|
-
]
|
|
386
|
+
const category = controller.getToolCategory({ toolName: 'execute_command' })
|
|
578
387
|
```
|
|
579
388
|
|
|
580
|
-
|
|
389
|
+
Returns: `ToolCategory | null`
|
|
581
390
|
|
|
582
|
-
|
|
391
|
+
### Intervals
|
|
583
392
|
|
|
584
|
-
|
|
585
|
-
- **Parent agent reused.** The fork runs through the parent agent's `stream(...)` call. The parent's instructions, tools, model, `maxSteps`, and `stopWhen` apply. The subagent definition's `instructions`, `tools`, `allowedAgentControllerTools`, `allowedWorkspaceTools`, `defaultModelId`, `maxSteps`, and `stopWhen` are ignored in forked mode. This preserves the prompt-cache prefix.
|
|
586
|
-
- **Toolsets inherited, recursive forks blocked at runtime.** Forks inherit the parent's toolsets verbatim (`ask_user`, `submit_plan`, user-configured agentController tools, _including the `subagent` tool itself_) so the LLM request prefix, system prompt + tool list + tool schemas + tool descriptions, stays byte-identical to the parent's. This is what preserves the prompt cache. The `subagent` entry is kept on the model side but its `execute` is replaced inside the fork with a stub that returns a non-error "tool unavailable inside a forked subagent" message: nested forks are blocked at the runtime layer without perturbing the cached prefix.
|
|
587
|
-
- **Fork threads are tagged.** Each fork thread is created with `metadata.forkedSubagent === true` and `metadata.parentThreadId === <parent>`. By default, [`session.thread.list()`](https://mastra.ai/reference/agent-controller/session) hides these so they don't show up in user-facing thread pickers / startup flows. Pass `includeForkedSubagents: true` to see them in admin / debug tooling.
|
|
588
|
-
- **Save-queue flushed before clone.** The agent stream batches message saves through a debounced `SaveQueueManager`, so the parent's latest user / assistant turn may not be on disk yet when the subagent tool call fires. The fork tool flushes pending saves first via the `flushMessages` callback on `AgentToolExecutionContext` before cloning, so the fork actually carries the latest turn. Flush failures are non-fatal: the clone still runs.
|
|
589
|
-
- **Parent thread untouched.** All subagent activity (messages, OM writes) lands on the fork. The parent thread is never appended to during a forked subagent run.
|
|
393
|
+
#### `registerInterval(handler)`
|
|
590
394
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
Forked mode trades isolation for context inheritance. Use the default (non-forked) mode when the subagent needs a restricted toolset or a different system prompt. The same applies when using a cheaper model. Pass any required context explicitly in the `task` description.
|
|
594
|
-
|
|
595
|
-
### Events
|
|
596
|
-
|
|
597
|
-
#### `subscribe(listener)`
|
|
598
|
-
|
|
599
|
-
Register an event listener. Returns an unsubscribe function.
|
|
600
|
-
|
|
601
|
-
Use this method for all consumers: UI, Server-Sent Events (SSE), terminal UI (TUI), bridge rendering, audit logs, debugging, analytics, and deterministic replay. For display rendering, watch for the `display_state_changed` event and read the latest snapshot from [`session.displayState.get()`](https://mastra.ai/reference/agent-controller/session). After every event the agentController emits `display_state_changed`, so high-frequency events such as `message_update`, `tool_update`, and `tool_input_delta` are coalesced into the next snapshot.
|
|
395
|
+
Start or replace a periodic handler.
|
|
602
396
|
|
|
603
397
|
```typescript
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
}
|
|
398
|
+
controller.registerInterval({
|
|
399
|
+
id: 'refresh',
|
|
400
|
+
intervalMs: 60_000,
|
|
401
|
+
handler: async () => refreshData(),
|
|
609
402
|
})
|
|
610
|
-
|
|
611
|
-
// Render an initial frame before the next agentController event:
|
|
612
|
-
render(agentController.session.displayState.get())
|
|
613
403
|
```
|
|
614
404
|
|
|
615
|
-
|
|
405
|
+
#### `removeInterval({ id })`
|
|
616
406
|
|
|
617
|
-
|
|
618
|
-
const unsubscribe = agentController.subscribe(event => {
|
|
619
|
-
switch (event.type) {
|
|
620
|
-
case 'message_update':
|
|
621
|
-
renderMessage(event.message)
|
|
622
|
-
break
|
|
623
|
-
case 'tool_approval_required':
|
|
624
|
-
showApprovalPrompt(event.toolName)
|
|
625
|
-
break
|
|
626
|
-
case 'error':
|
|
627
|
-
console.error(event.error)
|
|
628
|
-
break
|
|
629
|
-
}
|
|
630
|
-
})
|
|
407
|
+
Stop one interval and run its optional shutdown callback.
|
|
631
408
|
|
|
632
|
-
|
|
633
|
-
|
|
409
|
+
```typescript
|
|
410
|
+
await controller.removeInterval({ id: 'refresh' })
|
|
634
411
|
```
|
|
635
412
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
| Event type | Description |
|
|
641
|
-
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
642
|
-
| `mode_changed` | The active mode changed. |
|
|
643
|
-
| `model_changed` | The active model changed. |
|
|
644
|
-
| `thread_changed` | The active thread changed. |
|
|
645
|
-
| `thread_created` | A new thread was created. |
|
|
646
|
-
| `thread_deleted` | A thread was deleted. |
|
|
647
|
-
| `state_changed` | AgentController state was updated. |
|
|
648
|
-
| `agent_start` | The agent started processing. |
|
|
649
|
-
| `agent_end` | The agent finished processing. |
|
|
650
|
-
| `message_start` | A new message started streaming. |
|
|
651
|
-
| `message_update` | A message was updated with new content. |
|
|
652
|
-
| `message_end` | A message finished streaming. |
|
|
653
|
-
| `tool_start` | A tool call started. |
|
|
654
|
-
| `tool_approval_required` | A tool call requires user approval. |
|
|
655
|
-
| `tool_suspended` | A tool paused via the native tool-suspension primitive (for example `ask_user`, `request_access`, or `submit_plan`). Includes `toolCallId`, `toolName`, and `suspendPayload`. Resume it with [`respondToToolSuspension`](#respondtotoolsuspension-resumedata-toolcallid-requestcontext-). |
|
|
656
|
-
| `tool_update` | A tool call was updated with progress. |
|
|
657
|
-
| `tool_end` | A tool call finished. |
|
|
658
|
-
| `tool_input_start` | Tool input started streaming. |
|
|
659
|
-
| `tool_input_delta` | Tool input received a streaming delta. |
|
|
660
|
-
| `tool_input_end` | Tool input finished streaming. |
|
|
661
|
-
| `usage_update` | Token usage was updated. |
|
|
662
|
-
| `error` | An error occurred. |
|
|
663
|
-
| `info` | An informational message was emitted. |
|
|
664
|
-
| `system_reminder` | A system reminder was injected into the conversation. |
|
|
665
|
-
| `state_signal` | A state signal was emitted (state-driven prompt injection). |
|
|
666
|
-
| `reactive_signal` | A reactive signal fired in response to a state change. |
|
|
667
|
-
| `notification` | A notification was delivered to the thread inbox. |
|
|
668
|
-
| `notification_summary` | A summary of pending notifications was emitted. |
|
|
669
|
-
| `follow_up_queued` | A follow-up message was queued. |
|
|
670
|
-
| `workspace_status_changed` | The workspace status changed. |
|
|
671
|
-
| `workspace_ready` | The workspace finished initializing. |
|
|
672
|
-
| `workspace_error` | The workspace encountered an error. |
|
|
673
|
-
| `om_status` | Observational Memory status update. |
|
|
674
|
-
| `om_activation` | Observational Memory was activated for the thread. |
|
|
675
|
-
| `om_model_changed` | An Observational Memory role model changed (`observer` or `reflector`). |
|
|
676
|
-
| `om_observation_start` | An observation started. |
|
|
677
|
-
| `om_observation_end` | An observation completed. |
|
|
678
|
-
| `om_observation_failed` | An observation failed. |
|
|
679
|
-
| `om_reflection_start` | A reflection started. |
|
|
680
|
-
| `om_reflection_end` | A reflection completed. |
|
|
681
|
-
| `om_reflection_failed` | A reflection failed. |
|
|
682
|
-
| `om_buffering_start` | Observational Memory started buffering messages. |
|
|
683
|
-
| `om_buffering_end` | Observational Memory finished buffering messages. |
|
|
684
|
-
| `om_buffering_failed` | Observational Memory buffering failed. |
|
|
685
|
-
| `om_thread_title_updated` | Observational Memory updated the thread title. |
|
|
686
|
-
| `subagent_start` | A subagent started processing. |
|
|
687
|
-
| `subagent_text_delta` | A subagent emitted a text delta. |
|
|
688
|
-
| `subagent_tool_start` | A subagent started a tool call. |
|
|
689
|
-
| `subagent_tool_end` | A subagent finished a tool call. |
|
|
690
|
-
| `subagent_end` | A subagent finished processing. |
|
|
691
|
-
| `subagent_model_changed` | A subagent's model changed. |
|
|
692
|
-
| `task_updated` | A task list was updated. |
|
|
693
|
-
| `goal_evaluation` | A goal evaluation completed (when native agent goals are configured). |
|
|
694
|
-
| `shell_output` | A tool emitted shell output (stdout or stderr). |
|
|
695
|
-
| `display_state_changed` | The canonical `AgentControllerDisplayState` snapshot changed. Read it from [`session.displayState.get()`](https://mastra.ai/reference/agent-controller/session). |
|
|
696
|
-
|
|
697
|
-
The agentController also emits low-level streaming content chunks: `text`, `thinking`, `tool_call`, `tool_result`, `image`, and `file`. These are the raw pieces that get assembled into messages. Most UIs render from `message_update` (or read the [`session.displayState`](https://mastra.ai/reference/agent-controller/session) snapshot) rather than subscribing to them directly.
|
|
698
|
-
|
|
699
|
-
## Built-in tools
|
|
700
|
-
|
|
701
|
-
The agentController provides built-in tools to agents in every mode:
|
|
702
|
-
|
|
703
|
-
| Tool | Description |
|
|
704
|
-
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
705
|
-
| `ask_user` | Ask the user a question and wait for their response. Supports free text, single-select choices, and multi-select choices. |
|
|
706
|
-
| `submit_plan` | Submit a plan for user review and approval. |
|
|
707
|
-
| `task_write` | Create or replace a structured task list for tracking progress. Assigns task IDs when omitted and returns the structured task list snapshot. |
|
|
708
|
-
| `task_update` | Update one tracked task by ID and return the structured task list snapshot. |
|
|
709
|
-
| `task_complete` | Mark one tracked task completed by ID and return the structured task list snapshot. |
|
|
710
|
-
| `task_check` | Check the completion status of the current task list and return `tasks`, `summary`, `incompleteTasks`, and `isError` fields. |
|
|
711
|
-
| `subagent` | Spawn a focused subagent with constrained tools (only available when `subagents` is configured). Pass `forked: true` to inherit the parent conversation. See [Forked subagents](#forked-subagents). |
|
|
712
|
-
|
|
713
|
-
### `ask_user` selections
|
|
714
|
-
|
|
715
|
-
The `ask_user` tool accepts `options` for choice prompts. Set `selectionMode` to `single_select` to let the user pick one option, or `multi_select` to let the user pick multiple options. When `options` are provided and `selectionMode` is omitted, the prompt defaults to `single_select`. Omit `options` for free-text questions.
|
|
716
|
-
|
|
717
|
-
The following example demonstrates a multi-select response handler. The tool pauses through the `tool_suspended` event, the UI reads `selectionMode` from `event.suspendPayload`, lets the user choose multiple options, then returns a string array with `respondToToolSuspension()`.
|
|
413
|
+
#### `stopIntervals()`
|
|
414
|
+
|
|
415
|
+
Stop all intervals and run their optional shutdown callbacks.
|
|
718
416
|
|
|
719
417
|
```typescript
|
|
720
|
-
|
|
721
|
-
if (event.type === 'tool_suspended' && event.toolName === 'ask_user') {
|
|
722
|
-
const { selectionMode } = event.suspendPayload as { selectionMode?: string }
|
|
723
|
-
if (selectionMode === 'multi_select') {
|
|
724
|
-
agentController.respondToToolSuspension({
|
|
725
|
-
toolCallId: event.toolCallId,
|
|
726
|
-
resumeData: ['Add tests', 'Update docs'],
|
|
727
|
-
})
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
})
|
|
418
|
+
await controller.stopIntervals()
|
|
731
419
|
```
|
|
732
420
|
|
|
733
421
|
## Related
|
|
734
422
|
|
|
735
|
-
- [
|
|
736
|
-
- [
|
|
737
|
-
- [
|
|
738
|
-
- [
|
|
423
|
+
- [AgentController guide](https://mastra.ai/docs/harness/agent-controller)
|
|
424
|
+
- [Session reference](https://mastra.ai/reference/agent-controller/session)
|
|
425
|
+
- [Agents](https://mastra.ai/docs/agents/overview)
|
|
426
|
+
- [Workspace](https://mastra.ai/docs/workspace/overview)
|
|
427
|
+
- [Channels](https://mastra.ai/docs/capabilities/channels/overview)
|