@mastra/mcp-docs-server 1.0.0-beta.14 → 1.0.0-beta.16

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.
Files changed (63) hide show
  1. package/.docs/organized/changelogs/%40mastra%2Fagent-builder.md +41 -41
  2. package/.docs/organized/changelogs/%40mastra%2Fai-sdk.md +51 -51
  3. package/.docs/organized/changelogs/%40mastra%2Fclickhouse.md +235 -235
  4. package/.docs/organized/changelogs/%40mastra%2Fclient-js.md +85 -85
  5. package/.docs/organized/changelogs/%40mastra%2Fcloudflare-d1.md +235 -235
  6. package/.docs/organized/changelogs/%40mastra%2Fcloudflare.md +235 -235
  7. package/.docs/organized/changelogs/%40mastra%2Fconvex.md +258 -0
  8. package/.docs/organized/changelogs/%40mastra%2Fcore.md +338 -338
  9. package/.docs/organized/changelogs/%40mastra%2Fdeployer-cloud.md +27 -27
  10. package/.docs/organized/changelogs/%40mastra%2Fdeployer.md +67 -67
  11. package/.docs/organized/changelogs/%40mastra%2Fdynamodb.md +235 -235
  12. package/.docs/organized/changelogs/%40mastra%2Fevals.md +10 -10
  13. package/.docs/organized/changelogs/%40mastra%2Ffastembed.md +6 -0
  14. package/.docs/organized/changelogs/%40mastra%2Flance.md +235 -235
  15. package/.docs/organized/changelogs/%40mastra%2Flibsql.md +235 -235
  16. package/.docs/organized/changelogs/%40mastra%2Fmcp-docs-server.md +16 -16
  17. package/.docs/organized/changelogs/%40mastra%2Fmcp.md +30 -30
  18. package/.docs/organized/changelogs/%40mastra%2Fmemory.md +168 -168
  19. package/.docs/organized/changelogs/%40mastra%2Fmongodb.md +259 -259
  20. package/.docs/organized/changelogs/%40mastra%2Fmssql.md +259 -259
  21. package/.docs/organized/changelogs/%40mastra%2Fpg.md +279 -279
  22. package/.docs/organized/changelogs/%40mastra%2Fplayground-ui.md +108 -108
  23. package/.docs/organized/changelogs/%40mastra%2Freact.md +77 -77
  24. package/.docs/organized/changelogs/%40mastra%2Fserver.md +180 -180
  25. package/.docs/organized/changelogs/%40mastra%2Fupstash.md +235 -235
  26. package/.docs/organized/changelogs/create-mastra.md +11 -11
  27. package/.docs/organized/changelogs/mastra.md +40 -40
  28. package/.docs/organized/code-examples/agent-v6.md +70 -11
  29. package/.docs/organized/code-examples/client-side-tools.md +1 -1
  30. package/.docs/raw/agents/adding-voice.mdx +8 -3
  31. package/.docs/raw/deployment/overview.mdx +3 -4
  32. package/.docs/raw/deployment/workflow-runners.mdx +14 -0
  33. package/.docs/raw/getting-started/studio.mdx +1 -1
  34. package/.docs/raw/guides/deployment/inngest.mdx +198 -140
  35. package/.docs/raw/guides/migrations/upgrade-to-v1/memory.mdx +11 -3
  36. package/.docs/raw/guides/migrations/upgrade-to-v1/processors.mdx +11 -0
  37. package/.docs/raw/guides/migrations/upgrade-to-v1/storage.mdx +68 -0
  38. package/.docs/raw/mastra-cloud/deployment.mdx +39 -0
  39. package/.docs/raw/mastra-cloud/observability.mdx +9 -15
  40. package/.docs/raw/mastra-cloud/overview.mdx +14 -44
  41. package/.docs/raw/mastra-cloud/setup.mdx +64 -0
  42. package/.docs/raw/mastra-cloud/studio.mdx +35 -0
  43. package/.docs/raw/reference/client-js/workflows.mdx +15 -0
  44. package/.docs/raw/reference/logging/pino-logger.mdx +1 -1
  45. package/.docs/raw/reference/processors/token-limiter-processor.mdx +39 -18
  46. package/.docs/raw/reference/storage/cloudflare-d1.mdx +4 -2
  47. package/.docs/raw/reference/storage/composite.mdx +223 -0
  48. package/.docs/raw/reference/storage/lance.mdx +3 -2
  49. package/.docs/raw/reference/storage/libsql.mdx +5 -2
  50. package/.docs/raw/reference/storage/mongodb.mdx +4 -2
  51. package/.docs/raw/reference/storage/mssql.mdx +4 -2
  52. package/.docs/raw/reference/storage/postgresql.mdx +4 -2
  53. package/.docs/raw/reference/tools/mcp-server.mdx +9 -0
  54. package/.docs/raw/reference/workflows/run-methods/cancel.mdx +51 -3
  55. package/.docs/raw/reference/workflows/run.mdx +8 -2
  56. package/.docs/raw/voice/overview.mdx +1 -1
  57. package/.docs/raw/workflows/overview.mdx +1 -1
  58. package/.docs/raw/workflows/snapshots.mdx +2 -1
  59. package/CHANGELOG.md +15 -0
  60. package/package.json +5 -5
  61. package/.docs/raw/mastra-cloud/dashboard.mdx +0 -96
  62. package/.docs/raw/mastra-cloud/setting-up.mdx +0 -106
  63. package/.docs/raw/workflows/inngest-workflow.mdx +0 -362
@@ -1,502 +1,502 @@
1
1
  # @mastra/core
2
2
 
3
- ## 1.0.0-beta.14
3
+ ## 1.0.0-beta.16
4
4
 
5
5
  ### Minor Changes
6
6
 
7
- - Add support for AI SDK v6 (LanguageModelV3) ([#11191](https://github.com/mastra-ai/mastra/pull/11191))
7
+ - Add `onError` hook to server configuration for custom error handling. ([#11403](https://github.com/mastra-ai/mastra/pull/11403))
8
8
 
9
- Agents can now use `LanguageModelV3` models from AI SDK v6 beta providers like `@ai-sdk/openai@^3.0.0-beta`.
9
+ You can now provide a custom error handler through the Mastra server config to catch errors, format responses, or send them to external services like Sentry:
10
10
 
11
- **New features:**
12
- - Usage normalization: V3's nested usage format is normalized to Mastra's flat format with `reasoningTokens`, `cachedInputTokens`, and raw data preserved in a `raw` field
11
+ ```typescript
12
+ import { Mastra } from '@mastra/core/mastra';
13
13
 
14
- **Backward compatible:** All existing V1 and V2 models continue to work unchanged.
14
+ const mastra = new Mastra({
15
+ server: {
16
+ onError: (err, c) => {
17
+ // Send to Sentry
18
+ Sentry.captureException(err);
19
+
20
+ // Return custom formatted response
21
+ return c.json(
22
+ {
23
+ error: err.message,
24
+ timestamp: new Date().toISOString(),
25
+ },
26
+ 500,
27
+ );
28
+ },
29
+ },
30
+ });
31
+ ```
15
32
 
16
- ### Patch Changes
33
+ If no `onError` is provided, the default error handler is used.
17
34
 
18
- - Fix model-level and runtime header support for LLM calls ([#11275](https://github.com/mastra-ai/mastra/pull/11275))
35
+ Fixes #9610
19
36
 
20
- This fixes a bug where custom headers configured on models (like `anthropic-beta`) were not being passed through to the underlying AI SDK calls. The fix properly handles headers from multiple sources with correct priority:
37
+ ### Patch Changes
21
38
 
22
- **Header Priority (low to high):**
23
- 1. Model config headers - Headers set in model configuration
24
- 2. ModelSettings headers - Runtime headers that override model config
25
- 3. Provider-level headers - Headers baked into AI SDK providers (not overridden)
39
+ - fix(observability): start MODEL_STEP span at beginning of LLM execution ([#11409](https://github.com/mastra-ai/mastra/pull/11409))
26
40
 
27
- **Examples that now work:**
41
+ The MODEL_STEP span was being created when the step-start chunk arrived (after the model API call completed), causing the span's startTime to be close to its endTime instead of accurately reflecting when the step began.
28
42
 
29
- ```typescript
30
- // Model config headers
31
- new Agent({
32
- model: {
33
- id: 'anthropic/claude-4-5-sonnet',
34
- headers: { 'anthropic-beta': 'context-1m-2025-08-07' },
35
- },
36
- });
43
+ This fix ensures MODEL_STEP spans capture the full duration of each LLM execution step, including the API call latency, by starting the span at the beginning of the step execution rather than when the response starts streaming.
37
44
 
38
- // Runtime headers override config
39
- agent.generate('...', {
40
- modelSettings: { headers: { 'x-custom': 'runtime-value' } },
41
- });
45
+ Fixes #11271
42
46
 
43
- // Provider-level headers preserved
44
- const openai = createOpenAI({ headers: { 'openai-organization': 'org-123' } });
45
- new Agent({ model: openai('gpt-4o-mini') });
46
- ```
47
+ - Fixed inline type narrowing for `tool.execute()` return type when using `outputSchema`. ([#11420](https://github.com/mastra-ai/mastra/pull/11420))
47
48
 
48
- - Fixed AbortSignal not propagating from parent workflows to nested sub-workflows in the evented workflow engine. ([#11142](https://github.com/mastra-ai/mastra/pull/11142))
49
+ **Problem:** When calling `tool.execute()`, TypeScript couldn't narrow the `ValidationError | OutputType` union after checking `'error' in result && result.error`, causing type errors when accessing output properties.
49
50
 
50
- Previously, canceling a parent workflow did not stop nested sub-workflows, causing them to continue running and consuming resources after the parent was canceled.
51
+ **Solution:**
52
+ - Added `{ error?: never }` to the success type, enabling proper discriminated union narrowing
53
+ - Simplified `createTool` generics so `inputData` is correctly typed based on `inputSchema`
51
54
 
52
- Now, when you cancel a parent workflow, all nested sub-workflows are automatically canceled as well, ensuring clean termination of the entire workflow tree.
55
+ **Note:** Tool output schemas should not use `error` as a field name since it's reserved for ValidationError discrimination. Use `errorMessage` or similar instead.
53
56
 
54
- **Example:**
57
+ **Usage:**
55
58
 
56
59
  ```typescript
57
- const parentWorkflow = createWorkflow({ id: 'parent-workflow' }).then(someStep).then(nestedChildWorkflow).commit();
60
+ const result = await myTool.execute({ firstName: 'Hans' });
58
61
 
59
- const run = await parentWorkflow.createRun();
60
- const resultPromise = run.start({ inputData: { value: 5 } });
61
-
62
- // Cancel the parent workflow - nested workflows will also be canceled
63
- await run.cancel();
64
- // or use: run.abortController.abort();
62
+ if ('error' in result && result.error) {
63
+ console.error('Validation failed:', result.message);
64
+ return;
65
+ }
65
66
 
66
- const result = await resultPromise;
67
- // result.status === 'canceled'
68
- // All nested child workflows are also canceled
67
+ // TypeScript now correctly narrows result
68
+ return { fullName: result.fullName };
69
69
  ```
70
70
 
71
- Related to #11063
72
-
73
- - Fix empty overrideScorers causing error instead of skipping scoring ([#11257](https://github.com/mastra-ai/mastra/pull/11257))
71
+ - Add support for `instructions` field in MCPServer ([#11421](https://github.com/mastra-ai/mastra/pull/11421))
74
72
 
75
- When `overrideScorers` was passed as an empty object `{}`, the agent would throw a "No scorers found" error. Now an empty object explicitly skips scoring, while `undefined` continues to use default scorers.
73
+ Implements the official MCP specification's `instructions` field, which allows MCP servers to provide system-wide prompts that are automatically sent to clients during initialization. This eliminates the need for per-project configuration files (like AGENTS.md) by centralizing the system prompt in the server definition.
76
74
 
77
- - feat: Add field filtering and nested workflow control to workflow execution result endpoint ([#11246](https://github.com/mastra-ai/mastra/pull/11246))
75
+ **What's New:**
76
+ - Added `instructions` optional field to `MCPServerConfig` type
77
+ - Instructions are passed to the underlying MCP SDK Server during initialization
78
+ - Instructions are sent to clients in the `InitializeResult` response
79
+ - Fully compatible with all MCP clients (Cursor, Windsurf, Claude Desktop, etc.)
78
80
 
79
- Adds two optional query parameters to `/api/workflows/:workflowId/runs/:runId/execution-result` endpoint:
80
- - `fields`: Request only specific fields (e.g., `status`, `result`, `error`)
81
- - `withNestedWorkflows`: Control whether to fetch nested workflow data
81
+ **Example Usage:**
82
82
 
83
- This significantly reduces response payload size and improves response times for large workflows.
83
+ ```typescript
84
+ const server = new MCPServer({
85
+ name: 'GitHub MCP Server',
86
+ version: '1.0.0',
87
+ instructions:
88
+ 'Use the available tools to help users manage GitHub repositories, issues, and pull requests. Always search before creating to avoid duplicates.',
89
+ tools: { searchIssues, createIssue, listPRs },
90
+ });
91
+ ```
84
92
 
85
- ## Server Endpoint Usage
93
+ - Add storage composition to MastraStorage ([#11401](https://github.com/mastra-ai/mastra/pull/11401))
86
94
 
87
- ```http
88
- # Get only status (minimal payload - fastest)
89
- GET /api/workflows/:workflowId/runs/:runId/execution-result?fields=status
95
+ `MastraStorage` can now compose storage domains from different adapters. Use it when you need different databases for different purposes - for example, PostgreSQL for memory and workflows, but a different database for observability.
90
96
 
91
- # Get status and result
92
- GET /api/workflows/:workflowId/runs/:runId/execution-result?fields=status,result
97
+ ```typescript
98
+ import { MastraStorage } from '@mastra/core/storage';
99
+ import { MemoryPG, WorkflowsPG, ScoresPG } from '@mastra/pg';
100
+ import { MemoryLibSQL } from '@mastra/libsql';
101
+
102
+ // Compose domains from different stores
103
+ const storage = new MastraStorage({
104
+ id: 'composite',
105
+ domains: {
106
+ memory: new MemoryLibSQL({ url: 'file:./local.db' }),
107
+ workflows: new WorkflowsPG({ connectionString: process.env.DATABASE_URL }),
108
+ scores: new ScoresPG({ connectionString: process.env.DATABASE_URL }),
109
+ },
110
+ });
111
+ ```
93
112
 
94
- # Get all fields but without nested workflow data (faster)
95
- GET /api/workflows/:workflowId/runs/:runId/execution-result?withNestedWorkflows=false
113
+ **Breaking changes:**
114
+ - `storage.supports` property no longer exists
115
+ - `StorageSupports` type is no longer exported from `@mastra/core/storage`
96
116
 
97
- # Get only specific fields without nested workflow data
98
- GET /api/workflows/:workflowId/runs/:runId/execution-result?fields=status,steps&withNestedWorkflows=false
117
+ All stores now support the same features. For domain availability, use `getStore()`:
99
118
 
100
- # Get full data (default behavior)
101
- GET /api/workflows/:workflowId/runs/:runId/execution-result
119
+ ```typescript
120
+ const store = await storage.getStore('memory');
121
+ if (store) {
122
+ // domain is available
123
+ }
102
124
  ```
103
125
 
104
- ## Client SDK Usage
126
+ - Fix various places in core package where we were logging with console.error instead of the mastra logger. ([#11425](https://github.com/mastra-ai/mastra/pull/11425))
105
127
 
106
- ```typescript
107
- import { MastraClient } from '@mastra/client-js';
128
+ - fix(workflows): ensure writer.custom() bubbles up from nested workflows and loops ([#11422](https://github.com/mastra-ai/mastra/pull/11422))
108
129
 
109
- const client = new MastraClient({ baseUrl: 'http://localhost:4111' });
110
- const workflow = client.getWorkflow('myWorkflow');
130
+ Previously, when using `writer.custom()` in steps within nested sub-workflows or loops (like `dountil`), the custom data events would not properly bubble up to the top-level workflow stream. This fix ensures that custom events are now correctly propagated through the nested workflow hierarchy without modification, allowing them to be consumed at the top level.
111
131
 
112
- // Get only status (minimal payload - fastest)
113
- const statusOnly = await workflow.runExecutionResult(runId, {
114
- fields: ['status'],
115
- });
116
- console.log(statusOnly.status); // 'success' | 'failed' | 'running' | etc.
132
+ This brings workflows in line with the existing behavior for agents, where custom data chunks properly bubble up through sub-agent execution.
117
133
 
118
- // Get status and result
119
- const statusAndResult = await workflow.runExecutionResult(runId, {
120
- fields: ['status', 'result'],
121
- });
134
+ **What changed:**
135
+ - Modified the `nestedWatchCb` function in workflow event handling to detect and preserve `data-*` custom events
136
+ - Custom events now bubble up directly without being wrapped or modified
137
+ - Regular workflow events continue to work as before with proper step ID prefixing
122
138
 
123
- // Get all fields but without nested workflow data (faster)
124
- const resultWithoutNested = await workflow.runExecutionResult(runId, {
125
- withNestedWorkflows: false,
126
- });
139
+ **Example:**
127
140
 
128
- // Get specific fields without nested workflow data
129
- const optimized = await workflow.runExecutionResult(runId, {
130
- fields: ['status', 'steps'],
131
- withNestedWorkflows: false,
141
+ ```typescript
142
+ const subStep = createStep({
143
+ id: 'subStep',
144
+ execute: async ({ writer }) => {
145
+ await writer.custom({
146
+ type: 'custom-progress',
147
+ data: { status: 'processing' },
148
+ });
149
+ return { result: 'done' };
150
+ },
132
151
  });
133
152
 
134
- // Get full execution result (default behavior)
135
- const fullResult = await workflow.runExecutionResult(runId);
136
- ```
153
+ const subWorkflow = createWorkflow({ id: 'sub' }).then(subStep).commit();
137
154
 
138
- ## Core API Changes
155
+ const topWorkflow = createWorkflow({ id: 'top' }).then(subWorkflow).commit();
139
156
 
140
- The `Workflow.getWorkflowRunExecutionResult` method now accepts an options object:
157
+ const run = await topWorkflow.createRun();
158
+ const stream = run.stream({ inputData: {} });
141
159
 
142
- ```typescript
143
- await workflow.getWorkflowRunExecutionResult(runId, {
144
- withNestedWorkflows: false, // default: true, set to false to skip nested workflow data
145
- fields: ['status', 'result'], // optional field filtering
146
- });
160
+ // Custom events from subStep now properly appear in the top-level stream
161
+ for await (const event of stream) {
162
+ if (event.type === 'custom-progress') {
163
+ console.log(event.data); // { status: 'processing' }
164
+ }
165
+ }
147
166
  ```
148
167
 
149
- ## Inngest Compatibility
150
-
151
- The `@mastra/inngest` package has been updated to use the new options object API. This is a non-breaking internal change - no action required from inngest workflow users.
152
-
153
- ## Performance Impact
168
+ ## 1.0.0-beta.15
154
169
 
155
- For workflows with large step outputs:
156
- - Requesting only `status`: ~99% reduction in payload size
157
- - Requesting `status,result,error`: ~95% reduction in payload size
158
- - Using `withNestedWorkflows=false`: Avoids expensive nested workflow data fetching
159
- - Combining both: Maximum performance optimization
160
-
161
- - Removed a debug log that printed large Zod schemas, resulting in cleaner console output when using agents with memory enabled. ([#11279](https://github.com/mastra-ai/mastra/pull/11279))
170
+ ### Minor Changes
162
171
 
163
- - Set `externals: true` as the default for `mastra build` and cloud-deployer to reduce bundle issues with native dependencies. ([`0dbf199`](https://github.com/mastra-ai/mastra/commit/0dbf199110f22192ce5c95b1c8148d4872b4d119))
172
+ - Introduce StorageDomain base class for composite storage support ([#11249](https://github.com/mastra-ai/mastra/pull/11249))
164
173
 
165
- **Note:** If you previously relied on the default bundling behavior (all dependencies bundled), you can explicitly set `externals: false` in your bundler configuration.
174
+ Storage adapters now use a domain-based architecture where each domain (memory, workflows, scores, observability, agents) extends a `StorageDomain` base class with `init()` and `dangerouslyClearAll()` methods.
166
175
 
167
- - Fix delayed promises rejecting when stream suspends on tool-call-approval ([#11278](https://github.com/mastra-ai/mastra/pull/11278))
176
+ **Key changes:**
177
+ - Add `StorageDomain` abstract base class that all domain storage classes extend
178
+ - Add `InMemoryDB` class for shared state across in-memory domain implementations
179
+ - All storage domains now implement `dangerouslyClearAll()` for test cleanup
180
+ - Remove `operations` from public `StorageDomains` type (now internal to each adapter)
181
+ - Add flexible client/config patterns - domains accept either an existing database client or config to create one internally
168
182
 
169
- When a stream ends in suspended state (e.g., requiring tool approval), the delayed promises like `toolResults`, `toolCalls`, `text`, etc. now resolve with partial results instead of rejecting with an error. This allows consumers to access data that was produced before the suspension.
183
+ **Why this matters:**
170
184
 
171
- Also improves generic type inference for `LLMStepResult` and related types throughout the streaming infrastructure.
185
+ This enables composite storage where you can use different database adapters per domain:
172
186
 
173
- ## 1.0.0-beta.13
187
+ ```typescript
188
+ import { Mastra } from '@mastra/core';
189
+ import { PostgresStore } from '@mastra/pg';
190
+ import { ClickhouseStore } from '@mastra/clickhouse';
174
191
 
175
- ### Patch Changes
192
+ // Use Postgres for most domains but Clickhouse for observability
193
+ const mastra = new Mastra({
194
+ storage: new PostgresStore({
195
+ connectionString: 'postgres://...',
196
+ }),
197
+ // Future: override specific domains
198
+ // observability: new ClickhouseStore({ ... }).getStore('observability'),
199
+ });
200
+ ```
176
201
 
177
- - Add `onFinish` and `onError` lifecycle callbacks to workflow options ([#11200](https://github.com/mastra-ai/mastra/pull/11200))
202
+ **Standalone domain usage:**
178
203
 
179
- Workflows now support lifecycle callbacks for server-side handling of workflow completion and errors:
180
- - `onFinish`: Called when workflow completes with any status (success, failed, suspended, tripwire)
181
- - `onError`: Called only when workflow fails (failed or tripwire status)
204
+ Domains can now be used independently with flexible configuration:
182
205
 
183
206
  ```typescript
184
- const workflow = createWorkflow({
185
- id: 'my-workflow',
186
- inputSchema: z.object({ ... }),
187
- outputSchema: z.object({ ... }),
188
- options: {
189
- onFinish: async (result) => {
190
- // Handle any workflow completion
191
- await updateJobStatus(result.status);
192
- },
193
- onError: async (errorInfo) => {
194
- // Handle workflow failures
195
- await logError(errorInfo.error);
196
- },
197
- },
207
+ import { MemoryLibSQL } from '@mastra/libsql/memory';
208
+
209
+ // Option 1: Pass config to create client internally
210
+ const memory = new MemoryLibSQL({
211
+ url: 'file:./local.db',
198
212
  });
199
- ```
200
213
 
201
- Both callbacks support sync and async functions. Callback errors are caught and logged, not propagated to the workflow result.
214
+ // Option 2: Pass existing client for shared connections
215
+ import { createClient } from '@libsql/client';
216
+ const client = createClient({ url: 'file:./local.db' });
217
+ const memory = new MemoryLibSQL({ client });
218
+ ```
202
219
 
203
- ## 1.0.0-beta.12
220
+ **Breaking changes:**
221
+ - `StorageDomains` type no longer includes `operations` - access via `getStore()` instead
222
+ - Domain base classes now require implementing `dangerouslyClearAll()` method
204
223
 
205
- ### Patch Changes
224
+ - Refactor storage architecture to use domain-specific stores via `getStore()` pattern ([#11361](https://github.com/mastra-ai/mastra/pull/11361))
206
225
 
207
- - Remove redundant toolCalls from network agent finalResult ([#11189](https://github.com/mastra-ai/mastra/pull/11189))
226
+ ### Summary
208
227
 
209
- The network agent's `finalResult` was storing `toolCalls` separately even though all tool call information is already present in the `messages` array (as `tool-call` and `tool-result` type messages). This caused significant token waste since the routing agent reads this data from memory on every iteration.
228
+ This release introduces a new storage architecture that replaces passthrough methods on `MastraStorage` with domain-specific storage interfaces accessed via `getStore()`. This change reduces code duplication across storage adapters and provides a cleaner, more modular API.
210
229
 
211
- **Before:** `finalResult: { text, toolCalls, messages }`
212
- **After:** `finalResult: { text, messages }`
230
+ ### Migration Guide
213
231
 
214
- +**Migration:** If you were accessing `finalResult.toolCalls`, retrieve tool calls from `finalResult.messages` by filtering for messages with `type: 'tool-call'`.
232
+ All direct method calls on storage instances should be updated to use `getStore()`:
215
233
 
216
- Updated `@mastra/react` to extract tool calls directly from the `messages` array instead of the removed `toolCalls` field when resolving initial messages from memory.
234
+ ```typescript
235
+ // Before
236
+ const thread = await storage.getThreadById({ threadId });
237
+ await storage.persistWorkflowSnapshot({ workflowName, runId, snapshot });
238
+ await storage.createSpan(span);
217
239
 
218
- Fixes #11059
240
+ // After
241
+ const memory = await storage.getStore('memory');
242
+ const thread = await memory?.getThreadById({ threadId });
219
243
 
220
- - Embed AI types to fix peerdeps mismatches ([`9650cce`](https://github.com/mastra-ai/mastra/commit/9650cce52a1d917ff9114653398e2a0f5c3ba808))
244
+ const workflows = await storage.getStore('workflows');
245
+ await workflows?.persistWorkflowSnapshot({ workflowName, runId, snapshot });
221
246
 
222
- - Fix invalid state: Controller is already closed ([`932d63d`](https://github.com/mastra-ai/mastra/commit/932d63dd51be9c8bf1e00e3671fe65606c6fb9cd))
247
+ const observability = await storage.getStore('observability');
248
+ await observability?.createSpan(span);
249
+ ```
223
250
 
224
- Fixes #11005
251
+ ### Available Domains
252
+ - **`memory`**: Thread and message operations (`getThreadById`, `saveThread`, `saveMessages`, etc.)
253
+ - **`workflows`**: Workflow state persistence (`persistWorkflowSnapshot`, `loadWorkflowSnapshot`, `getWorkflowRunById`, etc.)
254
+ - **`scores`**: Evaluation scores (`saveScore`, `listScoresByScorerId`, etc.)
255
+ - **`observability`**: Tracing and spans (`createSpan`, `updateSpan`, `getTrace`, etc.)
256
+ - **`agents`**: Stored agent configurations (`createAgent`, `getAgentById`, `listAgents`, etc.)
225
257
 
226
- - Fix HITL (Human-In-The-Loop) tool execution bug when mixing tools with and without execute functions. ([#11178](https://github.com/mastra-ai/mastra/pull/11178))
258
+ ### Breaking Changes
259
+ - Passthrough methods have been removed from `MastraStorage` base class
260
+ - All storage adapters now require accessing domains via `getStore()`
261
+ - The `stores` property on storage instances is now the canonical way to access domain storage
227
262
 
228
- When an agent called multiple tools simultaneously where some had `execute` functions and others didn't (HITL tools expecting `addToolResult` from the frontend), the HITL tools would incorrectly receive `result: undefined` and be marked as "output-available" instead of "input-available". This caused the agent to continue instead of pausing for user input.
263
+ ### Internal Changes
264
+ - Each storage adapter now initializes domain-specific stores in its constructor
265
+ - Domain stores share database connections and handle their own table initialization
229
266
 
230
- - Add resourceId to workflow routes ([#11166](https://github.com/mastra-ai/mastra/pull/11166))
267
+ - Add support for AI SDK v6 ToolLoopAgent in Mastra ([#11254](https://github.com/mastra-ai/mastra/pull/11254))
231
268
 
232
- - Auto resume suspended tools if `autoResumeSuspendedTools: true` ([#11157](https://github.com/mastra-ai/mastra/pull/11157))
269
+ You can now pass an AI SDK v6 `ToolLoopAgent` directly to Mastra's agents configuration. The agent will be automatically converted to a Mastra Agent while preserving all ToolLoopAgent lifecycle hooks:
270
+ - `prepareCall` - Called once at the start of generate/stream
271
+ - `prepareStep` - Called before each step in the agentic loop
272
+ - `stopWhen` - Custom stop conditions for the loop
233
273
 
234
- The flag can be added to `defaultAgentOptions` when creating the agent or to options in `agent.stream` or `agent.generate`
274
+ Example:
235
275
 
236
276
  ```typescript
237
- const agent = new Agent({
238
- //...agent information,
239
- defaultAgentOptions: {
240
- autoResumeSuspendedTools: true,
277
+ import { ToolLoopAgent } from 'ai';
278
+ import { Mastra } from '@mastra/core/mastra';
279
+
280
+ const toolLoopAgent = new ToolLoopAgent({
281
+ model: openai('gpt-4o'),
282
+ instructions: 'You are a helpful assistant.',
283
+ tools: { weather: weatherTool },
284
+ prepareStep: async ({ stepNumber }) => {
285
+ if (stepNumber === 0) {
286
+ return { toolChoice: 'required' };
287
+ }
241
288
  },
242
289
  });
243
- ```
244
-
245
- - Preserve error details when thrown from workflow steps ([#10992](https://github.com/mastra-ai/mastra/pull/10992))
246
- - Errors thrown in workflow steps now preserve full error details including `cause` chain and custom properties
247
- - Added `SerializedError` type with proper cause chain support
248
- - Added `SerializedStepResult` and `SerializedStepFailure` types for handling errors loaded from storage
249
- - Enhanced `addErrorToJSON` to recursively serialize error cause chains with max depth protection
250
- - Added `hydrateSerializedStepErrors` to convert serialized errors back to Error instances
251
- - Fixed Inngest workflow error handling to extract original error from `NonRetriableError.cause`
252
-
253
- - Move `@ai-sdk/azure` to devDependencies ([#10218](https://github.com/mastra-ai/mastra/pull/10218))
254
-
255
- - Refactor internal event system from Emitter to PubSub abstraction for workflow event handling. This change replaces the EventEmitter-based event system with a pluggable PubSub interface, enabling support for distributed workflow execution backends like Inngest. Adds `close()` method to PubSub implementations for proper cleanup. ([#11052](https://github.com/mastra-ai/mastra/pull/11052))
256
-
257
- - Add `startAsync()` method and fix Inngest duplicate workflow execution bug ([#11093](https://github.com/mastra-ai/mastra/pull/11093))
258
290
 
259
- **New Feature: `startAsync()` for fire-and-forget workflow execution**
260
- - Add `Run.startAsync()` to base workflow class - starts workflow in background and returns `{ runId }` immediately
261
- - Add `EventedRun.startAsync()` - publishes workflow start event without subscribing for completion
262
- - Add `InngestRun.startAsync()` - sends Inngest event without polling for result
291
+ const mastra = new Mastra({
292
+ agents: { toolLoopAgent },
293
+ });
263
294
 
264
- **Bug Fix: Prevent duplicate Inngest workflow executions**
265
- - Fix `getRuns()` to properly handle rate limits (429), empty responses, and JSON parse errors with retry logic and exponential backoff
266
- - Fix `getRunOutput()` to throw `NonRetriableError` when polling fails, preventing Inngest from retrying the parent function and re-triggering the workflow
267
- - Add timeout to `getRunOutput()` polling (default 5 minutes) with `NonRetriableError` on timeout
295
+ // Use like any other Mastra agent
296
+ const agent = mastra.getAgent('toolLoopAgent');
297
+ const result = await agent.generate('What is the weather?');
298
+ ```
268
299
 
269
- This fixes a production issue where polling failures after successful workflow completion caused Inngest to retry the parent function, which fired a new workflow event and resulted in duplicate executions (e.g., duplicate Slack messages).
300
+ - Unified observability schema with entity-based span identification ([#11132](https://github.com/mastra-ai/mastra/pull/11132))
270
301
 
271
- - Preserve error details when thrown from workflow steps ([#10992](https://github.com/mastra-ai/mastra/pull/10992))
302
+ ## What changed
272
303
 
273
- Workflow errors now retain custom properties like `statusCode`, `responseHeaders`, and `cause` chains. This enables error-specific recovery logic in your applications.
304
+ Spans now use a unified identification model with `entityId`, `entityType`, and `entityName` instead of separate `agentId`, `toolId`, `workflowId` fields.
274
305
 
275
306
  **Before:**
276
307
 
277
308
  ```typescript
278
- const result = await workflow.execute({ input });
279
- if (result.status === 'failed') {
280
- // Custom error properties were lost
281
- console.log(result.error); // "Step execution failed" (just a string)
282
- }
309
+ // Old span structure
310
+ span.agentId; // 'my-agent'
311
+ span.toolId; // undefined
312
+ span.workflowId; // undefined
283
313
  ```
284
314
 
285
315
  **After:**
286
316
 
287
317
  ```typescript
288
- const result = await workflow.execute({ input });
289
- if (result.status === 'failed') {
290
- // Custom properties are preserved
291
- console.log(result.error.message); // "Step execution failed"
292
- console.log(result.error.statusCode); // 429
293
- console.log(result.error.cause?.name); // "RateLimitError"
294
- }
318
+ // New span structure
319
+ span.entityType; // EntityType.AGENT
320
+ span.entityId; // 'my-agent'
321
+ span.entityName; // 'My Agent'
295
322
  ```
296
323
 
297
- **Type change:** `WorkflowState.error` and `WorkflowRunState.error` types changed from `string | Error` to `SerializedError`.
324
+ ## New `listTraces()` API
298
325
 
299
- Other changes:
300
- - Added `UpdateWorkflowStateOptions` type for workflow state updates
326
+ Query traces with filtering, pagination, and sorting:
301
327
 
302
- - Fix Zod 4 compatibility issue with structuredOutput in agent.generate() ([#11133](https://github.com/mastra-ai/mastra/pull/11133))
303
-
304
- Users with Zod 4 installed would see `TypeError: undefined is not an object (evaluating 'def.valueType._zod')` when using `structuredOutput` with agent.generate(). This happened because ProcessorStepSchema contains `z.custom()` fields that hold user-provided Zod schemas, and the workflow validation was trying to deeply validate these schemas causing version conflicts.
305
-
306
- The fix disables input validation for processor workflows since `z.custom()` fields are meant to pass through arbitrary types without deep validation.
307
-
308
- - Truncate map config when too long ([#11175](https://github.com/mastra-ai/mastra/pull/11175))
309
-
310
- - Add helpful JSDoc comments to `BundlerConfig` properties (used with `bundler` option) ([#10218](https://github.com/mastra-ai/mastra/pull/10218))
311
-
312
- - Fixes .network() method ignores MASTRA_RESOURCE_ID_KEY from requestContext ([`4524734`](https://github.com/mastra-ai/mastra/commit/45247343e384717a7c8404296275c56201d6470f))
313
-
314
- - fix: make getSqlType consistent across storage adapters ([#11112](https://github.com/mastra-ai/mastra/pull/11112))
315
- - PostgreSQL: use `getSqlType()` in `createTable` instead of `toUpperCase()`
316
- - LibSQL: use `getSqlType()` in `createTable`, return `JSONB` for jsonb type (matches SQLite 3.45+ support)
317
- - ClickHouse: use `getSqlType()` in `createTable` instead of `COLUMN_TYPES` constant, add missing types (uuid, float, boolean)
318
- - Remove unused `getSqlType()` and `getDefaultValue()` from `MastraStorage` base class (all stores use `StoreOperations` versions)
319
-
320
- - Fix workflow cancel not updating status when workflow is suspended ([#11139](https://github.com/mastra-ai/mastra/pull/11139))
321
- - `Run.cancel()` now updates workflow status to 'canceled' in storage, resolving the issue where suspended workflows remained in 'suspended' status after cancellation
322
- - Cancellation status is immediately persisted and reflected to observers
328
+ ```typescript
329
+ const { spans, pagination } = await storage.listTraces({
330
+ filters: {
331
+ entityType: EntityType.AGENT,
332
+ entityId: 'my-agent',
333
+ userId: 'user-123',
334
+ environment: 'production',
335
+ status: TraceStatus.SUCCESS,
336
+ startedAt: { start: new Date('2024-01-01'), end: new Date('2024-01-31') },
337
+ },
338
+ pagination: { page: 0, perPage: 50 },
339
+ orderBy: { field: 'startedAt', direction: 'DESC' },
340
+ });
341
+ ```
323
342
 
324
- - What changed: ([#10998](https://github.com/mastra-ai/mastra/pull/10998))
343
+ **Available filters:** date ranges (`startedAt`, `endedAt`), entity (`entityType`, `entityId`, `entityName`), identity (`userId`, `organizationId`), correlation IDs (`runId`, `sessionId`, `threadId`), deployment (`environment`, `source`, `serviceName`), `tags`, `metadata`, and `status`.
325
344
 
326
- Support for sequential tool execution was added. Tool call concurrency is now set conditionally, defaulting to 1 when sequential execution is needed (to avoid race conditions that interfere with human-in-the-loop approval during the workflow) rather than the default of 10 when concurrency is acceptable.
345
+ ## New retrieval methods
346
+ - `getSpan({ traceId, spanId })` - Get a single span
347
+ - `getRootSpan({ traceId })` - Get the root span of a trace
348
+ - `getTrace({ traceId })` - Get all spans for a trace
327
349
 
328
- How it was changed:
350
+ ## Backward compatibility
329
351
 
330
- A `sequentialExecutionRequired` constant was set to a boolean depending on whether any of the tools involved in a returned agentic execution workflow would require approval. If any tool has a 'suspendSchema' property (used for conditionally suspending execution and waiting for human input), or if they have their `requireApproval` property set to `true`, then the concurrency property used in the toolCallStep is set to 1, causing sequential execution. The old default of 10 remains otherwise.
352
+ The legacy `getTraces()` method continues to work. When you pass `name: "agent run: my-agent"`, it automatically transforms to `entityId: "my-agent", entityType: AGENT`.
331
353
 
332
- - Fixed duplicate assistant messages appearing when using `useChat` with memory enabled. ([#11195](https://github.com/mastra-ai/mastra/pull/11195))
354
+ ## Migration
333
355
 
334
- **What was happening:** When using `useChat` with `chatRoute` and memory, assistant messages were being duplicated in storage after multiple conversation turns. This occurred because the backend-generated message ID wasn't being sent back to `useChat`, causing ID mismatches during deduplication.
356
+ **Automatic:** SQL-based stores (PostgreSQL, LibSQL, MSSQL) automatically add new columns to existing `spans` tables on initialization. Existing data is preserved with new columns set to `NULL`.
335
357
 
336
- **What changed:**
337
- - The backend now sends the assistant message ID in the stream's start event, so `useChat` uses the same ID as storage
338
- - Custom `data-*` parts (from `writer.custom()`) are now preserved when messages contain V5 tool parts
358
+ **No action required:** Your existing code continues to work. Adopt the new fields and `listTraces()` API at your convenience.
339
359
 
340
- Fixes #11091
360
+ ### Patch Changes
341
361
 
342
- - Updated dependencies [[`9650cce`](https://github.com/mastra-ai/mastra/commit/9650cce52a1d917ff9114653398e2a0f5c3ba808), [`5a632bd`](https://github.com/mastra-ai/mastra/commit/5a632bdf7b78953b664f5e038e98d4ba5f971e47)]:
343
- - @mastra/schema-compat@1.0.0-beta.3
344
- - @mastra/observability@1.0.0-beta.5
362
+ - When calling `abort()` inside a `processInputStep` processor, the TripWire was being caught by the model retry logic instead of emitting a tripwire chunk to the stream. ([#11343](https://github.com/mastra-ai/mastra/pull/11343))
345
363
 
346
- ## 1.0.0-beta.11
364
+ Before this fix, processors using `processInputStep` with abort would see errors like:
347
365
 
348
- ### Minor Changes
366
+ ```
367
+ Error executing model gpt-4o-mini, attempt 1==== TripWire [Error]: Potentially harmful content detected
368
+ ```
349
369
 
350
- - Respect structured outputs for v2 models so tool schemas aren’t stripped ([#11038](https://github.com/mastra-ai/mastra/pull/11038))
370
+ Now the TripWire is properly handled - it emits a tripwire chunk and signals the abort correctly,
351
371
 
352
- ### Patch Changes
372
+ - Consolidate memory integration tests and fix working memory filtering in MessageHistory processor ([#11367](https://github.com/mastra-ai/mastra/pull/11367))
353
373
 
354
- - Fix type safety for message ordering - restrict `orderBy` to only accept `'createdAt'` field ([#11069](https://github.com/mastra-ai/mastra/pull/11069))
374
+ Moved `extractWorkingMemoryTags`, `removeWorkingMemoryTags`, and `extractWorkingMemoryContent` utilities from `@mastra/memory` to `@mastra/core/memory` so they can be used by the `MessageHistory` processor.
355
375
 
356
- Messages don't have an `updatedAt` field, but the previous type allowed ordering by it, which would return empty results. This change adds compile-time type safety by making `StorageOrderBy` generic and restricting `StorageListMessagesInput.orderBy` to only accept `'createdAt'`. The API validation schemas have also been updated to reject invalid orderBy values at runtime.
376
+ Updated `MessageHistory.filterMessagesForPersistence()` to properly filter out `updateWorkingMemory` tool invocations and strip working memory tags from text content, fixing an issue where working memory tool call arguments were polluting saved message history for v5+ models.
357
377
 
358
- - Loosen tools types in processInputStep / prepareStep. ([#11071](https://github.com/mastra-ai/mastra/pull/11071))
378
+ Also consolidated integration tests for agent-memory, working-memory, and pg-storage into shared test functions that can run against multiple model versions (v4, v5, v6).
359
379
 
360
- - Added the ability to provide a base path for Mastra Studio. ([#10441](https://github.com/mastra-ai/mastra/pull/10441))
380
+ - Add support for AI SDK's `needsApproval` in tools. ([#11388](https://github.com/mastra-ai/mastra/pull/11388))
361
381
 
362
- ```ts
363
- import { Mastra } from '@mastra/core';
382
+ **AI SDK tools with static approval:**
364
383
 
365
- export const mastra = new Mastra({
366
- server: {
367
- studioBase: '/my-mastra-studio',
384
+ ```typescript
385
+ import { tool } from 'ai';
386
+ import { z } from 'zod';
387
+
388
+ const weatherTool = tool({
389
+ description: 'Get weather information',
390
+ inputSchema: z.object({ city: z.string() }),
391
+ needsApproval: true,
392
+ execute: async ({ city }) => {
393
+ return { weather: 'sunny', temp: 72 };
368
394
  },
369
395
  });
370
396
  ```
371
397
 
372
- This will make Mastra Studio available at `http://localhost:4111/my-mastra-studio`.
373
-
374
- - Expand `processInputStep` processor method and integrate `prepareStep` as a processor ([#10774](https://github.com/mastra-ai/mastra/pull/10774))
375
-
376
- **New Features:**
377
- - `prepareStep` callback now runs through the standard `processInputStep` pipeline
378
- - Processors can now modify per-step: `model`, `tools`, `toolChoice`, `activeTools`, `messages`, `systemMessages`, `providerOptions`, `modelSettings`, and `structuredOutput`
379
- - Processor chaining: each processor receives accumulated state from previous processors
380
- - System messages are isolated per-step (reset at start of each step)
381
-
382
- **Breaking Change:**
383
- - `prepareStep` messages format changed from AI SDK v5 model messages to `MastraDBMessage` format
384
- - Migration: Use `messageList.get.all.aiV5.model()` if you need the old format
398
+ **AI SDK tools with dynamic approval:**
385
399
 
386
- - Multiple Processor improvements including: ([#10947](https://github.com/mastra-ai/mastra/pull/10947))
387
- - Workflows can now return tripwires, they bubble up from agents that return tripwires in a step
388
- - You can write processors as workflows using the existing Workflow primitive, every processor flow is now a workflow.
389
- - tripwires that you throw can now return additional information including ability to retry the step
390
- - New processor method `processOutputStep` added which runs after every step.
391
-
392
- **What's new:**
400
+ ```typescript
401
+ const paymentTool = tool({
402
+ description: 'Process payment',
403
+ inputSchema: z.object({ amount: z.number() }),
404
+ needsApproval: async ({ amount }) => amount > 1000,
405
+ execute: async ({ amount }) => {
406
+ return { success: true, amount };
407
+ },
408
+ });
409
+ ```
393
410
 
394
- **1. Retry mechanism with LLM feedback** - Processors can now request retries with feedback that gets sent back to the LLM:
411
+ **Mastra tools continue to work with `requireApproval`:**
395
412
 
396
413
  ```typescript
397
- processOutputStep: async ({ text, abort, retryCount }) => {
398
- if (isLowQuality(text)) {
399
- abort('Response quality too low', { retry: true, metadata: { score: 0.6 } });
400
- }
401
- return [];
402
- };
414
+ import { createTool } from '@mastra/core';
415
+
416
+ const deleteTool = createTool({
417
+ id: 'delete-file',
418
+ description: 'Delete a file',
419
+ requireApproval: true,
420
+ inputSchema: z.object({ path: z.string() }),
421
+ execute: async ({ path }) => {
422
+ return { deleted: true };
423
+ },
424
+ });
403
425
  ```
404
426
 
405
- Configure with `maxProcessorRetries` (default: 3). Rejected steps are preserved in `result.steps[n].tripwire`. Retries are only available in `processOutputStep` and `processInputStep`. It will replay the step with additional context added.
427
+ - Fix stopWhen type to accept AI SDK v6 StopCondition functions like `stepCountIs()` ([#11402](https://github.com/mastra-ai/mastra/pull/11402))
406
428
 
407
- **2. Workflow orchestration for processors** - Processors can now be composed using workflow primitives:
429
+ - Fix missing `title` field in Convex threads table schema ([#11356](https://github.com/mastra-ai/mastra/pull/11356))
408
430
 
409
- ```typescript
410
- import { createStep, createWorkflow } from '@mastra/core/workflows';
411
- import {
412
- ProcessorStepSchema,
413
- } from '@mastra/core/processors';
431
+ The Convex schema was hardcoded and out of sync with the core `TABLE_SCHEMAS`, causing errors when creating threads:
414
432
 
415
- const moderationWorkflow = createWorkflow({ id: 'moderation', inputSchema: ProcessorStepSchema, outputSchema: ProcessorStepSchema })
416
- .then(createStep(new lengthValidator({...})))
417
- .parallel([createStep(new piiDetector({...}), createStep(new toxicityChecker({...}))])
418
- .commit();
419
-
420
- const agent = new Agent({ inputProcessors: [moderationWorkflow] });
433
+ ```
434
+ Error: Failed to insert or update a document in table "mastra_threads"
435
+ because it does not match the schema: Object contains extra field `title`
436
+ that is not in the validator.
421
437
  ```
422
438
 
423
- Every processor array that gets passed to an agent gets added as a workflow
424
- <img width="614" height="673" alt="image" src="https://github.com/user-attachments/assets/0d79f1fd-8fca-4d86-8b45-22fddea984a8" />
425
-
426
- **3. Extended tripwire API** - `abort()` now accepts options for retry control and typed metadata:
439
+ Now the Convex schema dynamically builds from `TABLE_SCHEMAS` via a new `@mastra/core/storage/constants` export path that doesn't pull in Node.js dependencies (safe for Convex's sandboxed schema evaluation).
427
440
 
428
441
  ```typescript
429
- abort('reason', { retry: true, metadata: { score: 0.8, category: 'quality' } });
442
+ // Users can now import schema tables without Node.js dependency issues
443
+ import { mastraThreadsTable, mastraMessagesTable } from '@mastra/convex/schema';
444
+
445
+ export default defineSchema({
446
+ mastra_threads: mastraThreadsTable,
447
+ mastra_messages: mastraMessagesTable,
448
+ });
430
449
  ```
431
450
 
432
- **4. New `processOutputStep` method** - Per-step output processing with access to step number, finish reason, tool calls, and retry count.
451
+ Fixes #11319
433
452
 
434
- **5. Workflow tripwire status** - Workflows now have a `'tripwire'` status distinct from `'failed'`, properly bubbling up processor rejections.
453
+ - Added support for AI SDK v6 embedding models (specification version v3) in memory and vector modules. Fixed TypeScript error where `ModelRouterEmbeddingModel` was trying to implement a union type instead of `EmbeddingModelV2` directly. ([#11362](https://github.com/mastra-ai/mastra/pull/11362))
435
454
 
436
- ## 1.0.0-beta.10
455
+ - fix: support gs:// and s3:// cloud storage URLs in attachmentsToParts ([#11398](https://github.com/mastra-ai/mastra/pull/11398))
437
456
 
438
- ### Patch Changes
457
+ - Add validation to detect when a function is passed as a tool instead of a tool object. Previously, passing a tool factory function (e.g., `tools: { myTool }` instead of `tools: { myTool: myTool() }`) would silently fail - the LLM would request tool calls but nothing would execute. Now throws a clear error with guidance on how to fix it. ([#11288](https://github.com/mastra-ai/mastra/pull/11288))
439
458
 
440
- - Add support for typed structured output in agent workflow steps ([#11014](https://github.com/mastra-ai/mastra/pull/11014))
459
+ - Fix reasoning providerMetadata leaking into text parts when using memory with OpenAI reasoning models. The runState.providerOptions is now cleared after reasoning-end to prevent text parts from inheriting the reasoning's itemId. ([#11380](https://github.com/mastra-ai/mastra/pull/11380))
441
460
 
442
- When wrapping an agent with `createStep()` and providing a `structuredOutput.schema`, the step's `outputSchema` is now correctly inferred from the provided schema instead of defaulting to `{ text: string }`.
461
+ - Upgrade AI SDK v6 from beta to stable (6.0.1) and fix finishReason breaking change. ([#11351](https://github.com/mastra-ai/mastra/pull/11351))
443
462
 
444
- This enables type-safe chaining of agent steps with structured output to subsequent steps:
463
+ AI SDK v6 stable changed finishReason from a string to an object with `unified` and `raw` properties. Added `normalizeFinishReason()` helper to handle both v5 (string) and v6 (object) formats at the stream transform layer
445
464
 
446
- ```typescript
447
- const articleSchema = z.object({
448
- title: z.string(),
449
- summary: z.string(),
450
- tags: z.array(z.string()),
451
- });
465
+ - Improve autoResumeSuspendedTools instruction for tool approval ([#11338](https://github.com/mastra-ai/mastra/pull/11338))
452
466
 
453
- // Agent step with structured output - outputSchema is now articleSchema
454
- const agentStep = createStep(agent, {
455
- structuredOutput: { schema: articleSchema },
456
- });
467
+ - Add debugger-like click-through UI to workflow graph ([#11350](https://github.com/mastra-ai/mastra/pull/11350))
457
468
 
458
- // Next step can receive the structured output directly
459
- const processStep = createStep({
460
- id: 'process',
461
- inputSchema: articleSchema, // Matches agent's outputSchema
462
- outputSchema: z.object({ tagCount: z.number() }),
463
- execute: async ({ inputData }) => ({
464
- tagCount: inputData.tags.length, // Fully typed!
465
- }),
466
- });
469
+ - Add `perStep` option to workflow run methods, allowing a workflow to run just a step instead of all the workflow steps ([#11276](https://github.com/mastra-ai/mastra/pull/11276))
467
470
 
468
- workflow.then(agentStep).then(processStep).commit();
469
- ```
471
+ - Fix workflow throwing error when using .map after .foreach ([#11352](https://github.com/mastra-ai/mastra/pull/11352))
470
472
 
471
- When `structuredOutput` is not provided, the agent step continues to use the default `{ text: string }` output schema.
473
+ - Bump @ai-sdk/openai from 3.0.0-beta.102 to 3.0.1 ([#11377](https://github.com/mastra-ai/mastra/pull/11377))
472
474
 
473
- - Fixed a bug where multiple tools streaming output simultaneously could fail with "WritableStreamDefaultWriter is locked" errors. Tool streaming now works reliably during concurrent tool executions. ([#10830](https://github.com/mastra-ai/mastra/pull/10830))
475
+ ## 1.0.0-beta.14
474
476
 
475
- - Add delete workflow run API ([#10991](https://github.com/mastra-ai/mastra/pull/10991))
477
+ ### Minor Changes
476
478
 
477
- ```typescript
478
- await workflow.deleteWorkflowRunById(runId);
479
- ```
479
+ - Add support for AI SDK v6 (LanguageModelV3) ([#11191](https://github.com/mastra-ai/mastra/pull/11191))
480
480
 
481
- - Fixed CachedToken tracking in all Observability Exporters. Also fixed TimeToFirstToken in Langfuse, Braintrust, PostHog exporters. Fixed trace formatting in Posthog Exporter. ([#11029](https://github.com/mastra-ai/mastra/pull/11029))
481
+ Agents can now use `LanguageModelV3` models from AI SDK v6 beta providers like `@ai-sdk/openai@^3.0.0-beta`.
482
482
 
483
- - fix: persist data-\* chunks from writer.custom() to memory storage ([#10884](https://github.com/mastra-ai/mastra/pull/10884))
484
- - Add persistence for custom data chunks (`data-*` parts) emitted via `writer.custom()` in tools
485
- - Data chunks are now saved to message storage so they survive page refreshes
486
- - Update `@assistant-ui/react` to v0.11.47 with native `DataMessagePart` support
487
- - Convert `data-*` parts to `DataMessagePart` format (`{ type: 'data', name: string, data: T }`)
488
- - Update related `@assistant-ui/*` packages for compatibility
483
+ **New features:**
484
+ - Usage normalization: V3's nested usage format is normalized to Mastra's flat format with `reasoningTokens`, `cachedInputTokens`, and raw data preserved in a `raw` field
489
485
 
490
- - Fixed double validation bug that prevented Zod transforms from working correctly in tool schemas. ([#11025](https://github.com/mastra-ai/mastra/pull/11025))
486
+ **Backward compatible:** All existing V1 and V2 models continue to work unchanged.
491
487
 
492
- When tools with Zod `.transform()` or `.pipe()` in their `outputSchema` were executed through the Agent pipeline, validation was happening twice - once in Tool.execute() (correct) and again in CoreToolBuilder (incorrect). The second validation received already-transformed data but expected pre-transform data, causing validation errors.
488
+ ### Patch Changes
493
489
 
494
- This fix enables proper use of Zod transforms in both `inputSchema` (for normalizing/cleaning input data) and `outputSchema` (for transforming output data to be LLM-friendly).
490
+ - Fix model-level and runtime header support for LLM calls ([#11275](https://github.com/mastra-ai/mastra/pull/11275))
491
+
492
+ This fixes a bug where custom headers configured on models (like `anthropic-beta`) were not being passed through to the underlying AI SDK calls. The fix properly handles headers from multiple sources with correct priority:
495
493
 
496
- - Updated dependencies [[`5d7000f`](https://github.com/mastra-ai/mastra/commit/5d7000f757cd65ea9dc5b05e662fd83dfd44e932)]:
497
- - @mastra/observability@1.0.0-beta.4
494
+ **Header Priority (low to high):**
495
+ 1. Model config headers - Headers set in model configuration
496
+ 2. ModelSettings headers - Runtime headers that override model config
497
+ 3. Provider-level headers - Headers baked into AI SDK providers (not overridden)
498
498
 
499
- ## 1.0.0-beta.9
499
+ **Examples that now work:**
500
500
 
501
501
 
502
- ... 6489 more lines hidden. See full changelog in package directory.
502
+ ... 6961 more lines hidden. See full changelog in package directory.