@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,30 +1,31 @@
|
|
|
1
1
|
> Discover all available pages from the documentation index: https://mastra.ai/llms.txt
|
|
2
2
|
|
|
3
|
-
# Session
|
|
3
|
+
# Session
|
|
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
|
-
A `Session`
|
|
7
|
+
A `Session` is the isolated runtime for one resource and optional scope. It owns its event bus, thread binding, state, mode and model selections, run control, approvals, suspensions, follow-ups, and display state. The [`AgentController`](https://mastra.ai/reference/agent-controller/agent-controller-class) supplies shared agents, configuration, storage, workspaces, and services.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Create sessions through `controller.createSession()`. Direct construction and controller wiring methods aren't application APIs.
|
|
10
10
|
|
|
11
|
-
For a conceptual introduction, see the [AgentController overview](https://mastra.ai/docs/agent-controller
|
|
11
|
+
For a conceptual introduction, see the [AgentController overview](https://mastra.ai/docs/harness/agent-controller).
|
|
12
12
|
|
|
13
13
|
## Usage example
|
|
14
14
|
|
|
15
|
+
The following example uses the supported controller-to-session flow.
|
|
16
|
+
|
|
15
17
|
```typescript
|
|
16
|
-
|
|
17
|
-
const modeId = agentController.session.mode.get()
|
|
18
|
-
const modelId = agentController.session.model.get()
|
|
19
|
-
const threadId = agentController.session.thread.getId()
|
|
20
|
-
const grants = agentController.session.getGrants()
|
|
18
|
+
await controller.init()
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
const session = await controller.createSession({ resourceId: 'project-42' })
|
|
21
|
+
const unsubscribe = session.subscribe(event => {
|
|
24
22
|
if (event.type === 'display_state_changed') {
|
|
25
|
-
render(
|
|
23
|
+
render(event.displayState)
|
|
26
24
|
}
|
|
27
25
|
})
|
|
26
|
+
|
|
27
|
+
await session.sendMessage({ content: 'Review the current project.' })
|
|
28
|
+
unsubscribe()
|
|
28
29
|
```
|
|
29
30
|
|
|
30
31
|
## Properties
|
|
@@ -39,6 +40,12 @@ The session is organized into sub-objects, each owning one domain of per-convers
|
|
|
39
40
|
|
|
40
41
|
**model** (`SessionModel`): Active model selection, including per-mode persistence. See model methods below.
|
|
41
42
|
|
|
43
|
+
**om** (`SessionOM`): Observer and reflector model settings for observational memory.
|
|
44
|
+
|
|
45
|
+
**permissions** (`SessionPermissions`): Tool and category permission policies represented in session state.
|
|
46
|
+
|
|
47
|
+
**subagents** (`SessionSubagents`): Global and per-agent-type subagent model selection.
|
|
48
|
+
|
|
42
49
|
**run** (`SessionRun`): Run and trace identity plus abort state for the in-flight run. See run methods below.
|
|
43
50
|
|
|
44
51
|
**stream** (`SessionStream`): The live subscription to the agent thread stream. See stream methods below.
|
|
@@ -51,12 +58,85 @@ The session is organized into sub-objects, each owning one domain of per-convers
|
|
|
51
58
|
|
|
52
59
|
**displayState** (`SessionDisplayState`): The canonical AgentControllerDisplayState snapshot a UI renders from. See display-state methods below.
|
|
53
60
|
|
|
54
|
-
**state** (`
|
|
61
|
+
**state** (`AgentControllerRequestState<TState>`): The schema-validated, session-owned AgentController state. See state methods below.
|
|
55
62
|
|
|
56
63
|
**browser** (`MastraBrowser | undefined`): The browser automation instance for this session. Set at creation via createSession, or from the AgentController config default. Undefined when no browser is configured.
|
|
57
64
|
|
|
58
65
|
## Methods
|
|
59
66
|
|
|
67
|
+
### Identity and events
|
|
68
|
+
|
|
69
|
+
#### `getTags()`
|
|
70
|
+
|
|
71
|
+
Return a copy of the tags supplied when the session was created.
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
const tags = session.getTags()
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Returns: `Record<string, string>`
|
|
78
|
+
|
|
79
|
+
#### `subscribe(listener)`
|
|
80
|
+
|
|
81
|
+
Subscribe to this session's isolated event bus. The method returns an unsubscribe function.
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
const unsubscribe = session.subscribe(event => {
|
|
85
|
+
console.log(event.type)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
unsubscribe()
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Returns: `() => void`
|
|
92
|
+
|
|
93
|
+
### Messages and run control
|
|
94
|
+
|
|
95
|
+
#### `sendMessage({ content, files?, requestContext? })`
|
|
96
|
+
|
|
97
|
+
Send a user message. The session creates a thread first when no thread is active.
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
await session.sendMessage({
|
|
101
|
+
content: 'Summarize this file.',
|
|
102
|
+
files: [{ data: fileContents, mediaType: 'text/plain', filename: 'notes.txt' }],
|
|
103
|
+
})
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### `steer({ content, requestContext? })`
|
|
107
|
+
|
|
108
|
+
Queue steering content into an active run.
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
await session.steer({ content: 'Focus on the failing tests.' })
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### `followUp({ content, requestContext? })`
|
|
115
|
+
|
|
116
|
+
Queue a follow-up while a run is active, or send it immediately while idle.
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
await session.followUp({ content: 'Then propose a fix.' })
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### `getCurrentRunId()`
|
|
123
|
+
|
|
124
|
+
Return the active stream run identifier, the tracked run identifier, or `null` while idle.
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
const runId = session.getCurrentRunId()
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Returns: `string | null`
|
|
131
|
+
|
|
132
|
+
#### `abort()`
|
|
133
|
+
|
|
134
|
+
Abort the active run and clear pending suspension display state.
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
session.abort()
|
|
138
|
+
```
|
|
139
|
+
|
|
60
140
|
### Workspace
|
|
61
141
|
|
|
62
142
|
#### `getWorkspace()`
|
|
@@ -64,13 +144,13 @@ The session is organized into sub-objects, each owning one domain of per-convers
|
|
|
64
144
|
Return the workspace resolved for this session. This preserves session-level overrides and workspaces selected from the session scope.
|
|
65
145
|
|
|
66
146
|
```typescript
|
|
67
|
-
const workspace =
|
|
147
|
+
const workspace = session.getWorkspace()
|
|
68
148
|
const skill = await workspace.skills?.get('code-review')
|
|
69
149
|
```
|
|
70
150
|
|
|
71
151
|
Returns: `Workspace`
|
|
72
152
|
|
|
73
|
-
###
|
|
153
|
+
### Session grants
|
|
74
154
|
|
|
75
155
|
Session-scoped grants auto-approve tools without prompting. Grants are ephemeral: they reset when the session restarts and are never persisted.
|
|
76
156
|
|
|
@@ -79,7 +159,7 @@ Session-scoped grants auto-approve tools without prompting. Grants are ephemeral
|
|
|
79
159
|
Grant a tool category for the current session. Tools in this category are auto-approved.
|
|
80
160
|
|
|
81
161
|
```typescript
|
|
82
|
-
|
|
162
|
+
session.grantCategory('edit')
|
|
83
163
|
```
|
|
84
164
|
|
|
85
165
|
#### `grantTool(toolName)`
|
|
@@ -87,7 +167,7 @@ agentController.session.grantCategory('edit')
|
|
|
87
167
|
Grant a specific tool for the current session.
|
|
88
168
|
|
|
89
169
|
```typescript
|
|
90
|
-
|
|
170
|
+
session.grantTool('mastra_workspace_execute_command')
|
|
91
171
|
```
|
|
92
172
|
|
|
93
173
|
#### `getGrants()`
|
|
@@ -95,40 +175,65 @@ agentController.session.grantTool('mastra_workspace_execute_command')
|
|
|
95
175
|
Return the currently granted categories and tools.
|
|
96
176
|
|
|
97
177
|
```typescript
|
|
98
|
-
const grants =
|
|
178
|
+
const grants = session.getGrants()
|
|
99
179
|
// { categories: string[], tools: string[] }
|
|
100
180
|
```
|
|
101
181
|
|
|
182
|
+
#### `hasCategoryGrant(category)`
|
|
183
|
+
|
|
184
|
+
Return whether a category has an in-memory session grant.
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
const allowed = session.hasCategoryGrant('edit')
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Returns: `boolean`
|
|
191
|
+
|
|
192
|
+
#### `hasToolGrant(toolName)`
|
|
193
|
+
|
|
194
|
+
Return whether a tool has an in-memory session grant.
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
const allowed = session.hasToolGrant('write_file')
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Returns: `boolean`
|
|
201
|
+
|
|
102
202
|
### Tool approvals
|
|
103
203
|
|
|
104
|
-
#### `
|
|
204
|
+
#### `resolveToolApproval(toolName)`
|
|
105
205
|
|
|
106
|
-
|
|
206
|
+
Return the effective policy after applying explicit tool rules, session grants, and category rules.
|
|
107
207
|
|
|
108
208
|
```typescript
|
|
109
|
-
|
|
110
|
-
agentController.session.respondToToolApproval({ decision: 'decline' })
|
|
111
|
-
agentController.session.respondToToolApproval({ decision: 'always_allow_category' })
|
|
209
|
+
const policy = session.resolveToolApproval('execute_command')
|
|
112
210
|
```
|
|
113
211
|
|
|
114
|
-
|
|
212
|
+
Returns: `PermissionPolicy`
|
|
115
213
|
|
|
116
|
-
#### `
|
|
214
|
+
#### `respondToToolApproval({ decision, toolCallId?, requestContext?, declineContext? })`
|
|
117
215
|
|
|
118
|
-
|
|
216
|
+
Respond to a pending tool approval request, raised by a `tool_approval_required` event. Pass `always_allow_category` to also grant the tool's whole category for the rest of the session.
|
|
119
217
|
|
|
120
218
|
```typescript
|
|
121
|
-
|
|
219
|
+
session.respondToToolApproval({ decision: 'approve' })
|
|
220
|
+
session.respondToToolApproval({ decision: 'decline' })
|
|
221
|
+
session.respondToToolApproval({ decision: 'always_allow_category' })
|
|
122
222
|
```
|
|
123
223
|
|
|
124
|
-
#### `
|
|
224
|
+
#### `respondToToolSuspension({ resumeData, toolCallId?, requestContext? })`
|
|
125
225
|
|
|
126
|
-
|
|
226
|
+
Resume a suspended tool with application-provided data. Supply `toolCallId` when several tool calls are suspended.
|
|
127
227
|
|
|
128
228
|
```typescript
|
|
129
|
-
|
|
229
|
+
await session.respondToToolSuspension({
|
|
230
|
+
toolCallId: event.toolCallId,
|
|
231
|
+
resumeData: ['src'],
|
|
232
|
+
})
|
|
130
233
|
```
|
|
131
234
|
|
|
235
|
+
For `submit_plan`, pass `{ action: 'approved' }` or `{ action: 'rejected', feedback }`. Approval can switch to the mode configured by `transitionsTo` before the tool resumes.
|
|
236
|
+
|
|
132
237
|
### Token usage
|
|
133
238
|
|
|
134
239
|
#### `getTokenUsage()`
|
|
@@ -136,7 +241,7 @@ agentController.session.abortRun()
|
|
|
136
241
|
Return a copy of the running token-usage tally for the active thread.
|
|
137
242
|
|
|
138
243
|
```typescript
|
|
139
|
-
const usage =
|
|
244
|
+
const usage = session.getTokenUsage()
|
|
140
245
|
// { promptTokens, completionTokens, totalTokens, ... }
|
|
141
246
|
```
|
|
142
247
|
|
|
@@ -149,7 +254,7 @@ const usage = agentController.session.getTokenUsage()
|
|
|
149
254
|
Return the stable session identifier.
|
|
150
255
|
|
|
151
256
|
```typescript
|
|
152
|
-
const sessionId =
|
|
257
|
+
const sessionId = session.identity.getId()
|
|
153
258
|
```
|
|
154
259
|
|
|
155
260
|
### `session.identity.getOwnerId()`
|
|
@@ -157,7 +262,7 @@ const sessionId = agentController.session.identity.getId()
|
|
|
157
262
|
Return the stable owner identifier for the session.
|
|
158
263
|
|
|
159
264
|
```typescript
|
|
160
|
-
const ownerId =
|
|
265
|
+
const ownerId = session.identity.getOwnerId()
|
|
161
266
|
```
|
|
162
267
|
|
|
163
268
|
### `session.identity.getResourceId()`
|
|
@@ -165,7 +270,7 @@ const ownerId = agentController.session.identity.getOwnerId()
|
|
|
165
270
|
Return the current resource ID.
|
|
166
271
|
|
|
167
272
|
```typescript
|
|
168
|
-
const resourceId =
|
|
273
|
+
const resourceId = session.identity.getResourceId()
|
|
169
274
|
```
|
|
170
275
|
|
|
171
276
|
### `session.identity.getDefaultResourceId()`
|
|
@@ -173,21 +278,71 @@ const resourceId = agentController.session.identity.getResourceId()
|
|
|
173
278
|
Return the resource ID the session was created with.
|
|
174
279
|
|
|
175
280
|
```typescript
|
|
176
|
-
const defaultResourceId =
|
|
281
|
+
const defaultResourceId = session.identity.getDefaultResourceId()
|
|
177
282
|
```
|
|
178
283
|
|
|
179
|
-
To change the resource ID, use [`
|
|
284
|
+
To change the resource ID, use [`controller.setResourceId()`](https://mastra.ai/reference/agent-controller/agent-controller-class), which also clears the active thread. The session `id` and `ownerId` aren't affected by resource switches.
|
|
180
285
|
|
|
181
286
|
## Thread
|
|
182
287
|
|
|
183
|
-
`session.thread` owns the active thread binding
|
|
288
|
+
`session.thread` owns the active thread binding and resource-scoped thread operations. Stored threads and messages can survive controller recreation when storage is configured. The live session and its event bus don't.
|
|
289
|
+
|
|
290
|
+
### `session.thread.create({ title?, id? })`
|
|
291
|
+
|
|
292
|
+
Create a thread, bind the session to it, and open its event stream.
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
const thread = await session.thread.create({
|
|
296
|
+
id: 'thread-7',
|
|
297
|
+
title: 'Investigate login failure',
|
|
298
|
+
})
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
Returns: `Promise<AgentControllerThread>`
|
|
302
|
+
|
|
303
|
+
### `session.thread.rename({ title })`
|
|
304
|
+
|
|
305
|
+
Rename the active stored thread.
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
await session.thread.rename({ title: 'Fix login failure' })
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### `session.thread.clone({ sourceThreadId?, title?, resourceId? })`
|
|
312
|
+
|
|
313
|
+
Clone an owned thread and its messages, then bind the session to the clone.
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
const clone = await session.thread.clone({
|
|
317
|
+
sourceThreadId: 'thread-7',
|
|
318
|
+
title: 'Alternative approach',
|
|
319
|
+
})
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Returns: `Promise<AgentControllerThread>`
|
|
323
|
+
|
|
324
|
+
### `session.thread.switch({ threadId, emitEvent? })`
|
|
325
|
+
|
|
326
|
+
Switch to an owned stored thread and hydrate its mode, model, and observational memory settings.
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
await session.thread.switch({ threadId: 'thread-8' })
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### `session.thread.delete({ threadId })`
|
|
333
|
+
|
|
334
|
+
Delete an owned thread. Deleting the active thread also clears the current binding.
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
await session.thread.delete({ threadId: 'thread-8' })
|
|
338
|
+
```
|
|
184
339
|
|
|
185
340
|
### `session.thread.getId()`
|
|
186
341
|
|
|
187
342
|
Return the active thread ID, or `null` when no thread is bound.
|
|
188
343
|
|
|
189
344
|
```typescript
|
|
190
|
-
const threadId =
|
|
345
|
+
const threadId = session.thread.getId()
|
|
191
346
|
```
|
|
192
347
|
|
|
193
348
|
### `session.thread.list(options?)`
|
|
@@ -195,9 +350,9 @@ const threadId = agentController.session.thread.getId()
|
|
|
195
350
|
List threads from storage. By default only threads for the current resource are returned, and transient forked subagent threads are hidden.
|
|
196
351
|
|
|
197
352
|
```typescript
|
|
198
|
-
const threads = await
|
|
199
|
-
const allThreads = await
|
|
200
|
-
const everything = await
|
|
353
|
+
const threads = await session.thread.list()
|
|
354
|
+
const allThreads = await session.thread.list({ allResources: true })
|
|
355
|
+
const everything = await session.thread.list({ includeForkedSubagents: true })
|
|
201
356
|
```
|
|
202
357
|
|
|
203
358
|
### `session.thread.getById({ threadId })`
|
|
@@ -205,7 +360,7 @@ const everything = await agentController.session.thread.list({ includeForkedSuba
|
|
|
205
360
|
Return a single thread by ID, or `null` if it doesn't exist.
|
|
206
361
|
|
|
207
362
|
```typescript
|
|
208
|
-
const thread = await
|
|
363
|
+
const thread = await session.thread.getById({ threadId: 'thread-abc123' })
|
|
209
364
|
```
|
|
210
365
|
|
|
211
366
|
### `session.thread.listActiveMessages(options?)`
|
|
@@ -213,7 +368,7 @@ const thread = await agentController.session.thread.getById({ threadId: 'thread-
|
|
|
213
368
|
Retrieve messages for the active thread. Returns an empty array when no thread is bound.
|
|
214
369
|
|
|
215
370
|
```typescript
|
|
216
|
-
const messages = await
|
|
371
|
+
const messages = await session.thread.listActiveMessages({ limit: 50 })
|
|
217
372
|
```
|
|
218
373
|
|
|
219
374
|
### `session.thread.listMessages({ threadId, limit? })`
|
|
@@ -221,7 +376,7 @@ const messages = await agentController.session.thread.listActiveMessages({ limit
|
|
|
221
376
|
Retrieve messages for a specific thread.
|
|
222
377
|
|
|
223
378
|
```typescript
|
|
224
|
-
const messages = await
|
|
379
|
+
const messages = await session.thread.listMessages({ threadId: 'thread-abc123' })
|
|
225
380
|
```
|
|
226
381
|
|
|
227
382
|
The message-reading methods `listActiveMessages`, `listMessages`, and `firstUserMessage` return `MastraDBMessage` objects, while `firstUserMessages` returns a `Map<string, MastraDBMessage>` keyed by thread ID. Each message has a `role`, an `id`, a `createdAt`, and a `content` object with `content.format` and a `content.parts` array. Read text, reasoning, tool calls, and attachments from `content.parts`. Signals such as system reminders and notifications are returned as separate messages with `role: 'signal'`.
|
|
@@ -231,7 +386,7 @@ The message-reading methods `listActiveMessages`, `listMessages`, and `firstUser
|
|
|
231
386
|
Retrieve the first user message for a thread, or `null` if none.
|
|
232
387
|
|
|
233
388
|
```typescript
|
|
234
|
-
const firstMsg = await
|
|
389
|
+
const firstMsg = await session.thread.firstUserMessage({
|
|
235
390
|
threadId: 'thread-abc123',
|
|
236
391
|
})
|
|
237
392
|
```
|
|
@@ -241,19 +396,33 @@ const firstMsg = await agentController.session.thread.firstUserMessage({
|
|
|
241
396
|
Retrieve the first user message for many threads at once, returned as a map.
|
|
242
397
|
|
|
243
398
|
```typescript
|
|
244
|
-
const firstByThread = await
|
|
399
|
+
const firstByThread = await session.thread.firstUserMessages({
|
|
245
400
|
threadIds: ['thread-a', 'thread-b'],
|
|
246
401
|
})
|
|
247
402
|
```
|
|
248
403
|
|
|
249
|
-
### `session.thread.getSetting({ key })`
|
|
404
|
+
### `session.thread.getSetting({ key })`
|
|
250
405
|
|
|
251
|
-
Read
|
|
406
|
+
Read a setting from the active thread metadata.
|
|
252
407
|
|
|
253
408
|
```typescript
|
|
254
|
-
await
|
|
255
|
-
|
|
256
|
-
|
|
409
|
+
const value = await session.thread.getSetting({ key: 'omThreshold' })
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### `session.thread.setSetting({ key, value })`
|
|
413
|
+
|
|
414
|
+
Write a setting to the active thread metadata.
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
await session.thread.setSetting({ key: 'omThreshold', value: 0.8 })
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### `session.thread.deleteSetting({ key })`
|
|
421
|
+
|
|
422
|
+
Remove a setting from the active thread metadata.
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
await session.thread.deleteSetting({ key: 'omThreshold' })
|
|
257
426
|
```
|
|
258
427
|
|
|
259
428
|
## Mode
|
|
@@ -265,23 +434,23 @@ await agentController.session.thread.deleteSetting({ key: 'omThreshold' })
|
|
|
265
434
|
Return the active mode ID.
|
|
266
435
|
|
|
267
436
|
```typescript
|
|
268
|
-
const modeId =
|
|
437
|
+
const modeId = session.mode.get()
|
|
269
438
|
```
|
|
270
439
|
|
|
271
440
|
### `session.mode.resolve()`
|
|
272
441
|
|
|
273
|
-
Return the full `AgentControllerMode` object for the active mode, resolved against the
|
|
442
|
+
Return the full `AgentControllerMode` object for the active mode, resolved against the controller's configured modes.
|
|
274
443
|
|
|
275
444
|
```typescript
|
|
276
|
-
const mode =
|
|
445
|
+
const mode = session.mode.resolve()
|
|
277
446
|
```
|
|
278
447
|
|
|
279
448
|
### `session.mode.switch({ modeId })`
|
|
280
449
|
|
|
281
|
-
Switch to
|
|
450
|
+
Switch to another mode. The session saves the outgoing mode's model before persisting the new mode on the active thread. It then restores the incoming mode's selected or default model. The session emits `mode_changed` immediately and `model_changed` after model resolution.
|
|
282
451
|
|
|
283
452
|
```typescript
|
|
284
|
-
await
|
|
453
|
+
await session.mode.switch({ modeId: 'build' })
|
|
285
454
|
```
|
|
286
455
|
|
|
287
456
|
## Model
|
|
@@ -293,15 +462,15 @@ await agentController.session.mode.switch({ modeId: 'build' })
|
|
|
293
462
|
Return the active model ID.
|
|
294
463
|
|
|
295
464
|
```typescript
|
|
296
|
-
const modelId =
|
|
465
|
+
const modelId = session.model.get()
|
|
297
466
|
```
|
|
298
467
|
|
|
299
468
|
### `session.model.displayName()`
|
|
300
469
|
|
|
301
|
-
Return
|
|
470
|
+
Return the last segment of the active model ID as a short display name. Returns `'unknown'` when no model is selected.
|
|
302
471
|
|
|
303
472
|
```typescript
|
|
304
|
-
const name =
|
|
473
|
+
const name = session.model.displayName()
|
|
305
474
|
```
|
|
306
475
|
|
|
307
476
|
### `session.model.hasSelection()`
|
|
@@ -309,37 +478,37 @@ const name = agentController.session.model.displayName()
|
|
|
309
478
|
Check whether a model is currently selected.
|
|
310
479
|
|
|
311
480
|
```typescript
|
|
312
|
-
if (
|
|
481
|
+
if (session.model.hasSelection()) {
|
|
313
482
|
// Ready to send messages
|
|
314
483
|
}
|
|
315
484
|
```
|
|
316
485
|
|
|
317
486
|
### `session.model.switch({ modelId, scope?, modeId? })`
|
|
318
487
|
|
|
319
|
-
Switch the active model. When `scope` is `'thread'` (the default), the model ID is persisted as the per-mode model so it's restored when switching back. Reports the selection to the
|
|
488
|
+
Switch the active model. When `scope` is `'thread'` (the default), the model ID is persisted as the per-mode model so it's restored when switching back. Reports the selection to the controller's `modelUseCountTracker` and emits a `model_changed` event.
|
|
320
489
|
|
|
321
490
|
```typescript
|
|
322
491
|
// Set for the current session only
|
|
323
|
-
await
|
|
492
|
+
await session.model.switch({
|
|
324
493
|
modelId: 'anthropic/claude-sonnet-4-6',
|
|
325
494
|
scope: 'global',
|
|
326
495
|
})
|
|
327
496
|
|
|
328
497
|
// Persist to the current thread (default)
|
|
329
|
-
await
|
|
498
|
+
await session.model.switch({ modelId: 'anthropic/claude-sonnet-4-6' })
|
|
330
499
|
```
|
|
331
500
|
|
|
332
501
|
## Observational Memory
|
|
333
502
|
|
|
334
|
-
The observational-memory model selection, grouped by role under `session.om.observer` and `session.om.reflector`. Both roles expose the same methods. Reads return the value from session state when set, falling back to the
|
|
503
|
+
The observational-memory model selection, grouped by role under `session.om.observer` and `session.om.reflector`. Both roles expose the same methods. Reads return the value from session state when set, falling back to the controller's `omConfig` defaults.
|
|
335
504
|
|
|
336
505
|
### `session.om.observer.modelId()` / `session.om.reflector.modelId()`
|
|
337
506
|
|
|
338
507
|
Return the role's model ID, or `undefined` when neither session state nor `omConfig` provides one.
|
|
339
508
|
|
|
340
509
|
```typescript
|
|
341
|
-
const observer =
|
|
342
|
-
const reflector =
|
|
510
|
+
const observer = session.om.observer.modelId()
|
|
511
|
+
const reflector = session.om.reflector.modelId()
|
|
343
512
|
```
|
|
344
513
|
|
|
345
514
|
### `session.om.observer.threshold()` / `session.om.reflector.threshold()`
|
|
@@ -347,8 +516,8 @@ const reflector = agentController.session.om.reflector.modelId()
|
|
|
347
516
|
Return the role's threshold in tokens (observation threshold for the observer, reflection threshold for the reflector), or `undefined` when unset.
|
|
348
517
|
|
|
349
518
|
```typescript
|
|
350
|
-
const observationThreshold =
|
|
351
|
-
const reflectionThreshold =
|
|
519
|
+
const observationThreshold = session.om.observer.threshold()
|
|
520
|
+
const reflectionThreshold = session.om.reflector.threshold()
|
|
352
521
|
```
|
|
353
522
|
|
|
354
523
|
### `session.om.observer.switchModel({ modelId })` / `session.om.reflector.switchModel({ modelId })`
|
|
@@ -356,32 +525,33 @@ const reflectionThreshold = agentController.session.om.reflector.threshold()
|
|
|
356
525
|
Switch the role's model. Persists the setting to thread metadata and emits an `om_model_changed` event.
|
|
357
526
|
|
|
358
527
|
```typescript
|
|
359
|
-
await
|
|
528
|
+
await session.om.observer.switchModel({
|
|
360
529
|
modelId: 'anthropic/claude-haiku-4-5',
|
|
361
530
|
})
|
|
362
|
-
await
|
|
531
|
+
await session.om.reflector.switchModel({
|
|
363
532
|
modelId: 'anthropic/claude-haiku-4-5',
|
|
364
533
|
})
|
|
365
534
|
```
|
|
366
535
|
|
|
367
536
|
### `session.om.observer.resolvedModel()` / `session.om.reflector.resolvedModel()`
|
|
368
537
|
|
|
369
|
-
Resolve the role's model ID to a model instance via the
|
|
538
|
+
Resolve the role's model ID to a model instance via the configured model gateways, or `undefined` when no model ID is set or no resolver is configured.
|
|
370
539
|
|
|
371
540
|
```typescript
|
|
372
|
-
const observerModel =
|
|
541
|
+
const observerModel = session.om.observer.resolvedModel()
|
|
542
|
+
const reflectorModel = session.om.reflector.resolvedModel()
|
|
373
543
|
```
|
|
374
544
|
|
|
375
545
|
## Permissions
|
|
376
546
|
|
|
377
|
-
`session.permissions` owns the
|
|
547
|
+
`session.permissions` owns the tool-approval policy represented in `session.state`: the per-category and per-tool rules consulted during approval resolution. These are distinct from the in-memory grants documented under [Session grants](#session-grants). Grants reset with the live session. Permission rules aren't durable unless the host restores the corresponding session state.
|
|
378
548
|
|
|
379
549
|
### `session.permissions.getRules()`
|
|
380
550
|
|
|
381
551
|
Return the current permission rules, or empty rules (`{ categories: {}, tools: {} }`) when none are set.
|
|
382
552
|
|
|
383
553
|
```typescript
|
|
384
|
-
const rules =
|
|
554
|
+
const rules = session.permissions.getRules()
|
|
385
555
|
// { categories: { execute: 'ask' }, tools: { dangerous_tool: 'deny' } }
|
|
386
556
|
```
|
|
387
557
|
|
|
@@ -390,7 +560,7 @@ const rules = agentController.session.permissions.getRules()
|
|
|
390
560
|
Set the approval policy (`'allow' | 'ask' | 'deny'`) for a tool category. Resolves once the change is persisted to session state.
|
|
391
561
|
|
|
392
562
|
```typescript
|
|
393
|
-
await
|
|
563
|
+
await session.permissions.setForCategory({ category: 'execute', policy: 'ask' })
|
|
394
564
|
```
|
|
395
565
|
|
|
396
566
|
### `session.permissions.setForTool({ toolName, policy })`
|
|
@@ -398,7 +568,7 @@ await agentController.session.permissions.setForCategory({ category: 'execute',
|
|
|
398
568
|
Set the approval policy for a specific tool. Per-tool policies take precedence over category policies. Resolves once persisted.
|
|
399
569
|
|
|
400
570
|
```typescript
|
|
401
|
-
await
|
|
571
|
+
await session.permissions.setForTool({ toolName: 'dangerous_tool', policy: 'deny' })
|
|
402
572
|
```
|
|
403
573
|
|
|
404
574
|
## Subagents
|
|
@@ -410,7 +580,7 @@ await agentController.session.permissions.setForTool({ toolName: 'dangerous_tool
|
|
|
410
580
|
Return the subagent model ID, preferring the per-`agentType` value when one is given, then the global subagent model, or `null` when neither is set.
|
|
411
581
|
|
|
412
582
|
```typescript
|
|
413
|
-
const modelId =
|
|
583
|
+
const modelId = session.subagents.model.get({ agentType: 'explore' })
|
|
414
584
|
```
|
|
415
585
|
|
|
416
586
|
### `session.subagents.model.set({ modelId, agentType? })`
|
|
@@ -419,10 +589,10 @@ Set the subagent model ID. Pass an `agentType` to set a per-type override, or om
|
|
|
419
589
|
|
|
420
590
|
```typescript
|
|
421
591
|
// Set the global subagent model
|
|
422
|
-
await
|
|
592
|
+
await session.subagents.model.set({ modelId: 'anthropic/claude-sonnet-4-6' })
|
|
423
593
|
|
|
424
594
|
// Set a per-type override
|
|
425
|
-
await
|
|
595
|
+
await session.subagents.model.set({
|
|
426
596
|
modelId: 'anthropic/claude-haiku-4-5',
|
|
427
597
|
agentType: 'explore',
|
|
428
598
|
})
|
|
@@ -437,8 +607,8 @@ await agentController.session.subagents.model.set({
|
|
|
437
607
|
Return the stored run ID and trace ID for the current run, or `null` when idle.
|
|
438
608
|
|
|
439
609
|
```typescript
|
|
440
|
-
const runId =
|
|
441
|
-
const traceId =
|
|
610
|
+
const runId = session.run.getRunId()
|
|
611
|
+
const traceId = session.run.getTraceId()
|
|
442
612
|
```
|
|
443
613
|
|
|
444
614
|
### `session.run.isRunning()`
|
|
@@ -446,7 +616,7 @@ const traceId = agentController.session.run.getTraceId()
|
|
|
446
616
|
Return whether a run is currently in progress.
|
|
447
617
|
|
|
448
618
|
```typescript
|
|
449
|
-
if (
|
|
619
|
+
if (session.run.isRunning()) {
|
|
450
620
|
// A run is active
|
|
451
621
|
}
|
|
452
622
|
```
|
|
@@ -460,7 +630,7 @@ if (agentController.session.run.isRunning()) {
|
|
|
460
630
|
Return the run ID active on the live stream, or `null` when no stream is open.
|
|
461
631
|
|
|
462
632
|
```typescript
|
|
463
|
-
const runId =
|
|
633
|
+
const runId = session.stream.activeRunId()
|
|
464
634
|
```
|
|
465
635
|
|
|
466
636
|
### `session.stream.isActive()`
|
|
@@ -468,7 +638,7 @@ const runId = agentController.session.stream.activeRunId()
|
|
|
468
638
|
Return whether the stream currently has an active run.
|
|
469
639
|
|
|
470
640
|
```typescript
|
|
471
|
-
if (
|
|
641
|
+
if (session.stream.isActive()) {
|
|
472
642
|
// The current thread's stream is producing output
|
|
473
643
|
}
|
|
474
644
|
```
|
|
@@ -482,7 +652,7 @@ if (agentController.session.stream.isActive()) {
|
|
|
482
652
|
Return whether any tool is currently suspended.
|
|
483
653
|
|
|
484
654
|
```typescript
|
|
485
|
-
if (
|
|
655
|
+
if (session.suspensions.hasPending()) {
|
|
486
656
|
// At least one interactive tool is waiting for a response
|
|
487
657
|
}
|
|
488
658
|
```
|
|
@@ -492,10 +662,10 @@ if (agentController.session.suspensions.hasPending()) {
|
|
|
492
662
|
Return whether a specific tool call is suspended.
|
|
493
663
|
|
|
494
664
|
```typescript
|
|
495
|
-
const waiting =
|
|
665
|
+
const waiting = session.suspensions.has({ toolCallId: event.toolCallId })
|
|
496
666
|
```
|
|
497
667
|
|
|
498
|
-
Resume a suspended tool with [`
|
|
668
|
+
Resume a suspended tool with [`session.respondToToolSuspension()`](#tool-approvals).
|
|
499
669
|
|
|
500
670
|
## Follow-ups
|
|
501
671
|
|
|
@@ -506,7 +676,7 @@ Resume a suspended tool with [`agentController.respondToToolSuspension()`](https
|
|
|
506
676
|
Return the number of queued follow-ups.
|
|
507
677
|
|
|
508
678
|
```typescript
|
|
509
|
-
const queued =
|
|
679
|
+
const queued = session.followUps.count()
|
|
510
680
|
```
|
|
511
681
|
|
|
512
682
|
### `session.followUps.isEmpty()`
|
|
@@ -514,7 +684,7 @@ const queued = agentController.session.followUps.count()
|
|
|
514
684
|
Return whether the follow-up queue is empty.
|
|
515
685
|
|
|
516
686
|
```typescript
|
|
517
|
-
if (!
|
|
687
|
+
if (!session.followUps.isEmpty()) {
|
|
518
688
|
// Messages are waiting to be processed
|
|
519
689
|
}
|
|
520
690
|
```
|
|
@@ -528,23 +698,23 @@ if (!agentController.session.followUps.isEmpty()) {
|
|
|
528
698
|
Return whether a tool is currently awaiting an approval decision.
|
|
529
699
|
|
|
530
700
|
```typescript
|
|
531
|
-
if (
|
|
701
|
+
if (session.approval.isArmed()) {
|
|
532
702
|
// Show the approval prompt
|
|
533
703
|
}
|
|
534
704
|
```
|
|
535
705
|
|
|
536
|
-
Respond with [`session.respondToToolApproval()`](#
|
|
706
|
+
Respond with [`session.respondToToolApproval()`](#tool-approvals).
|
|
537
707
|
|
|
538
708
|
## Display state
|
|
539
709
|
|
|
540
|
-
`session.displayState` owns the canonical `AgentControllerDisplayState` snapshot a UI renders from, and the reducer that keeps it in sync with every
|
|
710
|
+
`session.displayState` owns the canonical `AgentControllerDisplayState` snapshot a UI renders from, and the reducer that keeps it in sync with every session event.
|
|
541
711
|
|
|
542
712
|
### `session.displayState.get()`
|
|
543
713
|
|
|
544
714
|
Return the current `AgentControllerDisplayState` snapshot for UI rendering.
|
|
545
715
|
|
|
546
716
|
```typescript
|
|
547
|
-
const displayState =
|
|
717
|
+
const displayState = session.displayState.get()
|
|
548
718
|
```
|
|
549
719
|
|
|
550
720
|
### `session.displayState.restoreTasks(tasks)`
|
|
@@ -552,10 +722,10 @@ const displayState = agentController.session.displayState.get()
|
|
|
552
722
|
Restore the task portion of the snapshot after a UI replays persisted task tool history. This is a pure update of the snapshot and doesn't emit an event, so re-render explicitly after calling it.
|
|
553
723
|
|
|
554
724
|
```typescript
|
|
555
|
-
|
|
725
|
+
session.displayState.restoreTasks(replayedTasks)
|
|
556
726
|
```
|
|
557
727
|
|
|
558
|
-
After every event the
|
|
728
|
+
After every event, the session emits `display_state_changed` with the latest snapshot. Subscribe with [`session.subscribe()`](#identity-and-events) or read the current value from `session.displayState.get()`.
|
|
559
729
|
|
|
560
730
|
## State
|
|
561
731
|
|
|
@@ -566,7 +736,7 @@ After every event the agentController emits `display_state_changed`, so high-fre
|
|
|
566
736
|
Return a readonly copy of the current state snapshot.
|
|
567
737
|
|
|
568
738
|
```typescript
|
|
569
|
-
const state =
|
|
739
|
+
const state = session.state.get()
|
|
570
740
|
```
|
|
571
741
|
|
|
572
742
|
### `session.state.set(updates)`
|
|
@@ -574,7 +744,7 @@ const state = agentController.session.state.get()
|
|
|
574
744
|
Merge a partial update into the state. Updates are queued so concurrent calls apply in order, validated against the schema, and emit `state_changed` with the changed keys.
|
|
575
745
|
|
|
576
746
|
```typescript
|
|
577
|
-
await
|
|
747
|
+
await session.state.set({ yolo: true })
|
|
578
748
|
```
|
|
579
749
|
|
|
580
750
|
### `session.state.update(updater)`
|
|
@@ -582,28 +752,21 @@ await agentController.session.state.set({ yolo: true })
|
|
|
582
752
|
Run an updater against the current snapshot and apply its result atomically within the write queue. Use this for read-modify-write changes that must see the latest state. The updater returns `updates` to merge, optional `events` to emit, and a `result` value that `update()` resolves to.
|
|
583
753
|
|
|
584
754
|
```typescript
|
|
585
|
-
const added = await
|
|
755
|
+
const added = await session.state.update(current => ({
|
|
586
756
|
updates: { count: (current.count ?? 0) + 1 },
|
|
587
757
|
result: (current.count ?? 0) + 1,
|
|
588
758
|
}))
|
|
589
759
|
```
|
|
590
760
|
|
|
591
|
-
##
|
|
592
|
-
|
|
593
|
-
Sessions carry scoping tags (e.g. `{ projectPath }`) seeded at creation and stamped onto every thread the session creates. Thread listings can be filtered back to the session's scope using these tags.
|
|
761
|
+
## Persistence boundaries
|
|
594
762
|
|
|
595
|
-
|
|
763
|
+
A `Session` is a live runtime object. Its event bus, arbitrary `session.state`, permission rules, permission grants, pending approvals, suspensions, follow-ups, run state, and stream state don't automatically survive controller or process recreation. The host must restore any of this state when recreating a session.
|
|
596
764
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
```typescript
|
|
600
|
-
const tags = agentController.session.getTags()
|
|
601
|
-
// { projectPath: '/my/project' }
|
|
602
|
-
```
|
|
765
|
+
With configured storage, threads, messages, and token usage persist. Thread settings restore mode and model choices. They can also restore observational memory settings and subagent model selections, including per-agent-type overrides. A chat channel can map back to stored threads, but channel-to-session and auto-approval state held by `AgentControllerChannels` remains in memory.
|
|
603
766
|
|
|
604
767
|
## Related
|
|
605
768
|
|
|
606
769
|
- [AgentController class](https://mastra.ai/reference/agent-controller/agent-controller-class)
|
|
607
|
-
- [AgentController overview](https://mastra.ai/docs/agent-controller
|
|
608
|
-
- [Threads and state](https://mastra.ai/docs/agent-controller
|
|
609
|
-
- [Tool approvals](https://mastra.ai/docs/agent-controller
|
|
770
|
+
- [AgentController overview](https://mastra.ai/docs/harness/agent-controller)
|
|
771
|
+
- [Threads and state](https://mastra.ai/docs/harness/agent-controller)
|
|
772
|
+
- [Tool approvals](https://mastra.ai/docs/harness/agent-controller)
|