@mastra/client-js 1.40.1-alpha.7 → 1.41.0-alpha.11

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/CHANGELOG.md CHANGED
@@ -1,5 +1,86 @@
1
1
  # @mastra/client-js
2
2
 
3
+ ## 1.41.0-alpha.11
4
+
5
+ ### Minor Changes
6
+
7
+ - Added a `durable` option to stored agents so agents created through the Agents API can run with durable execution — no code deployment required. ([#21715](https://github.com/mastra-ai/mastra/pull/21715))
8
+
9
+ ```typescript
10
+ await mastraClient.createStoredAgent({
11
+ id: 'helper',
12
+ name: 'Helper',
13
+ instructions: 'You are a helpful assistant.',
14
+ model: { provider: 'openai', name: 'gpt-5' },
15
+ durable: true,
16
+ });
17
+ ```
18
+
19
+ Pass `true` for defaults, or `{ maxSteps, cleanupTimeoutMs }` to tune the durable loop. Cache and pubsub are inherited from the server's Mastra instance, so configure distributed backends there for durability across replicas. Automatic recovery is still configured in code via `recovery.durableAgents`.
20
+
21
+ - Fixed the agent controller event types, which described payloads the server never sends. ([#21739](https://github.com/mastra-ai/mastra/pull/21739))
22
+
23
+ `KnownAgentControllerEvent` was written by hand and had drifted from the controller. Narrowing on `om_activation` gave you an `enabled` boolean that does not exist, `om_status` a `status` string instead of the token windows, `om_thread_title_updated` a `title` instead of `newTitle`, and `subagent_end` only a `toolCallId` — its `agentType`, `result`, `isError` and `durationMs` were missing. `usage_update` typed its payload as `unknown`, so every consumer cast it. Seven events the controller emits (`state_changed`, `command_exit`, `tool_suspension_cancelled`, and the four remaining `subagent_*` events) were not typed at all and fell through `isKnownAgentControllerEvent`.
24
+
25
+ `isKnownAgentControllerEvent` now returns `true` for those seven events as well. If you route unrecognised events to a fallback branch, they no longer reach it — give them a case in your `switch` or they are silently dropped.
26
+
27
+ `thread_created` now delivers `thread.createdAt` and `thread.updatedAt` as `Date`s, the way the `message_*` events already did — the stream carries them as ISO strings.
28
+
29
+ Payload drift is now a compile error instead of a wrong field at runtime, so handlers reading the old fields need updating.
30
+
31
+ ```ts
32
+ // Before: compiled, but `enabled` is always undefined
33
+ if (event.type === 'om_activation' && event.enabled) { ... }
34
+
35
+ // After: tsc rejects it; the event carries cycleId, tokensActivated, generationCount, …
36
+ if (event.type === 'om_activation') { console.log(event.tokensActivated) }
37
+ ```
38
+
39
+ ### Patch Changes
40
+
41
+ - Updated dependencies [[`6223446`](https://github.com/mastra-ai/mastra/commit/6223446ddce6166e96e0ba5e00d628b615dee8ca), [`583e235`](https://github.com/mastra-ai/mastra/commit/583e23519c13af16c1746f9c49722d011216611b), [`a77f8d4`](https://github.com/mastra-ai/mastra/commit/a77f8d4740d2178a74c41e4bf678b4fcd8fa0bb2), [`40d358e`](https://github.com/mastra-ai/mastra/commit/40d358e29d55543803e64b49241122f598ffabc7), [`e80cd7e`](https://github.com/mastra-ai/mastra/commit/e80cd7e7683e7d732e1cc6784bcac1d2640d2ce3), [`20504b2`](https://github.com/mastra-ai/mastra/commit/20504b2ecebd0e077acda3d457ab57480a98ed3e)]:
42
+ - @mastra/core@1.60.0-alpha.11
43
+
44
+ ## 1.41.0-alpha.10
45
+
46
+ ### Patch Changes
47
+
48
+ - Updated dependencies [[`b860493`](https://github.com/mastra-ai/mastra/commit/b86049391100e665d579f700c8a2034c036defc3)]:
49
+ - @mastra/core@1.60.0-alpha.10
50
+
51
+ ## 1.41.0-alpha.9
52
+
53
+ ### Patch Changes
54
+
55
+ - Preserve tool-call `providerMetadata` at the message-part level during client-tool continuations. ([#21703](https://github.com/mastra-ai/mastra/pull/21703))
56
+
57
+ The stream reducers nested `providerMetadata` inside `toolInvocation`, but the server reads it from `part.providerMetadata` when rebuilding the prompt. As a result the metadata was dropped on the recursive request, and Gemini thinking models (e.g. `gemini-3-flash-preview`) failed the follow-up turn with `Function call is missing a thought_signature in functionCall parts`.
58
+
59
+ - Updated dependencies [[`b0a2a07`](https://github.com/mastra-ai/mastra/commit/b0a2a07800d42bd9823292e7db832374ed084c9c), [`ccbbcd9`](https://github.com/mastra-ai/mastra/commit/ccbbcd974eedff4367a54ed0e24c9ee742ab2f61), [`3f5c6f7`](https://github.com/mastra-ai/mastra/commit/3f5c6f728ea35da344248de9aa070f12849f3aa0), [`77e6b1b`](https://github.com/mastra-ai/mastra/commit/77e6b1bc4c46ce94fe501023fb4393c812ec6be3), [`2e1d098`](https://github.com/mastra-ai/mastra/commit/2e1d0984e325fd319d32ea182f596b3170be3847)]:
60
+ - @mastra/core@1.60.0-alpha.9
61
+
62
+ ## 1.41.0-alpha.8
63
+
64
+ ### Minor Changes
65
+
66
+ - Added `Agent.readPlan()` for loading submitted plan Markdown. ([#21658](https://github.com/mastra-ai/mastra/pull/21658))
67
+
68
+ ```ts
69
+ const agent = client.getAgent('agent-id');
70
+ const plan = await agent.readPlan('.mastracode/plans/add-dark-mode.md');
71
+ ```
72
+
73
+ ### Patch Changes
74
+
75
+ - `session.state()` now accepts a `threadId`, so reopening a chat can load the durable task list for that specific thread. ([#21545](https://github.com/mastra-ai/mastra/pull/21545))
76
+
77
+ ```ts
78
+ const state = await session.state({ threadId: 'thread-123' });
79
+ ```
80
+
81
+ - Updated dependencies [[`4e7a421`](https://github.com/mastra-ai/mastra/commit/4e7a421dce8a48742f785d1e93ad2f43a572b282), [`242e324`](https://github.com/mastra-ai/mastra/commit/242e3241e73cbd5c9bb86a31ebb49ca0256488d4), [`217e967`](https://github.com/mastra-ai/mastra/commit/217e9672d8b3160eb729d8e9f0044949e88da239), [`d774e89`](https://github.com/mastra-ai/mastra/commit/d774e8930c781df8c9effe3763e6b501c099b6cc), [`9c27a53`](https://github.com/mastra-ai/mastra/commit/9c27a53cd9d3de4f3f025bc387d94ce371c33f95), [`dff25a1`](https://github.com/mastra-ai/mastra/commit/dff25a1103fa72ee082a9b6f805ebeb5ce400753), [`217e967`](https://github.com/mastra-ai/mastra/commit/217e9672d8b3160eb729d8e9f0044949e88da239), [`7f78585`](https://github.com/mastra-ai/mastra/commit/7f785857e401570e2ffb316911f126ed363aa537), [`f2a4afd`](https://github.com/mastra-ai/mastra/commit/f2a4afd7e37e809669001ed17724b341a5c1f45e), [`d438148`](https://github.com/mastra-ai/mastra/commit/d438148e222c1e2fb3c652725ce75680962ebec4), [`ba05fe0`](https://github.com/mastra-ai/mastra/commit/ba05fe0738f70cb686777546e968237d09269142), [`d26a8d4`](https://github.com/mastra-ai/mastra/commit/d26a8d4281f28414715b333c85bedaf70d0b2890), [`677cdc6`](https://github.com/mastra-ai/mastra/commit/677cdc6af564dec29a13464d12b7ab2a4efc22e9), [`a318490`](https://github.com/mastra-ai/mastra/commit/a318490e17da32f338d50929c770d901a9b3dd72), [`763e0c6`](https://github.com/mastra-ai/mastra/commit/763e0c61e04d76ad9a9efd301aa57525ca0cbea9), [`23e0be2`](https://github.com/mastra-ai/mastra/commit/23e0be261381e49534b4ff3101c60ee64a946cbf), [`7fc8806`](https://github.com/mastra-ai/mastra/commit/7fc880627d3cbf995d31ea0e8b807bf15417e651), [`0e02eac`](https://github.com/mastra-ai/mastra/commit/0e02eacdb2e30e1697a41910b41163742a181dc1), [`4df174c`](https://github.com/mastra-ai/mastra/commit/4df174c32bddf093a82f273070b8380aef7c9e90), [`f7c25b5`](https://github.com/mastra-ai/mastra/commit/f7c25b5106ddfb48e591f98df7a51e0f2dd01dba), [`dc09cc1`](https://github.com/mastra-ai/mastra/commit/dc09cc1083d861cde192c1cd235324dc75b8c731), [`36b4649`](https://github.com/mastra-ai/mastra/commit/36b4649045a3a380cbab8ceca866db4086223aff), [`377eb81`](https://github.com/mastra-ai/mastra/commit/377eb81ce43b964e3a6b541df172da74a8ff3716)]:
82
+ - @mastra/core@1.60.0-alpha.8
83
+
3
84
  ## 1.40.1-alpha.7
4
85
 
5
86
  ### Patch Changes
@@ -3,7 +3,7 @@ name: mastra-client-js
3
3
  description: Documentation for @mastra/client-js. Use when working with @mastra/client-js APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/client-js"
6
- version: "1.40.1-alpha.7"
6
+ version: "1.41.0-alpha.11"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -16,12 +16,12 @@ Read the individual reference documents for detailed explanations and code examp
16
16
 
17
17
  ### Docs
18
18
 
19
- - [A2A (Agent-to-Agent)](references/docs-agents-a2a.md) - Expose and call remote Mastra agents over the Agent-to-Agent protocol.
20
- - [Editor](references/docs-editor-overview.md) - Let collaborators update an agent in Studio, test their changes, and publish without editing code.
21
- - [Schedules](references/docs-long-running-agents-schedules.md) - Run an agent on a cron schedule to deliver a recurring prompt, with optional thread delivery and lifecycle hooks.
22
- - [Signals](references/docs-long-running-agents-signals.md) - Learn how to send real-time messages and context into a Mastra agent thread.
23
- - [JSON Web Token](references/docs-server-auth-jwt.md) - Documentation for JSON Web Token usage inside Mastra.
19
+ - [JSON Web Token](references/docs-auth-jwt.md) - Documentation for JSON Web Token usage inside Mastra.
20
+ - [A2A (Agent-to-Agent)](references/docs-connections-a2a.md) - Expose and call remote Mastra agents over the Agent-to-Agent protocol.
21
+ - [Schedules](references/docs-harness-schedules.md) - Run an agent on a cron schedule to deliver a recurring prompt, with optional thread delivery and lifecycle hooks.
22
+ - [Signals](references/docs-harness-signals.md) - Learn how to send real-time messages and context into a Mastra agent thread.
24
23
  - [Mastra client](references/docs-server-mastra-client.md) - Learn how to set up and use the Mastra Client SDK
24
+ - [Editor](references/docs-studio-editor.md) - Let collaborators update an agent in Studio, test their changes, and publish without editing code.
25
25
 
26
26
  ### Integrations
27
27
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.40.1-alpha.7",
2
+ "version": "1.41.0-alpha.11",
3
3
  "package": "@mastra/client-js",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -80,7 +80,7 @@ Use `A2AAgent` when another Mastra agent should delegate work to a remote agent.
80
80
 
81
81
  ## Consume A2A agents as subagents
82
82
 
83
- Use `A2AAgent` to wrap a remote A2A agent, then add it to a parent agent with the [supervisor agents](https://mastra.ai/docs/capabilities/subagents) pattern. Pass an explicit agent card URL when the remote server hosts multiple agents or uses a custom well-known path.
83
+ Use `A2AAgent` to wrap a remote A2A agent, then add it to a parent agent with the [supervisor agents](https://mastra.ai/docs/subagents) pattern. Pass an explicit agent card URL when the remote server hosts multiple agents or uses a custom well-known path.
84
84
 
85
85
  ```typescript
86
86
  import { Agent } from '@mastra/core/agent'
@@ -221,7 +221,7 @@ A2A models human-in-the-loop (HITL) work with the `input-required` task state. W
221
221
 
222
222
  Mastra maps its agent suspension model to this state in both directions:
223
223
 
224
- - **As a server**: when an exposed agent suspends, the task transitions to `input-required`. This includes suspensions caused by [tool approval](https://mastra.ai/docs/agents/agent-approval) or a tool that calls `suspend()`. The task status message includes a text prompt and a data part with the structured `suspendPayload` and `resumeSchema`. A follow-up `message/send` or `message/stream` request with the same `taskId` resumes the suspended run with the provided input.
224
+ - **As a server**: when an exposed agent suspends, the task transitions to `input-required`. This includes suspensions caused by [tool approval](https://mastra.ai/docs/agents/human-in-the-loop) or a tool that calls `suspend()`. The task status message includes a text prompt and a data part with the structured `suspendPayload` and `resumeSchema`. A follow-up `message/send` or `message/stream` request with the same `taskId` resumes the suspended run with the provided input.
225
225
  - **As a client**: when a remote task reaches `input-required` or `auth-required`, `A2AAgent` returns a suspended result with `finishReason: 'suspended'` and a `suspendPayload`. Calling `resumeGenerate()` or `resumeStream()` sends the input or credentials back to the remote task with the original `taskId`.
226
226
 
227
227
  ```typescript
@@ -6,11 +6,11 @@
6
6
 
7
7
  > **Beta:** Breaking changes may occur without a major version bump until the API is stable.
8
8
 
9
- A schedule runs an agent on a cron cadence. On each fire, Mastra sends a prompt to the agent, either as a [signal](https://mastra.ai/docs/long-running-agents/signals) into a thread or as a threadless [`agent.generate()`](https://mastra.ai/reference/agents/generate) run. Use schedules for recurring agent work such as daily summaries, periodic checks, or scheduled nudges into a conversation.
9
+ A schedule runs an agent on a cron cadence. On each fire, Mastra sends a prompt to the agent, either as a [signal](https://mastra.ai/docs/harness/signals) into a thread or as a threadless [`agent.generate()`](https://mastra.ai/reference/agents/generate) run. Use schedules for recurring agent work such as daily summaries, periodic checks, or scheduled nudges into a conversation.
10
10
 
11
11
  Schedules are persisted, so they survive restarts and redeploys. Manage them at runtime through [`mastra.schedules`](https://mastra.ai/reference/schedules/overview), the canonical create, read, update, and delete (CRUD) surface. The same surface also manages [workflow schedules](https://mastra.ai/docs/workflows/scheduled-workflows) (pass `workflowId` instead of `agentId` to schedule a workflow).
12
12
 
13
- > **Note:** Schedules require a [storage](https://mastra.ai/docs/storage/overview) adapter that implements the schedules domain. See the [`mastra.schedules` reference](https://mastra.ai/reference/schedules/overview) for supported adapters and API behavior.
13
+ > **Note:** Schedules require a [storage](https://mastra.ai/docs/storage) adapter that implements the schedules domain. See the [`mastra.schedules` reference](https://mastra.ai/reference/schedules/overview) for supported adapters and API behavior.
14
14
 
15
15
  ## Quickstart
16
16
 
@@ -71,7 +71,7 @@ Without a `threadId`, each fire is an isolated `agent.generate()` run. Nothing i
71
71
 
72
72
  ### Threaded
73
73
 
74
- With a `threadId`, the schedule sends a [signal](https://mastra.ai/docs/long-running-agents/signals) into that thread, so the prompt joins the agent's conversation. Threaded schedules require a `resourceId` alongside the `threadId`.
74
+ With a `threadId`, the schedule sends a [signal](https://mastra.ai/docs/harness/signals) into that thread, so the prompt joins the agent's conversation. Threaded schedules require a `resourceId` alongside the `threadId`.
75
75
 
76
76
  ```typescript
77
77
  await mastra.schedules.create({
@@ -83,7 +83,7 @@ await mastra.schedules.create({
83
83
  })
84
84
  ```
85
85
 
86
- Threaded schedules accept extra fields that control how the signal behaves, including the signal type, XML tag, tag attributes, and active-or-idle delivery behavior. They mirror the options [`agent.sendSignal()`](https://mastra.ai/docs/long-running-agents/signals) accepts and stay JSON-serializable so they persist with the schedule.
86
+ Threaded schedules accept extra fields that control how the signal behaves, including the signal type, XML tag, tag attributes, and active-or-idle delivery behavior. They mirror the options [`agent.sendSignal()`](https://mastra.ai/docs/harness/signals) accepts and stay JSON-serializable so they persist with the schedule.
87
87
 
88
88
  These fields require a `threadId`. For the full threaded input shape, see the [agent schedule input reference](https://mastra.ai/reference/schedules/overview).
89
89
 
@@ -197,5 +197,5 @@ Hook exceptions are caught and logged. They never re-route the worker or trigger
197
197
  ## Related
198
198
 
199
199
  - [`mastra.schedules`](https://mastra.ai/reference/schedules/overview): API reference for creating and managing schedules.
200
- - [Signals](https://mastra.ai/docs/long-running-agents/signals): the delivery mechanism behind threaded schedules.
200
+ - [Signals](https://mastra.ai/docs/harness/signals): the delivery mechanism behind threaded schedules.
201
201
  - [Scheduled workflows](https://mastra.ai/docs/workflows/scheduled-workflows): declare a cron schedule on a workflow definition.
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Mastra client
4
4
 
5
- The Mastra Client SDK provides a concise and type-safe interface for interacting with your [Mastra Server](https://mastra.ai/docs/server/mastra-server) from your client environment.
5
+ The Mastra Client SDK provides a concise and type-safe interface for interacting with your [Mastra Server](https://mastra.ai/docs/server/overview) from your client environment.
6
6
 
7
7
  ## Prerequisites
8
8
 
@@ -59,7 +59,7 @@ export const mastraClient = new MastraClient({
59
59
  The Mastra Client SDK exposes all resources served by the Mastra Server.
60
60
 
61
61
  - **[Agents](https://mastra.ai/reference/client-js/agents)**: Generate responses and stream conversations.
62
- - **[A2A](https://mastra.ai/docs/agents/a2a)**: Discover agents through agent cards and work with task-based A2A streams.
62
+ - **[A2A](https://mastra.ai/docs/connections/a2a)**: Discover agents through agent cards and work with task-based A2A streams.
63
63
  - **[Memory](https://mastra.ai/reference/client-js/memory)**: Manage conversation threads and message history.
64
64
  - **[Tools](https://mastra.ai/reference/client-js/tools)**: Executed and managed tools.
65
65
  - **[Workflows](https://mastra.ai/reference/client-js/workflows)**: Trigger workflows and track their execution.
@@ -89,7 +89,7 @@ By default, `MastraAuthWorkos` grants access to any authenticated WorkOS user. T
89
89
 
90
90
  ### FGA membership loading
91
91
 
92
- Set `fetchMemberships: true` when you use [`MastraFGAWorkos`](https://mastra.ai/docs/server/auth/fga). This tells the auth provider to load the user's WorkOS organization memberships during authentication so FGA checks can resolve the correct organization membership ID.
92
+ Set `fetchMemberships: true` when you use [`MastraFGAWorkos`](https://mastra.ai/docs/auth/fga). This tells the auth provider to load the user's WorkOS organization memberships during authentication so FGA checks can resolve the correct organization membership ID.
93
93
 
94
94
  ```typescript
95
95
  import { MastraAuthWorkos, MastraFGAWorkos } from '@mastra/auth-workos'
@@ -285,7 +285,7 @@ await subscription.processDataStream({
285
285
 
286
286
  ### `streamUntilIdle()`
287
287
 
288
- Stream a response and keep the stream open until every [background task](https://mastra.ai/docs/long-running-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 uses a plain `stream()`.
288
+ Stream a response and keep the stream open until every [background task](https://mastra.ai/docs/harness/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 uses a plain `stream()`.
289
289
 
290
290
  ```typescript
291
291
  const response = await agent.streamUntilIdle('Research solana for me', {
@@ -307,7 +307,7 @@ response.processDataStream({
307
307
 
308
308
  ### `resumeStreamUntilIdle()`
309
309
 
310
- Resume a suspended agent stream with custom data and keep the stream open until every [background task](https://mastra.ai/docs/long-running-agents/background-tasks) dispatched during the run completes. Use this to continue execution after a suspension point, such as a workflow suspend within an agent. Requires background tasks to be [enabled on the Mastra instance](https://mastra.ai/reference/configuration) and a memory thread; otherwise the call uses a plain `resumeStream()`:
310
+ Resume a suspended agent stream with custom data and keep the stream open until every [background task](https://mastra.ai/docs/harness/background-tasks) dispatched during the run completes. Use this to continue execution after a suspension point, such as a workflow suspend within an agent. Requires background tasks to be [enabled on the Mastra instance](https://mastra.ai/reference/configuration) and a memory thread; otherwise the call uses a plain `resumeStream()`:
311
311
 
312
312
  ```typescript
313
313
  const response = await agent.resumeStreamUntilIdle(
@@ -497,7 +497,7 @@ if (output.finishReason === 'suspended') {
497
497
 
498
498
  ## Agent schedules
499
499
 
500
- Use the client SDK schedule methods to manage persisted agent schedules over the `/api/schedules` routes. For concepts and server-side examples, see [Schedules](https://mastra.ai/docs/long-running-agents/schedules) and the [`mastra.schedules` reference](https://mastra.ai/reference/schedules/overview).
500
+ Use the client SDK schedule methods to manage persisted agent schedules over the `/api/schedules` routes. For concepts and server-side examples, see [Schedules](https://mastra.ai/docs/harness/schedules) and the [`mastra.schedules` reference](https://mastra.ai/reference/schedules/overview).
501
501
 
502
502
  ### `createSchedule()`
503
503
 
@@ -778,9 +778,29 @@ const agent = await mastraClient.createStoredAgent({
778
778
  version: '1.0',
779
779
  team: 'engineering',
780
780
  },
781
+ durable: true,
781
782
  })
782
783
  ```
783
784
 
785
+ #### Durable stored agents
786
+
787
+ Set `durable` to run the agent as a [durable agent](https://mastra.ai/docs/harness/durable-agents) once the server hydrates it. Pass `true` to accept the defaults, or an object to tune the durable loop:
788
+
789
+ ```typescript
790
+ const agent = await mastraClient.createStoredAgent({
791
+ id: 'durable-agent',
792
+ name: 'Durable Agent',
793
+ instructions: 'You are a helpful assistant.',
794
+ model: {
795
+ provider: 'openai',
796
+ name: 'gpt-5.4',
797
+ },
798
+ durable: { maxSteps: 50, cleanupTimeoutMs: 0 },
799
+ })
800
+ ```
801
+
802
+ Only serializable options are accepted. The durable cache and pubsub are inherited from the server's `Mastra` instance. If it has no distributed cache or pubsub configured, durability is process-local. Automatic recovery is still configured in code through `recovery.durableAgents`.
803
+
784
804
  ### `getStoredAgent()`
785
805
 
786
806
  Get an instance of a specific stored agent:
@@ -839,7 +859,7 @@ console.log(result.success) // true
839
859
 
840
860
  ## Version management
841
861
 
842
- Both `Agent` (code-defined) and `StoredAgent` instances have methods for managing configuration versions. See [Editor versioning](https://mastra.ai/docs/editor/overview) for lifecycle and selection behavior.
862
+ Both `Agent` (code-defined) and `StoredAgent` instances have methods for managing configuration versions. See [Editor versioning](https://mastra.ai/docs/studio/editor) for lifecycle and selection behavior.
843
863
 
844
864
  ### Getting an agent with a specific version
845
865
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  Editor versions stored agents and prompt blocks. Database-backed resources use draft and publish operations. Code-backed agent overrides use deterministic files and Git history.
6
6
 
7
- See [Editor versioning](https://mastra.ai/docs/editor/overview) for release and experimentation patterns.
7
+ See [Editor versioning](https://mastra.ai/docs/studio/editor) for release and experimentation patterns.
8
8
 
9
9
  ## Database lifecycle
10
10
 
@@ -35,7 +35,7 @@ See [`MastraEditor`](https://mastra.ai/reference/editor/mastra-editor) for sourc
35
35
 
36
36
  ## Select an agent version
37
37
 
38
- Calling [`mastra.getAgentById()`](https://mastra.ai/reference/core/getAgentById) without a selector returns the registered code-defined agent. Pass `status` or `versionId` to apply a stored override. See [Select a version](https://mastra.ai/docs/editor/overview) for a TypeScript example.
38
+ Calling [`mastra.getAgentById()`](https://mastra.ai/reference/core/getAgentById) without a selector returns the registered code-defined agent. Pass `status` or `versionId` to apply a stored override. See [Select a version](https://mastra.ai/docs/studio/editor) for a TypeScript example.
39
39
 
40
40
  With the default server prefix, pass selectors as query parameters under `/api`:
41
41
 
@@ -54,7 +54,7 @@ See the [Client SDK agents reference](https://mastra.ai/reference/client-js/agen
54
54
 
55
55
  ## Sub-agent versioning
56
56
 
57
- Version overrides propagate through [supervisor-agent delegation](https://mastra.ai/docs/capabilities/subagents) in request context. Define selectors at three levels:
57
+ Version overrides propagate through [supervisor-agent delegation](https://mastra.ai/docs/subagents) in request context. Define selectors at three levels:
58
58
 
59
59
  1. `Mastra` instance `versions`: Defaults for every invocation
60
60
  2. Server request-body `versions`: Per-request values added to request context
package/dist/index.cjs CHANGED
@@ -884,6 +884,15 @@ var Agent = class extends BaseResource {
884
884
  return this.request(`/agents/${this.agentId}${this.getQueryString(requestContext)}`);
885
885
  }
886
886
  /**
887
+ * Reads a markdown plan submitted by this agent through the core submit_plan tool.
888
+ * The server only serves paths under `.mastracode/plans/` and only when the
889
+ * agent exposes that capability.
890
+ */
891
+ readPlan(path, requestContext) {
892
+ const contextQuery = this.getQueryString(requestContext, "&");
893
+ return this.request(`/agents/${this.agentId}/plans/file?path=${encodeURIComponent(path)}${contextQuery}`);
894
+ }
895
+ /**
887
896
  * Probe the agent's browser session state before opening a screencast WebSocket.
888
897
  *
889
898
  * Returns `{ hasSession, screencastAvailable }`. Use this to avoid opening a WS
@@ -1404,13 +1413,22 @@ var Agent = class extends BaseResource {
1404
1413
  let currentTextPart = void 0;
1405
1414
  let currentReasoningPart = void 0;
1406
1415
  let currentReasoningTextDetail = void 0;
1407
- function updateToolInvocationPart(toolCallId, invocation) {
1416
+ function updateToolInvocationPart(toolCallId, invocation, partProviderMetadata) {
1408
1417
  const part = message.parts.find((part) => part.type === "tool-invocation" && part.toolInvocation.toolCallId === toolCallId);
1409
- if (part != null) part.toolInvocation = invocation;
1410
- else message.parts.push({
1411
- type: "tool-invocation",
1412
- toolInvocation: invocation
1413
- });
1418
+ if (part != null) {
1419
+ part.toolInvocation = invocation;
1420
+ if (partProviderMetadata !== void 0) part.providerMetadata = {
1421
+ ...part.providerMetadata ?? {},
1422
+ ...partProviderMetadata
1423
+ };
1424
+ } else {
1425
+ const newPart = {
1426
+ type: "tool-invocation",
1427
+ toolInvocation: invocation
1428
+ };
1429
+ if (partProviderMetadata !== void 0) newPart.providerMetadata = partProviderMetadata;
1430
+ message.parts.push(newPart);
1431
+ }
1414
1432
  }
1415
1433
  const data = [];
1416
1434
  let messageAnnotations = replaceLastMessage ? lastMessage?.annotations : void 0;
@@ -1548,7 +1566,7 @@ var Agent = class extends BaseResource {
1548
1566
  if (message.toolInvocations == null) message.toolInvocations = [];
1549
1567
  message.toolInvocations.push(invocation);
1550
1568
  }
1551
- updateToolInvocationPart(value.toolCallId, invocation);
1569
+ updateToolInvocationPart(value.toolCallId, invocation, value.providerMetadata);
1552
1570
  execUpdate();
1553
1571
  if (onToolCall) {
1554
1572
  const result = await onToolCall({ toolCall: value });
@@ -1560,7 +1578,7 @@ var Agent = class extends BaseResource {
1560
1578
  result
1561
1579
  };
1562
1580
  message.toolInvocations[message.toolInvocations.length - 1] = invocation;
1563
- updateToolInvocationPart(value.toolCallId, invocation);
1581
+ updateToolInvocationPart(value.toolCallId, invocation, value.providerMetadata);
1564
1582
  execUpdate();
1565
1583
  }
1566
1584
  }
@@ -1576,7 +1594,7 @@ var Agent = class extends BaseResource {
1576
1594
  ...value
1577
1595
  };
1578
1596
  toolInvocations[toolInvocationIndex] = invocation;
1579
- updateToolInvocationPart(value.toolCallId, invocation);
1597
+ updateToolInvocationPart(value.toolCallId, invocation, value.providerMetadata);
1580
1598
  execUpdate();
1581
1599
  },
1582
1600
  onDataPart(value) {
@@ -1656,13 +1674,22 @@ var Agent = class extends BaseResource {
1656
1674
  let currentTextPart = void 0;
1657
1675
  let currentReasoningPart = void 0;
1658
1676
  let currentReasoningTextDetail = void 0;
1659
- function updateToolInvocationPart(toolCallId, invocation) {
1677
+ function updateToolInvocationPart(toolCallId, invocation, partProviderMetadata) {
1660
1678
  const part = message.parts.find((part) => part.type === "tool-invocation" && part.toolInvocation.toolCallId === toolCallId);
1661
- if (part != null) part.toolInvocation = invocation;
1662
- else message.parts.push({
1663
- type: "tool-invocation",
1664
- toolInvocation: invocation
1665
- });
1679
+ if (part != null) {
1680
+ part.toolInvocation = invocation;
1681
+ if (partProviderMetadata !== void 0) part.providerMetadata = {
1682
+ ...part.providerMetadata ?? {},
1683
+ ...partProviderMetadata
1684
+ };
1685
+ } else {
1686
+ const newPart = {
1687
+ type: "tool-invocation",
1688
+ toolInvocation: invocation
1689
+ };
1690
+ if (partProviderMetadata !== void 0) newPart.providerMetadata = partProviderMetadata;
1691
+ message.parts.push(newPart);
1692
+ }
1666
1693
  }
1667
1694
  const data = [];
1668
1695
  let messageAnnotations = replaceLastMessage ? lastMessage?.annotations : void 0;
@@ -1758,7 +1785,7 @@ var Agent = class extends BaseResource {
1758
1785
  if (message.toolInvocations == null) message.toolInvocations = [];
1759
1786
  message.toolInvocations.push(invocation);
1760
1787
  }
1761
- updateToolInvocationPart(chunk.payload.toolCallId, invocation);
1788
+ updateToolInvocationPart(chunk.payload.toolCallId, invocation, chunk.payload.providerMetadata);
1762
1789
  execUpdate();
1763
1790
  if (onToolCall) {
1764
1791
  const result = await onToolCall({ toolCall: chunk.payload });
@@ -1770,7 +1797,7 @@ var Agent = class extends BaseResource {
1770
1797
  result
1771
1798
  };
1772
1799
  message.toolInvocations[message.toolInvocations.length - 1] = invocation;
1773
- updateToolInvocationPart(chunk.payload.toolCallId, invocation);
1800
+ updateToolInvocationPart(chunk.payload.toolCallId, invocation, chunk.payload.providerMetadata);
1774
1801
  execUpdate();
1775
1802
  }
1776
1803
  }
@@ -1827,7 +1854,7 @@ var Agent = class extends BaseResource {
1827
1854
  ...chunk.payload
1828
1855
  };
1829
1856
  toolInvocations[toolInvocationIndex] = invocation;
1830
- updateToolInvocationPart(chunk.payload.toolCallId, invocation);
1857
+ updateToolInvocationPart(chunk.payload.toolCallId, invocation, chunk.payload.providerMetadata);
1831
1858
  execUpdate();
1832
1859
  break;
1833
1860
  }
@@ -5645,22 +5672,29 @@ const KNOWN_AGENT_CONTROLLER_EVENT_TYPES = new Set(Object.keys({
5645
5672
  message_start: true,
5646
5673
  message_update: true,
5647
5674
  message_end: true,
5675
+ state_changed: true,
5648
5676
  tool_input_start: true,
5649
5677
  tool_input_delta: true,
5650
5678
  tool_input_end: true,
5651
5679
  tool_start: true,
5652
5680
  tool_update: true,
5653
5681
  shell_output: true,
5682
+ command_exit: true,
5654
5683
  tool_end: true,
5655
5684
  tool_approval_required: true,
5656
5685
  tool_suspended: true,
5686
+ tool_suspension_cancelled: true,
5657
5687
  mode_changed: true,
5658
5688
  model_changed: true,
5659
5689
  thread_changed: true,
5660
5690
  thread_created: true,
5661
5691
  thread_deleted: true,
5662
5692
  subagent_start: true,
5693
+ subagent_text_delta: true,
5694
+ subagent_tool_start: true,
5695
+ subagent_tool_end: true,
5663
5696
  subagent_end: true,
5697
+ subagent_model_changed: true,
5664
5698
  task_updated: true,
5665
5699
  notification: true,
5666
5700
  notification_summary: true,
@@ -5691,19 +5725,37 @@ const KNOWN_AGENT_CONTROLLER_EVENT_TYPES = new Set(Object.keys({
5691
5725
  function isKnownAgentControllerEvent(event) {
5692
5726
  return KNOWN_AGENT_CONTROLLER_EVENT_TYPES.has(event.type);
5693
5727
  }
5728
+ const toDate = (value) => value instanceof Date ? value : new Date(value);
5694
5729
  function hydrateMessage(message) {
5695
5730
  return {
5696
5731
  ...message,
5697
- createdAt: message.createdAt instanceof Date ? message.createdAt : new Date(message.createdAt)
5732
+ createdAt: toDate(message.createdAt)
5698
5733
  };
5699
5734
  }
5700
- function hydrateEventMessage(event) {
5701
- if (event.type !== "message_start" && event.type !== "message_update" && event.type !== "message_end") return event;
5735
+ function hydrateThread(thread) {
5702
5736
  return {
5703
- ...event,
5704
- message: hydrateMessage(event.message)
5737
+ ...thread,
5738
+ createdAt: toDate(thread.createdAt),
5739
+ updatedAt: toDate(thread.updatedAt)
5705
5740
  };
5706
5741
  }
5742
+ /** The stream carries every timestamp as an ISO string; give consumers back the `Date`s the type promises. */
5743
+ function hydrateEventTimestamps(event) {
5744
+ if (!isKnownAgentControllerEvent(event)) return event;
5745
+ switch (event.type) {
5746
+ case "message_start":
5747
+ case "message_update":
5748
+ case "message_end": return {
5749
+ ...event,
5750
+ message: hydrateMessage(event.message)
5751
+ };
5752
+ case "thread_created": return {
5753
+ ...event,
5754
+ thread: hydrateThread(event.thread)
5755
+ };
5756
+ default: return event;
5757
+ }
5758
+ }
5707
5759
  /**
5708
5760
  * A session bound to a `resourceId` within one agent controller. Sessions are
5709
5761
  * get-or-create on the server, so re-creating the same resourceId (and scope)
@@ -5835,7 +5887,7 @@ var AgentControllerSession = class extends BaseResource {
5835
5887
  if (!data) continue;
5836
5888
  let event;
5837
5889
  try {
5838
- event = hydrateEventMessage(JSON.parse(data));
5890
+ event = hydrateEventTimestamps(JSON.parse(data));
5839
5891
  } catch {
5840
5892
  continue;
5841
5893
  }
@@ -5989,8 +6041,9 @@ var AgentControllerSession = class extends BaseResource {
5989
6041
  });
5990
6042
  }
5991
6043
  /** Get the current mode, model, and thread (for initial UI hydration). */
5992
- state() {
5993
- return this.request(this.url(this.base()));
6044
+ state(options) {
6045
+ const path = options?.threadId ? `${this.base()}?threadId=${encodeURIComponent(options.threadId)}` : this.base();
6046
+ return this.request(this.url(path));
5994
6047
  }
5995
6048
  /** Merge key-value pairs into the session state. Existing keys not in the payload are preserved. */
5996
6049
  async setState(updates) {