@mastra/mcp-docs-server 1.2.2 → 1.2.3-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/{harness → agent-controller}/modes.md +19 -19
- package/.docs/docs/agent-controller/overview.md +128 -0
- package/.docs/docs/agent-controller/session.md +143 -0
- package/.docs/docs/{harness → agent-controller}/subagents.md +12 -12
- package/.docs/docs/agent-controller/threads-and-state.md +141 -0
- package/.docs/docs/{harness → agent-controller}/tool-approvals.md +23 -23
- package/.docs/docs/agents/channels.md +47 -0
- package/.docs/docs/agents/signals.md +25 -1
- package/.docs/models/gateways/vercel.md +3 -1
- package/.docs/models/index.md +1 -1
- package/.docs/models/providers/anthropic.md +4 -5
- package/.docs/models/providers/chutes.md +17 -43
- package/.docs/models/providers/tinfoil.md +77 -0
- package/.docs/models/providers.md +1 -0
- package/.docs/reference/{harness/harness-class.md → agent-controller/agent-controller-class.md} +106 -106
- package/.docs/reference/{harness → agent-controller}/session.md +97 -91
- package/.docs/reference/agents/channels.md +3 -1
- package/.docs/reference/channels/channel-provider.md +65 -0
- package/.docs/reference/channels/slack-provider.md +226 -0
- package/.docs/reference/index.md +5 -2
- package/.docs/reference/pubsub/lease-provider.md +131 -0
- package/.docs/reference/pubsub/redis-streams.md +10 -2
- package/CHANGELOG.md +14 -0
- package/package.json +4 -4
- package/.docs/docs/harness/overview.md +0 -128
- package/.docs/docs/harness/session.md +0 -143
- package/.docs/docs/harness/threads-and-state.md +0 -141
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
# Session
|
|
2
|
-
|
|
3
|
-
A [`Session`](https://mastra.ai/reference/harness/session) holds the live state of a Harness: who the session is for, which thread is active, the selected mode and model, permission grants, queued follow-ups, token usage, application state, and the display snapshot. You reach it through `harness.session`.
|
|
4
|
-
|
|
5
|
-
## What the Session tracks
|
|
6
|
-
|
|
7
|
-
The Session is the live state of a single user's interaction with the Harness. It answers "what is true right now": who the session belongs to, which thread is currently bound, which mode and model are selected, what the user has approved, what's queued or running, the application state, and the snapshot to render. A session has one active thread at a time but can list, switch between, and clone many threads over its lifetime. Anything that describes the current state lives here; the Harness owns the shared infrastructure every session runs on.
|
|
8
|
-
|
|
9
|
-
Because each session has its own identity and state, one Harness can serve many users at once — each backed by its own Session — without one session's mode, grants, or active thread leaking into another.
|
|
10
|
-
|
|
11
|
-
The rest of this page walks through the Session's state. Each part is a focused sub-object on `harness.session`:
|
|
12
|
-
|
|
13
|
-
- **Who and where**: [Identity](#identity) sets the stable session `id`, `ownerId`, and resource the session belongs to, and [Thread](#thread) tracks the currently bound thread.
|
|
14
|
-
- **How the agent behaves**: [Mode and model](#mode-and-model) controls which agent profile and model are active, and [Permission grants](#permission-grants) records what the user has approved to run without prompting.
|
|
15
|
-
- **What's happening right now**: [Run state](#run-state) reflects the in-flight generation, and [Follow-ups](#follow-ups) holds messages queued to send when it finishes.
|
|
16
|
-
- **What you store and render**: [State](#state) holds your application's structured data, and [Display state](#display-state) is the single snapshot your UI renders from.
|
|
17
|
-
|
|
18
|
-
The Harness performs actions that change this state — switching threads, modes, or models — because those operations coordinate shared infrastructure and emit events. The Session is where you read the result. The sections below note this split where it matters.
|
|
19
|
-
|
|
20
|
-
## Identity
|
|
21
|
-
|
|
22
|
-
`session.identity` holds three stable identifiers for the conversation: a session `id`, an `ownerId`, and the resource ID. Threads are scoped to a resource ID, so this is what groups a conversation's threads together:
|
|
23
|
-
|
|
24
|
-
```typescript
|
|
25
|
-
const sessionId = harness.session.identity.getId()
|
|
26
|
-
const ownerId = harness.session.identity.getOwnerId()
|
|
27
|
-
const resourceId = harness.session.identity.getResourceId()
|
|
28
|
-
const threadId = harness.session.thread.getId()
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
The session `id` and `ownerId` are stable for the life of the session — they don't change when the resource ID is switched. They mirror the `id` and `ownerId` fields on `SessionRecord` in storage, so storage layers can key sessions by a stable identifier rather than the mutable resource ID.
|
|
32
|
-
|
|
33
|
-
The resource ID is set when creating a session via [`harness.createSession()`](https://mastra.ai/reference/harness/harness-class) and defaults to the harness `id`. See [Resource IDs](https://mastra.ai/docs/harness/threads-and-state) for how it scopes threads.
|
|
34
|
-
|
|
35
|
-
## Thread
|
|
36
|
-
|
|
37
|
-
`session.thread` owns the active thread binding and read access to threads and messages. The Harness performs lifecycle transitions; the Session reads the result:
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
// Lifecycle transitions live on the Harness
|
|
41
|
-
await harness.switchThread({ threadId: 'thread-abc123' })
|
|
42
|
-
|
|
43
|
-
// Reads live on the Session
|
|
44
|
-
const threads = await harness.session.thread.list()
|
|
45
|
-
const messages = await harness.session.thread.listActiveMessages()
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
See [Threads and state](https://mastra.ai/docs/harness/threads-and-state) for the full lifecycle.
|
|
49
|
-
|
|
50
|
-
## Mode and model
|
|
51
|
-
|
|
52
|
-
The Harness defines the available modes in `config.modes`. The Session tracks which mode and model are _currently_ selected:
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
// Switch mode (aborts the run, emits events)
|
|
56
|
-
await harness.session.mode.switch({ modeId: 'build' })
|
|
57
|
-
|
|
58
|
-
// Read the current selection (Session state)
|
|
59
|
-
const modeId = harness.session.mode.get()
|
|
60
|
-
const mode = harness.session.mode.resolve()
|
|
61
|
-
const modelId = harness.session.model.get()
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
See [Modes](https://mastra.ai/docs/harness/modes) for how modes carry their own model.
|
|
65
|
-
|
|
66
|
-
## Permission grants
|
|
67
|
-
|
|
68
|
-
The Harness owns permission _policy_ — which categories or tools require approval. The Session owns the _grants_ a user makes during the conversation. A grant lets a tool run for the rest of the session without prompting again:
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
// Grant a category or tool for the rest of the session
|
|
72
|
-
harness.session.grantCategory('edit')
|
|
73
|
-
harness.session.grantTool('mastra_workspace_execute_command')
|
|
74
|
-
|
|
75
|
-
// Inspect current grants
|
|
76
|
-
const grants = harness.session.getGrants()
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
Grants are intentionally in-memory and reset when the session restarts. See [Tool approvals](https://mastra.ai/docs/harness/tool-approvals) for the approval flow.
|
|
80
|
-
|
|
81
|
-
## Run state
|
|
82
|
-
|
|
83
|
-
`session.run` tracks the in-flight generation: whether a run is active, its run and trace IDs, and the abort signal. Use it to reflect run status in your UI:
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
if (harness.session.run.isRunning()) {
|
|
87
|
-
// show a stop button
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Abort the active run (Harness orchestration clears related state)
|
|
91
|
-
harness.abort()
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## Follow-ups
|
|
95
|
-
|
|
96
|
-
A user may want to add to the conversation while the agent is still working. Instead of dropping or interrupting those messages, the Session queues them on `session.followUps` and sends them when the current run finishes:
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
const queued = harness.session.followUps.count()
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Queue a follow-up with `harness.followUp({ content })`. To redirect the agent mid-run instead of waiting, use `harness.steer({ content })`. Both build on [signals](https://mastra.ai/docs/agents/signals).
|
|
103
|
-
|
|
104
|
-
## State
|
|
105
|
-
|
|
106
|
-
`session.state` holds the conversation's application state — structured values that agents and the UI share, such as model preferences, feature flags, or progress. The Harness defines the shape with a `stateSchema`; the Session owns the live snapshot, validates updates against the schema, and emits `state_changed` on every write:
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
const state = harness.session.state.get()
|
|
110
|
-
await harness.session.state.set({ theme: 'light' })
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
See [Threads and state](https://mastra.ai/docs/harness/threads-and-state) for defining a schema.
|
|
114
|
-
|
|
115
|
-
## Display state
|
|
116
|
-
|
|
117
|
-
A conversation emits many fine-grained events: tokens streaming in, tools starting and finishing, approvals pending, tasks updating, token usage climbing. Subscribing to each event type and reassembling the current picture yourself is tedious and error-prone. `session.displayState` does that work for you.
|
|
118
|
-
|
|
119
|
-
It's a reducer-maintained snapshot. The Session keeps one `HarnessDisplayState` object and folds every harness event into it as it happens, so the snapshot always reflects the latest state. It captures everything a UI needs to render: whether the agent is running and what it's streaming, which tools and subagents are active, anything waiting on the user such as approvals, the current task list, and running totals like token usage and queued follow-ups.
|
|
120
|
-
|
|
121
|
-
Because it's a single object, you can drive an entire UI from one place: read the current snapshot with `get()`, and re-render whenever the Harness emits `display_state_changed` (fired after every other event):
|
|
122
|
-
|
|
123
|
-
```typescript
|
|
124
|
-
const snapshot = harness.session.displayState.get()
|
|
125
|
-
|
|
126
|
-
// Re-render from the snapshot on every change
|
|
127
|
-
harness.subscribe(event => {
|
|
128
|
-
if (event.type === 'display_state_changed') {
|
|
129
|
-
render(harness.session.displayState.get())
|
|
130
|
-
}
|
|
131
|
-
})
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
This is the recommended pattern for most UIs. Subscribe to individual typed events only when you need to react to a specific transition rather than re-render the whole view.
|
|
135
|
-
|
|
136
|
-
> **Note:** Visit the [Session reference](https://mastra.ai/reference/harness/session) for the full list of sub-objects and method signatures.
|
|
137
|
-
|
|
138
|
-
## Related
|
|
139
|
-
|
|
140
|
-
- [Harness overview](https://mastra.ai/docs/harness/overview)
|
|
141
|
-
- [Threads and state](https://mastra.ai/docs/harness/threads-and-state)
|
|
142
|
-
- [Tool approvals](https://mastra.ai/docs/harness/tool-approvals)
|
|
143
|
-
- [Session reference](https://mastra.ai/reference/harness/session)
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
# Threads and state
|
|
2
|
-
|
|
3
|
-
Threads and state are how a Harness conversation survives beyond a single exchange. A **thread** is the persistent record of a conversation — its messages and metadata, saved to storage so a user can close the app and resume the same conversation later, or switch between several conversations. **State** is structured data attached to the conversation — values like model preferences, feature flags, or progress — that agents and your UI read and write as the conversation runs.
|
|
4
|
-
|
|
5
|
-
The two work together: the thread is the message history, and state is the shared scratchpad alongside it. Both persist across mode switches, model changes, and restarts, so nothing is lost when a user switches from plan mode to build mode or reopens the app the next day.
|
|
6
|
-
|
|
7
|
-
Thread _lifecycle_ transitions — create, switch, clone, delete — live on the Harness because they coordinate the shared thread lock and emit events. The active thread binding and thread/message _reads_ live on the [`Session`](https://mastra.ai/docs/harness/session) as `harness.session.thread`.
|
|
8
|
-
|
|
9
|
-
## Threads
|
|
10
|
-
|
|
11
|
-
A thread holds one conversation's full message history. The Harness binds the Session to one active thread at a time; messages you send and the agent's replies are appended to that thread and saved to storage. Threads let users resume a past conversation, keep several conversations side by side, or branch one into alternatives.
|
|
12
|
-
|
|
13
|
-
### Creating and selecting threads
|
|
14
|
-
|
|
15
|
-
On startup, call `selectOrCreateThread()` to resume the most recent thread or create a new one:
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
await harness.init()
|
|
19
|
-
const thread = await harness.selectOrCreateThread()
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
Create a thread explicitly with a title:
|
|
23
|
-
|
|
24
|
-
```typescript
|
|
25
|
-
const thread = await harness.createThread({ title: 'New conversation' })
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### Switching threads
|
|
29
|
-
|
|
30
|
-
Switch to an existing thread. The harness aborts any in-progress generation, acquires a lock on the new thread, and emits a `thread_changed` event:
|
|
31
|
-
|
|
32
|
-
```typescript
|
|
33
|
-
await harness.switchThread({ threadId: 'thread-abc123' })
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
### Listing threads
|
|
37
|
-
|
|
38
|
-
List threads for the current resource. Forked subagent threads are hidden by default:
|
|
39
|
-
|
|
40
|
-
```typescript
|
|
41
|
-
const threads = await harness.session.thread.list()
|
|
42
|
-
|
|
43
|
-
// Include all resources
|
|
44
|
-
const allThreads = await harness.session.thread.list({ allResources: true })
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### Cloning threads
|
|
48
|
-
|
|
49
|
-
Clone a thread to create a branch of the conversation. The harness copies all messages and switches to the clone:
|
|
50
|
-
|
|
51
|
-
```typescript
|
|
52
|
-
const cloned = await harness.cloneThread({ title: 'Alternative approach' })
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Thread locking
|
|
56
|
-
|
|
57
|
-
Pass a `threadLock` to the Harness constructor to prevent concurrent access from multiple processes. The lock is acquired before any thread operation and released on switch or delete:
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
const harness = new Harness({
|
|
61
|
-
id: 'my-agent',
|
|
62
|
-
threadLock: {
|
|
63
|
-
acquire: async threadId => {
|
|
64
|
-
/* acquire lock or throw */
|
|
65
|
-
},
|
|
66
|
-
release: async threadId => {
|
|
67
|
-
/* release lock */
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
})
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## State
|
|
74
|
-
|
|
75
|
-
Where a thread stores the conversation's messages, state stores structured values that describe the conversation but aren't messages — model preferences, feature flags, UI settings, or progress markers. Agents can read and update state during a run, and your UI can react to changes, so state is how the agent and the interface stay in sync on shared facts. You define its shape with a schema, and every update is validated against that schema before it's applied.
|
|
76
|
-
|
|
77
|
-
### Defining a state schema
|
|
78
|
-
|
|
79
|
-
Pass a `stateSchema` (Standard JSON Schema) to validate state and extract defaults:
|
|
80
|
-
|
|
81
|
-
```typescript
|
|
82
|
-
import { Agent } from '@mastra/core/agent'
|
|
83
|
-
import { Harness } from '@mastra/core/harness'
|
|
84
|
-
import { z } from 'zod'
|
|
85
|
-
|
|
86
|
-
const agent = new Agent({
|
|
87
|
-
name: 'assistant',
|
|
88
|
-
instructions: 'Help the user manage a stateful session.',
|
|
89
|
-
model: 'openai/gpt-5.5',
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
const harness = new Harness({
|
|
93
|
-
id: 'stateful-agent',
|
|
94
|
-
agent,
|
|
95
|
-
modes: [{ id: 'default', name: 'Default', metadata: { default: true } }],
|
|
96
|
-
stateSchema: z.object({
|
|
97
|
-
currentModelId: z.string().optional(),
|
|
98
|
-
theme: z.enum(['light', 'dark']).default('dark'),
|
|
99
|
-
}),
|
|
100
|
-
})
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Reading and writing state
|
|
104
|
-
|
|
105
|
-
State is owned by the [`Session`](https://mastra.ai/docs/harness/session) as `harness.session.state`:
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
// Read the current state snapshot
|
|
109
|
-
const state = harness.session.state.get()
|
|
110
|
-
|
|
111
|
-
// Update state — validates against schema and emits state_changed
|
|
112
|
-
await harness.session.state.set({ theme: 'light' })
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
State changes emit a `state_changed` event with the new state and the set of changed keys.
|
|
116
|
-
|
|
117
|
-
## Resource IDs
|
|
118
|
-
|
|
119
|
-
Threads are scoped to a resource ID, which groups a conversation's threads by project, user, or workspace. Set it on the Harness constructor; it defaults to the harness `id` when omitted:
|
|
120
|
-
|
|
121
|
-
```typescript
|
|
122
|
-
const harness = new Harness({
|
|
123
|
-
id: 'my-agent',
|
|
124
|
-
resourceId: 'project-xyz',
|
|
125
|
-
})
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
The resource ID is part of a conversation's identity, so you read it from the Session:
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
const resourceId = harness.session.identity.getResourceId()
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
The session also has a stable `id` and `ownerId` (read with `session.identity.getId()` and `session.identity.getOwnerId()`). Unlike the resource ID, these don't change when you switch resources — see [Session identity](https://mastra.ai/docs/harness/session) for details.
|
|
135
|
-
|
|
136
|
-
## Related
|
|
137
|
-
|
|
138
|
-
- [Harness overview](https://mastra.ai/docs/harness/overview)
|
|
139
|
-
- [Session](https://mastra.ai/docs/harness/session)
|
|
140
|
-
- [Modes](https://mastra.ai/docs/harness/modes)
|
|
141
|
-
- [API reference](https://mastra.ai/reference/harness/harness-class)
|