@mastra/mcp-docs-server 1.1.35-alpha.21 → 1.1.35-alpha.26
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/processors.md +1 -1
- package/.docs/docs/agents/signals.md +151 -0
- package/.docs/docs/browser/agent-browser.md +15 -0
- package/.docs/docs/browser/stagehand.md +25 -1
- package/.docs/docs/voice/overview.md +84 -0
- package/.docs/models/index.md +1 -1
- package/.docs/models/providers/chutes.md +23 -54
- package/.docs/models/providers/databricks.md +96 -0
- package/.docs/models/providers/novita-ai.md +5 -5
- package/.docs/models/providers/nvidia.md +59 -49
- package/.docs/models/providers/ollama-cloud.md +1 -1
- package/.docs/models/providers/opencode.md +43 -42
- package/.docs/models/providers/sarvam.md +72 -0
- package/.docs/models/providers.md +2 -0
- package/.docs/reference/agents/agent.md +83 -0
- package/.docs/reference/browser/agent-browser.md +37 -11
- package/.docs/reference/browser/stagehand-browser.md +35 -9
- package/.docs/reference/client-js/agents.md +89 -0
- package/.docs/reference/index.md +3 -0
- package/.docs/reference/processors/prefill-error-handler.md +3 -3
- package/.docs/reference/storage/dsql.md +428 -0
- package/.docs/reference/tools/brightdata.md +167 -0
- package/.docs/reference/voice/inworld.md +133 -0
- package/CHANGELOG.md +21 -0
- package/package.json +5 -5
|
@@ -61,18 +61,29 @@ Use stagehand_extract to get data from pages.`,
|
|
|
61
61
|
|
|
62
62
|
**screencast** (`ScreencastOptions`): Configuration for streaming browser frames to Studio.
|
|
63
63
|
|
|
64
|
+
**excludeTools** (`StagehandToolName[]`): Tool names to exclude from the browser toolset. Use this to disable specific tools for models that do not support certain capabilities, such as vision.
|
|
65
|
+
|
|
64
66
|
## Tools
|
|
65
67
|
|
|
66
|
-
`StagehandBrowser` provides
|
|
68
|
+
`StagehandBrowser` provides 7 AI-powered tools for browser automation:
|
|
69
|
+
|
|
70
|
+
| Tool | Description |
|
|
71
|
+
| ---------------------- | ------------------------------------------------------------------------------------- |
|
|
72
|
+
| `stagehand_act` | Perform actions using natural language instructions |
|
|
73
|
+
| `stagehand_extract` | Extract structured data from pages |
|
|
74
|
+
| `stagehand_observe` | Discover actionable elements on a page |
|
|
75
|
+
| `stagehand_navigate` | Navigate to a URL |
|
|
76
|
+
| `stagehand_tabs` | Manage browser tabs |
|
|
77
|
+
| `stagehand_screenshot` | Capture a screenshot as PNG (viewport by default; set `fullPage: true` for full page) |
|
|
78
|
+
| `stagehand_close` | Close the browser |
|
|
67
79
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
| `stagehand_close` | Close the browser |
|
|
80
|
+
To exclude specific tools, pass `excludeTools` in the constructor:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const browser = new StagehandBrowser({
|
|
84
|
+
excludeTools: ['stagehand_screenshot'],
|
|
85
|
+
})
|
|
86
|
+
```
|
|
76
87
|
|
|
77
88
|
## Tool reference
|
|
78
89
|
|
|
@@ -224,6 +235,21 @@ Manage browser tabs.
|
|
|
224
235
|
{ "action": "close", "index": 1 }
|
|
225
236
|
```
|
|
226
237
|
|
|
238
|
+
### `stagehand_screenshot`
|
|
239
|
+
|
|
240
|
+
Capture a screenshot of the current page as PNG (viewport by default; set `fullPage: true` for full-page capture). Returns image content that vision-capable models can interpret directly. Use `stagehand_observe` or `stagehand_extract` when you only need text or structured data.
|
|
241
|
+
|
|
242
|
+
```text
|
|
243
|
+
// Viewport only (default)
|
|
244
|
+
|
|
245
|
+
// Full scrollable page
|
|
246
|
+
{ "fullPage": true }
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
| Parameter | Type | Description |
|
|
250
|
+
| ---------- | --------- | ---------------------------------------------------------------------------------------- |
|
|
251
|
+
| `fullPage` | `boolean` | Capture the full scrollable page instead of just the viewport (optional, default: false) |
|
|
252
|
+
|
|
227
253
|
### `stagehand_close`
|
|
228
254
|
|
|
229
255
|
Close the browser and clean up resources.
|
|
@@ -151,6 +151,95 @@ for await (const part of uiMessageStream) {
|
|
|
151
151
|
}
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
+
### `sendSignal()`
|
|
155
|
+
|
|
156
|
+
Send a signal to an active agent run or memory thread. Use this with `subscribeToThread()` so the client can render the stream that wakes from, or receives, the signal.
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
const agent = mastraClient.getAgent('support-agent')
|
|
160
|
+
|
|
161
|
+
const result = await agent.sendSignal({
|
|
162
|
+
signal: {
|
|
163
|
+
type: 'user-message',
|
|
164
|
+
contents: 'Also consider the customer note I just added.',
|
|
165
|
+
},
|
|
166
|
+
resourceId: 'user-123',
|
|
167
|
+
threadId: 'thread-abc',
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
console.log(result.runId)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Use `ifActive.behavior` and `ifIdle.behavior` to control whether Mastra delivers, persists, discards, or wakes from a signal:
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
await agent.sendSignal({
|
|
177
|
+
signal: { type: 'user-message', contents: 'Store this for later.' },
|
|
178
|
+
resourceId: 'user-123',
|
|
179
|
+
threadId: 'thread-abc',
|
|
180
|
+
ifIdle: {
|
|
181
|
+
behavior: 'persist',
|
|
182
|
+
},
|
|
183
|
+
})
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Pass `ifIdle.streamOptions` when the idle wake-up stream needs options such as model settings, tools, or runtime context:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
await agent.sendSignal({
|
|
190
|
+
signal: { type: 'user-message', contents: 'Start from this signal.' },
|
|
191
|
+
resourceId: 'user-123',
|
|
192
|
+
threadId: 'thread-abc',
|
|
193
|
+
ifIdle: {
|
|
194
|
+
behavior: 'wake',
|
|
195
|
+
streamOptions: {
|
|
196
|
+
maxSteps: 3,
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
})
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Returns `{ accepted: true, runId: string }`.
|
|
203
|
+
|
|
204
|
+
**signal** (`{ type: 'user-message'; contents: MessageListInput } | { type: string; contents: string }`): \`user-message\` signals are treated as user input. Other signal types are converted to contextual XML before the next model call.
|
|
205
|
+
|
|
206
|
+
**runId** (`string`): Run ID to target directly.
|
|
207
|
+
|
|
208
|
+
**resourceId** (`string`): Resource ID for the memory thread. Use with \`threadId\` for thread-targeted signals.
|
|
209
|
+
|
|
210
|
+
**threadId** (`string`): Thread ID to target. Use with \`resourceId\` for thread-targeted signals.
|
|
211
|
+
|
|
212
|
+
**ifActive.behavior** (`'deliver' | 'persist' | 'discard'`): Controls what happens when the target thread is active. Defaults to \`deliver\`.
|
|
213
|
+
|
|
214
|
+
**ifIdle.behavior** (`'wake' | 'persist' | 'discard'`): Controls what happens when the target thread is idle. Defaults to \`wake\`.
|
|
215
|
+
|
|
216
|
+
**ifIdle.streamOptions** (`Omit<AgentExecutionOptions, 'messages'>`): Options for the stream that starts when \`ifIdle.behavior\` is \`wake\`.
|
|
217
|
+
|
|
218
|
+
### `subscribeToThread()`
|
|
219
|
+
|
|
220
|
+
Subscribe to raw stream chunks for a memory thread. Use this to render output from a thread that may be started or continued by `sendSignal()`.
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
const agent = mastraClient.getAgent('support-agent')
|
|
224
|
+
|
|
225
|
+
const subscription = await agent.subscribeToThread({
|
|
226
|
+
resourceId: 'user-123',
|
|
227
|
+
threadId: 'thread-abc',
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
await subscription.processDataStream({
|
|
231
|
+
onChunk: async chunk => {
|
|
232
|
+
console.log(chunk)
|
|
233
|
+
},
|
|
234
|
+
})
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
`subscribeToThread()` returns the underlying `Response` plus a `processDataStream()` helper. The helper reads the subscription stream until the connection closes or the request is aborted.
|
|
238
|
+
|
|
239
|
+
**resourceId** (`string`): Resource ID for the memory thread.
|
|
240
|
+
|
|
241
|
+
**threadId** (`string`): Thread ID to subscribe to.
|
|
242
|
+
|
|
154
243
|
### `streamUntilIdle()`
|
|
155
244
|
|
|
156
245
|
Stream a response and keep the stream open until every [background task](https://mastra.ai/docs/agents/background-tasks) dispatched during the run completes. The server re-enters the agentic loop on each task completion so the LLM can react to results in the same call. Requires background tasks to be [enabled on the Mastra instance](https://mastra.ai/reference/configuration) and a memory thread; otherwise the call falls through to a plain `stream()`.
|
package/.docs/reference/index.md
CHANGED
|
@@ -199,6 +199,7 @@ The Reference section provides documentation of Mastra's API, including paramete
|
|
|
199
199
|
- [registerApiRoute()](https://mastra.ai/reference/server/register-api-route)
|
|
200
200
|
- [Server Routes](https://mastra.ai/reference/server/routes)
|
|
201
201
|
- [Overview](https://mastra.ai/reference/storage/overview)
|
|
202
|
+
- [Aurora DSQL Storage](https://mastra.ai/reference/storage/dsql)
|
|
202
203
|
- [ClickHouse Storage](https://mastra.ai/reference/storage/clickhouse)
|
|
203
204
|
- [Cloudflare D1 Storage](https://mastra.ai/reference/storage/cloudflare-d1)
|
|
204
205
|
- [Cloudflare KV Storage](https://mastra.ai/reference/storage/cloudflare)
|
|
@@ -223,6 +224,7 @@ The Reference section provides documentation of Mastra's API, including paramete
|
|
|
223
224
|
- [.stream()](https://mastra.ai/reference/streaming/workflows/stream)
|
|
224
225
|
- [.timeTravelStream()](https://mastra.ai/reference/streaming/workflows/timeTravelStream)
|
|
225
226
|
- [Overview](https://mastra.ai/reference/templates/overview)
|
|
227
|
+
- [Bright Data Tools](https://mastra.ai/reference/tools/brightdata)
|
|
226
228
|
- [createDocumentChunkerTool()](https://mastra.ai/reference/tools/document-chunker-tool)
|
|
227
229
|
- [createGraphRAGTool()](https://mastra.ai/reference/tools/graph-rag-tool)
|
|
228
230
|
- [createTool()](https://mastra.ai/reference/tools/create-tool)
|
|
@@ -257,6 +259,7 @@ The Reference section provides documentation of Mastra's API, including paramete
|
|
|
257
259
|
- [Events](https://mastra.ai/reference/voice/voice.events)
|
|
258
260
|
- [Google](https://mastra.ai/reference/voice/google)
|
|
259
261
|
- [Google Gemini Live](https://mastra.ai/reference/voice/google-gemini-live)
|
|
262
|
+
- [Inworld](https://mastra.ai/reference/voice/inworld)
|
|
260
263
|
- [Mastra Voice](https://mastra.ai/reference/voice/mastra-voice)
|
|
261
264
|
- [Murf](https://mastra.ai/reference/voice/murf)
|
|
262
265
|
- [OpenAI](https://mastra.ai/reference/voice/openai)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The `PrefillErrorHandler` is an **error processor** that handles assistant-response prefill errors. This error occurs when a conversation ends with an assistant message and the model rejects the request because it interprets it as prefilling the assistant response.
|
|
4
4
|
|
|
5
|
-
When the error is detected, the processor
|
|
5
|
+
When the error is detected, the processor sends a hidden `system-reminder` signal with `continue` as its contents and signals a retry. The reminder is persisted as signal metadata, which keeps it available for retry reconstruction and raw history while standard UI-facing message conversions hide it.
|
|
6
6
|
|
|
7
7
|
Add this processor to `errorProcessors` when you want Mastra to recover from assistant prefill rejections (for example Anthropic's "assistant message prefill" and Qwen/llama.cpp's "assistant response prefill is incompatible with `enable_thinking`" errors).
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@ Add this processor to `errorProcessors` when you want Mastra to recover from ass
|
|
|
10
10
|
|
|
11
11
|
1. The LLM API call fails with a known assistant-prefill rejection message
|
|
12
12
|
2. `PrefillErrorHandler` checks that this is the first retry attempt
|
|
13
|
-
3. It
|
|
13
|
+
3. It sends a hidden `system-reminder` signal with `continue` as its contents
|
|
14
14
|
4. It returns `{ retry: true }` to signal the LLM call should be retried with the modified messages
|
|
15
15
|
|
|
16
16
|
The processor now reacts to the API rejection itself instead of re-checking whether the conversation currently ends with an assistant message. This makes it resilient to cases where the provider rejects the request for prefill semantics even if the trailing message shape has already been transformed upstream.
|
|
@@ -62,7 +62,7 @@ The `PrefillErrorHandler` takes no constructor parameters.
|
|
|
62
62
|
|
|
63
63
|
**name** (`'Prefill Error Handler'`): Processor display name.
|
|
64
64
|
|
|
65
|
-
**processAPIError** (`(args: ProcessAPIErrorArgs) => ProcessAPIErrorResult | void`): Handles known assistant-prefill errors by
|
|
65
|
+
**processAPIError** (`(args: ProcessAPIErrorArgs) => ProcessAPIErrorResult | void`): Handles known assistant-prefill errors by sending a hidden system reminder signal and signaling retry. Only triggers on the first retry attempt.
|
|
66
66
|
|
|
67
67
|
## Related
|
|
68
68
|
|
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
# Aurora DSQL Storage
|
|
2
|
+
|
|
3
|
+
The Aurora DSQL storage implementation provides storage using Amazon Aurora DSQL with IAM authentication.
|
|
4
|
+
|
|
5
|
+
Aurora DSQL does not support PostgreSQL extensions (`CREATE EXTENSION`), including `pgvector`. For vector storage, use a separate vector store such as `@mastra/s3vectors`.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @mastra/dsql@beta
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Prerequisites
|
|
14
|
+
|
|
15
|
+
- Amazon Aurora DSQL cluster
|
|
16
|
+
- AWS credentials with access to the DSQL cluster (IAM authentication)
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { DSQLStore } from '@mastra/dsql'
|
|
22
|
+
|
|
23
|
+
const storage = new DSQLStore({
|
|
24
|
+
id: 'my-dsql-store',
|
|
25
|
+
host: 'abc123.dsql.us-east-1.on.aws',
|
|
26
|
+
// region is auto-detected from host, or specify explicitly:
|
|
27
|
+
// region: 'us-east-1',
|
|
28
|
+
// user: 'admin', // default
|
|
29
|
+
// database: 'postgres', // default
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
// Initialize the store (creates tables if needed)
|
|
33
|
+
await storage.init()
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Parameters
|
|
37
|
+
|
|
38
|
+
**id** (`string`): Unique identifier for this store instance
|
|
39
|
+
|
|
40
|
+
**host** (`string`): DSQL cluster endpoint (e.g., abc123.dsql.us-east-1.on.aws)
|
|
41
|
+
|
|
42
|
+
**pool** (`pg.Pool`): Pre-configured pg.Pool instance. Use this for direct control over the connection pool. Cannot be used with host configuration.
|
|
43
|
+
|
|
44
|
+
**user** (`string`): Database user. Aurora DSQL's admin role is 'admin'.
|
|
45
|
+
|
|
46
|
+
**database** (`string`): Database name. Aurora DSQL exposes a single database named 'postgres' per cluster.
|
|
47
|
+
|
|
48
|
+
**region** (`string`): AWS region. Extracted from host if not provided.
|
|
49
|
+
|
|
50
|
+
**schemaName** (`string`): PostgreSQL schema name where Mastra tables and indexes are created.
|
|
51
|
+
|
|
52
|
+
**customCredentialsProvider** (`AwsCredentialIdentityProvider`): Custom AWS credentials provider for IAM authentication.
|
|
53
|
+
|
|
54
|
+
**max** (`number`): Maximum connections in the pool.
|
|
55
|
+
|
|
56
|
+
**min** (`number`): Minimum connections in the pool.
|
|
57
|
+
|
|
58
|
+
**idleTimeoutMillis** (`number`): Close idle connections after this many milliseconds.
|
|
59
|
+
|
|
60
|
+
**maxLifetimeSeconds** (`number`): Maximum connection lifetime in seconds. Must be less than 3600 due to Aurora DSQL's 60-minute connection limit.
|
|
61
|
+
|
|
62
|
+
**connectionTimeoutMillis** (`number`): Connection acquisition timeout in milliseconds.
|
|
63
|
+
|
|
64
|
+
**allowExitOnIdle** (`boolean`): Allow the process to exit when all connections are idle.
|
|
65
|
+
|
|
66
|
+
## Constructor Examples
|
|
67
|
+
|
|
68
|
+
You can instantiate `DSQLStore` in the following ways:
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { DSQLStore } from '@mastra/dsql'
|
|
72
|
+
|
|
73
|
+
// Basic configuration (region auto-detected from host)
|
|
74
|
+
const store1 = new DSQLStore({
|
|
75
|
+
id: 'my-dsql-store',
|
|
76
|
+
host: 'abc123.dsql.us-east-1.on.aws',
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
// With explicit region and schema
|
|
80
|
+
const store2 = new DSQLStore({
|
|
81
|
+
id: 'my-dsql-store',
|
|
82
|
+
host: 'abc123.dsql.us-east-1.on.aws',
|
|
83
|
+
region: 'us-east-1',
|
|
84
|
+
schemaName: 'my_app',
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
// With custom credentials provider
|
|
88
|
+
import { fromNodeProviderChain } from '@aws-sdk/credential-providers'
|
|
89
|
+
|
|
90
|
+
const store3 = new DSQLStore({
|
|
91
|
+
id: 'my-dsql-store',
|
|
92
|
+
host: 'abc123.dsql.us-east-1.on.aws',
|
|
93
|
+
customCredentialsProvider: fromNodeProviderChain(),
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
// With connection pool settings
|
|
97
|
+
const store4 = new DSQLStore({
|
|
98
|
+
id: 'my-dsql-store',
|
|
99
|
+
host: 'abc123.dsql.us-east-1.on.aws',
|
|
100
|
+
max: 20,
|
|
101
|
+
min: 2,
|
|
102
|
+
idleTimeoutMillis: 300000,
|
|
103
|
+
maxLifetimeSeconds: 3000,
|
|
104
|
+
connectionTimeoutMillis: 10000,
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
// Using a pre-configured pg.Pool
|
|
108
|
+
import { Pool } from 'pg'
|
|
109
|
+
import { AuroraDSQLClient } from '@aws/aurora-dsql-node-postgres-connector'
|
|
110
|
+
|
|
111
|
+
const pool = new Pool({
|
|
112
|
+
host: 'abc123.dsql.us-east-1.on.aws',
|
|
113
|
+
Client: AuroraDSQLClient,
|
|
114
|
+
region: 'us-east-1',
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
const store5 = new DSQLStore({
|
|
118
|
+
id: 'my-dsql-store',
|
|
119
|
+
pool,
|
|
120
|
+
})
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Additional Notes
|
|
124
|
+
|
|
125
|
+
### Schema Management
|
|
126
|
+
|
|
127
|
+
The storage implementation handles schema creation and updates automatically. It creates the following tables:
|
|
128
|
+
|
|
129
|
+
- `mastra_workflow_snapshot`: Stores workflow state and execution data
|
|
130
|
+
- `mastra_threads`: Stores conversation threads
|
|
131
|
+
- `mastra_messages`: Stores individual messages
|
|
132
|
+
- `mastra_ai_spans`: Stores span data for observability
|
|
133
|
+
- `mastra_scorers`: Stores scoring and evaluation data
|
|
134
|
+
- `mastra_resources`: Stores resource working memory data
|
|
135
|
+
- `mastra_agents`: Stores agent data
|
|
136
|
+
|
|
137
|
+
### Initialization
|
|
138
|
+
|
|
139
|
+
When you pass storage to the Mastra class, `init()` is called automatically before any storage operation:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { Mastra } from '@mastra/core'
|
|
143
|
+
import { DSQLStore } from '@mastra/dsql'
|
|
144
|
+
|
|
145
|
+
const storage = new DSQLStore({
|
|
146
|
+
id: 'my-dsql-store',
|
|
147
|
+
host: 'abc123.dsql.us-east-1.on.aws',
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
const mastra = new Mastra({
|
|
151
|
+
storage, // init() is called automatically
|
|
152
|
+
})
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
If you're using storage directly without Mastra, you must call `init()` explicitly to create the tables:
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
import { DSQLStore } from '@mastra/dsql'
|
|
159
|
+
|
|
160
|
+
const storage = new DSQLStore({
|
|
161
|
+
id: 'my-dsql-store',
|
|
162
|
+
host: 'abc123.dsql.us-east-1.on.aws',
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
// Required when using storage directly
|
|
166
|
+
await storage.init()
|
|
167
|
+
|
|
168
|
+
// Access domain-specific stores via getStore()
|
|
169
|
+
const memoryStore = await storage.getStore('memory')
|
|
170
|
+
const thread = await memoryStore?.getThreadById({ threadId: '...' })
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
> **Warning:** If `init()` is not called, tables won't be created and storage operations will fail silently or throw errors.
|
|
174
|
+
|
|
175
|
+
### Direct Database and Pool Access
|
|
176
|
+
|
|
177
|
+
`DSQLStore` exposes both the underlying database client and the pg.Pool instance as public fields:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
storage.db // Database client for executing queries
|
|
181
|
+
storage.pool // Underlying pg.Pool instance
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
This enables direct queries and custom transaction management. When using these fields:
|
|
185
|
+
|
|
186
|
+
- You are responsible for proper connection and transaction handling.
|
|
187
|
+
- Closing the store (`storage.close()`) will destroy the connection pool if it was created by the store.
|
|
188
|
+
- Direct access bypasses any additional logic or validation provided by DSQLStore methods.
|
|
189
|
+
|
|
190
|
+
This approach is intended for advanced scenarios where low-level access is required.
|
|
191
|
+
|
|
192
|
+
### Aurora DSQL Specifics
|
|
193
|
+
|
|
194
|
+
#### IAM-only authentication
|
|
195
|
+
|
|
196
|
+
Connections are authenticated with IAM. There are no database passwords. `@mastra/dsql` uses `@aws/aurora-dsql-node-postgres-connector` to generate short-lived auth tokens. You can provide a custom credentials provider via `customCredentialsProvider`.
|
|
197
|
+
|
|
198
|
+
#### Single database, schema-based isolation
|
|
199
|
+
|
|
200
|
+
Each cluster exposes a single database named `postgres`. Logical separation is done via schemas. The `schemaName` option controls where Mastra tables are created.
|
|
201
|
+
|
|
202
|
+
#### No PostgreSQL extensions
|
|
203
|
+
|
|
204
|
+
`CREATE EXTENSION` is not supported. This includes `pgvector`, `PostGIS`, and others. For vector storage, use a separate store such as `@mastra/s3vectors` alongside `DSQLStore`.
|
|
205
|
+
|
|
206
|
+
#### JSON stored as text
|
|
207
|
+
|
|
208
|
+
JSON/JSONB are available as query types but not as column types. `@mastra/dsql` stores structured fields (metadata, content, etc.) in `TEXT` columns and casts to JSON at query time.
|
|
209
|
+
|
|
210
|
+
#### Schema and DDL constraints
|
|
211
|
+
|
|
212
|
+
Some PostgreSQL features are not available:
|
|
213
|
+
|
|
214
|
+
- Foreign key constraints
|
|
215
|
+
- `TRUNCATE`
|
|
216
|
+
- Synchronous `CREATE INDEX`
|
|
217
|
+
|
|
218
|
+
Indexes are created asynchronously using `CREATE INDEX ASYNC`. The store's `init()` and index helper APIs respect these constraints.
|
|
219
|
+
|
|
220
|
+
#### Transactions and optimistic concurrency
|
|
221
|
+
|
|
222
|
+
Aurora DSQL uses optimistic concurrency control (OCC) and may return retriable OCC errors under contention. There are limits on transaction duration and size. Large bulk operations should be split into smaller batches at the application level.
|
|
223
|
+
|
|
224
|
+
#### Connection lifetime
|
|
225
|
+
|
|
226
|
+
Individual connections are limited to about 60 minutes. The default `maxLifetimeSeconds: 3300` ensures connections are recycled before hitting this limit.
|
|
227
|
+
|
|
228
|
+
## Usage Example
|
|
229
|
+
|
|
230
|
+
### Adding memory to an agent
|
|
231
|
+
|
|
232
|
+
To add Aurora DSQL memory to an agent use the `Memory` class and create a new `storage` key using `DSQLStore`. The `host` should point to your Aurora DSQL cluster endpoint.
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import { Memory } from '@mastra/memory'
|
|
236
|
+
import { Agent } from '@mastra/core/agent'
|
|
237
|
+
import { DSQLStore } from '@mastra/dsql'
|
|
238
|
+
|
|
239
|
+
export const dsqlAgent = new Agent({
|
|
240
|
+
id: 'dsql-agent',
|
|
241
|
+
name: 'DSQL Agent',
|
|
242
|
+
instructions:
|
|
243
|
+
'You are an AI agent with the ability to automatically recall memories from previous interactions.',
|
|
244
|
+
model: 'openai/gpt-5.1',
|
|
245
|
+
memory: new Memory({
|
|
246
|
+
storage: new DSQLStore({
|
|
247
|
+
id: 'dsql-agent-storage',
|
|
248
|
+
host: process.env.DSQL_HOST!,
|
|
249
|
+
}),
|
|
250
|
+
options: {
|
|
251
|
+
generateTitle: true, // Explicitly enable automatic title generation
|
|
252
|
+
},
|
|
253
|
+
}),
|
|
254
|
+
})
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Using the agent
|
|
258
|
+
|
|
259
|
+
Use `memoryOptions` to scope recall for this request. Set `lastMessages: 5` to limit recency-based recall, and use `semanticRecall` to fetch the `topK: 3` most relevant messages, including `messageRange: 2` neighboring messages for context around each match.
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
import 'dotenv/config'
|
|
263
|
+
|
|
264
|
+
import { mastra } from './mastra'
|
|
265
|
+
|
|
266
|
+
const threadId = '123'
|
|
267
|
+
const resourceId = 'user-456'
|
|
268
|
+
|
|
269
|
+
const agent = mastra.getAgent('dsql-agent')
|
|
270
|
+
|
|
271
|
+
const message = await agent.stream('My name is Mastra', {
|
|
272
|
+
memory: {
|
|
273
|
+
thread: threadId,
|
|
274
|
+
resource: resourceId,
|
|
275
|
+
},
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
await message.textStream.pipeTo(new WritableStream())
|
|
279
|
+
|
|
280
|
+
const stream = await agent.stream("What's my name?", {
|
|
281
|
+
memory: {
|
|
282
|
+
thread: threadId,
|
|
283
|
+
resource: resourceId,
|
|
284
|
+
},
|
|
285
|
+
memoryOptions: {
|
|
286
|
+
lastMessages: 5,
|
|
287
|
+
semanticRecall: {
|
|
288
|
+
topK: 3,
|
|
289
|
+
messageRange: 2,
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
for await (const chunk of stream.textStream) {
|
|
295
|
+
process.stdout.write(chunk)
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Index Management
|
|
300
|
+
|
|
301
|
+
Aurora DSQL storage provides index management capabilities to optimize query performance.
|
|
302
|
+
|
|
303
|
+
### Automatic Performance Indexes
|
|
304
|
+
|
|
305
|
+
Aurora DSQL storage automatically creates composite indexes during initialization for common query patterns:
|
|
306
|
+
|
|
307
|
+
- `mastra_threads_resourceid_createdat_idx`: (resourceId, createdAt)
|
|
308
|
+
- `mastra_messages_thread_id_createdat_idx`: (thread\_id, createdAt)
|
|
309
|
+
- `mastra_ai_spans_traceid_startedat_idx`: (traceId, startedAt)
|
|
310
|
+
- `mastra_ai_spans_parentspanid_startedat_idx`: (parentSpanId, startedAt)
|
|
311
|
+
- `mastra_ai_spans_name_idx`: (name)
|
|
312
|
+
- `mastra_ai_spans_spantype_startedat_idx`: (spanType, startedAt)
|
|
313
|
+
- `mastra_scores_trace_id_span_id_created_at_idx`: (traceId, spanId, createdAt)
|
|
314
|
+
|
|
315
|
+
Aurora DSQL creates these indexes asynchronously using `CREATE INDEX ASYNC`. Because index creation is asynchronous, new indexes may not be immediately available after `init()`. The store will continue to function without them, but queries may be slower until index creation completes.
|
|
316
|
+
|
|
317
|
+
### Creating Custom Indexes
|
|
318
|
+
|
|
319
|
+
Create additional indexes to optimize specific query patterns:
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
await storage.createIndex({
|
|
323
|
+
name: 'idx_threads_resource',
|
|
324
|
+
table: 'mastra_threads',
|
|
325
|
+
columns: ['resourceId'],
|
|
326
|
+
})
|
|
327
|
+
|
|
328
|
+
await storage.createIndex({
|
|
329
|
+
name: 'idx_messages_composite',
|
|
330
|
+
table: 'mastra_messages',
|
|
331
|
+
columns: ['thread_id', 'createdAt'],
|
|
332
|
+
})
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Aurora DSQL does not allow `ASC`/`DESC` in `CREATE INDEX ASYNC`. If you include them, they will be automatically stripped.
|
|
336
|
+
|
|
337
|
+
### Index Options
|
|
338
|
+
|
|
339
|
+
**name** (`string`): Unique name for the index
|
|
340
|
+
|
|
341
|
+
**table** (`string`): Table name (e.g., 'mastra\_threads')
|
|
342
|
+
|
|
343
|
+
**columns** (`string[]`): Array of column names. ASC/DESC modifiers are automatically stripped for Aurora DSQL compatibility.
|
|
344
|
+
|
|
345
|
+
**unique** (`boolean`): Create a unique index.
|
|
346
|
+
|
|
347
|
+
**concurrent** (`boolean`): Ignored in Aurora DSQL. Indexes are always created asynchronously.
|
|
348
|
+
|
|
349
|
+
**where** (`string`): Partial index condition.
|
|
350
|
+
|
|
351
|
+
**method** (`string`): Ignored in Aurora DSQL. Only btree indexes are supported.
|
|
352
|
+
|
|
353
|
+
**opclass** (`string`): Ignored in Aurora DSQL.
|
|
354
|
+
|
|
355
|
+
**storage** (`Record<string, any>`): Ignored in Aurora DSQL.
|
|
356
|
+
|
|
357
|
+
**tablespace** (`string`): Ignored in Aurora DSQL. Tablespaces are not supported.
|
|
358
|
+
|
|
359
|
+
### Managing Indexes
|
|
360
|
+
|
|
361
|
+
List and monitor existing indexes:
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
// List all indexes
|
|
365
|
+
const allIndexes = await storage.listIndexes()
|
|
366
|
+
console.log(allIndexes)
|
|
367
|
+
// [
|
|
368
|
+
// {
|
|
369
|
+
// name: 'mastra_threads_pkey',
|
|
370
|
+
// table: 'mastra_threads',
|
|
371
|
+
// columns: ['id'],
|
|
372
|
+
// unique: true,
|
|
373
|
+
// size: '16 KB',
|
|
374
|
+
// definition: 'CREATE UNIQUE INDEX...'
|
|
375
|
+
// },
|
|
376
|
+
// ...
|
|
377
|
+
// ]
|
|
378
|
+
|
|
379
|
+
// List indexes for a specific table
|
|
380
|
+
const threadIndexes = await storage.listIndexes('mastra_threads')
|
|
381
|
+
|
|
382
|
+
// Get detailed statistics for an index
|
|
383
|
+
const stats = await storage.describeIndex('idx_threads_resource')
|
|
384
|
+
console.log(stats)
|
|
385
|
+
// {
|
|
386
|
+
// name: 'idx_threads_resource',
|
|
387
|
+
// table: 'mastra_threads',
|
|
388
|
+
// columns: ['resourceId'],
|
|
389
|
+
// unique: false,
|
|
390
|
+
// size: '128 KB',
|
|
391
|
+
// definition: 'CREATE INDEX idx_threads_resource...',
|
|
392
|
+
// method: 'btree',
|
|
393
|
+
// scans: 1542,
|
|
394
|
+
// tuples_read: 45230,
|
|
395
|
+
// tuples_fetched: 12050
|
|
396
|
+
// }
|
|
397
|
+
|
|
398
|
+
// Drop an index
|
|
399
|
+
await storage.dropIndex('idx_threads_status')
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### Schema-Specific Indexes
|
|
403
|
+
|
|
404
|
+
When using custom schemas, indexes are created with schema prefixes:
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
const storage = new DSQLStore({
|
|
408
|
+
id: 'my-dsql-store',
|
|
409
|
+
host: 'abc123.dsql.us-east-1.on.aws',
|
|
410
|
+
schemaName: 'custom_schema',
|
|
411
|
+
})
|
|
412
|
+
|
|
413
|
+
// Creates index as: custom_schema_idx_threads_status
|
|
414
|
+
await storage.createIndex({
|
|
415
|
+
name: 'idx_threads_status',
|
|
416
|
+
table: 'mastra_threads',
|
|
417
|
+
columns: ['status'],
|
|
418
|
+
})
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
## Related Resources
|
|
422
|
+
|
|
423
|
+
- [Aurora DSQL Documentation](https://docs.aws.amazon.com/aurora-dsql/)
|
|
424
|
+
- [SQL Reference](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/working-with-aurora-dsql-sql.html)
|
|
425
|
+
- [Supported SQL Features](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/working-with-postgresql-compatibility-supported-sql-features.html)
|
|
426
|
+
- [Unsupported PostgreSQL Features](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/working-with-postgresql-compatibility-unsupported-features.html)
|
|
427
|
+
- [Supported Data Types](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/working-with-postgresql-compatibility-supported-data-types.html)
|
|
428
|
+
- [Asynchronous Indexes](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/working-with-create-index-async.html)
|