@mastra/client-js 1.21.2-alpha.2 → 1.22.0-alpha.4
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 +139 -0
- package/dist/docs/SKILL.md +2 -2
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-agents-signals.md +132 -71
- package/dist/index.cjs +144 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +144 -8
- package/dist/index.js.map +1 -1
- package/dist/resources/run.d.ts +25 -0
- package/dist/resources/run.d.ts.map +1 -1
- package/dist/resources/tool-provider.d.ts +57 -10
- package/dist/resources/tool-provider.d.ts.map +1 -1
- package/dist/route-types.generated.d.ts +1490 -76
- package/dist/route-types.generated.d.ts.map +1 -1
- package/dist/types.d.ts +74 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,144 @@
|
|
|
1
1
|
# @mastra/client-js
|
|
2
2
|
|
|
3
|
+
## 1.22.0-alpha.4
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added the v1 ToolProvider runtime, server routes, client SDK methods, and editor wiring that power OAuth-backed integrations on stored agents. ([#17248](https://github.com/mastra-ai/mastra/pull/17248))
|
|
8
|
+
|
|
9
|
+
**Stored agents can now pin OAuth connections per toolkit**
|
|
10
|
+
|
|
11
|
+
A stored agent's config accepts a new `toolProviders` shape that tells the runtime which connection to bind for each toolkit at execution time. Connections can be scoped per-author, shared across an org, or supplied by the caller.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
{
|
|
15
|
+
toolProviders: {
|
|
16
|
+
composio: {
|
|
17
|
+
connections: {
|
|
18
|
+
gmail: [{ kind: 'author', toolkit: 'gmail', connectionId: 'auth_abc', scope: 'per-author' }],
|
|
19
|
+
},
|
|
20
|
+
tools: {
|
|
21
|
+
GMAIL_FETCH_EMAILS: { toolkit: 'gmail' },
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**New client SDK surface for managing connections**
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { MastraClient } from '@mastra/client-js';
|
|
32
|
+
|
|
33
|
+
const client = new MastraClient({ baseUrl: '…' });
|
|
34
|
+
const composio = client.toolProvider('composio');
|
|
35
|
+
|
|
36
|
+
const { items } = await composio.listConnections({ toolkit: 'gmail' });
|
|
37
|
+
await composio.disconnectConnection('auth_abc');
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**New `ToolProvider` interface for custom providers**
|
|
41
|
+
|
|
42
|
+
Providers implement a VNext surface (`listToolkitsVNext`, `listToolsVNext`, `resolveToolsVNext`) plus the auth round-trip (`authorize`, `getAuthStatus`, `listConnections`, `disconnectConnection`, `listConnectionFields`, `health`). The Composio provider has been rewritten on this surface; the older catalog methods remain as `@deprecated` shims for back-compat.
|
|
43
|
+
|
|
44
|
+
Connections list responses use `page`/`perPage` pagination, matching the rest of the server surface.
|
|
45
|
+
|
|
46
|
+
Both stored agents (`editor.agent.getById(...)`) and code-defined agents with stored overrides (`editor.agent.applyStoredOverrides(...)`) resolve `toolProviders` at request time, merging provider-resolved tools alongside code/registry/MCP/integration tools.
|
|
47
|
+
|
|
48
|
+
Stored agents that don't set `toolProviders` continue to work unchanged. The Studio/Builder UI ships separately.
|
|
49
|
+
|
|
50
|
+
### Patch Changes
|
|
51
|
+
|
|
52
|
+
- Hardened v1 ToolProvider connection routes and SDK forwarding. ([#17248](https://github.com/mastra-ai/mastra/pull/17248))
|
|
53
|
+
|
|
54
|
+
**Fail closed on unknown `connectionId`**
|
|
55
|
+
|
|
56
|
+
`DELETE /tool-providers/:providerId/connections/:connectionId` and
|
|
57
|
+
`GET …/usage` now return `403` when storage is configured but no persisted
|
|
58
|
+
row matches the supplied `connectionId` and the caller isn't an admin.
|
|
59
|
+
Previously these routes fell through to the caller's own `authorId`, which
|
|
60
|
+
let non-admin callers probe (and trigger provider-side `revokeConnection`
|
|
61
|
+
for) IDs that didn't belong to them.
|
|
62
|
+
|
|
63
|
+
**Aligned authorize label validation with stored label rules**
|
|
64
|
+
|
|
65
|
+
`POST /tool-providers/:providerId/authorize` now enforces the same label
|
|
66
|
+
rules the stored `toolProviders` config uses (`min(1)`, `max(32)`,
|
|
67
|
+
`/^[A-Za-z0-9 _-]+$/`). Labels that pass `authorize` are now guaranteed to
|
|
68
|
+
pass downstream stored-agent validation.
|
|
69
|
+
|
|
70
|
+
**SDK forwards `toolkit` on connection-scoped operations**
|
|
71
|
+
|
|
72
|
+
`@mastra/client-js`:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
await client.toolProviders.get('composio').disconnectConnection('ca_xxx', {
|
|
76
|
+
toolkit: 'gmail',
|
|
77
|
+
force: true,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const usage = await client.toolProviders.get('composio').getConnectionUsage('ca_xxx', { toolkit: 'gmail' });
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`disconnectConnection` now forwards `params.toolkit` (previously dropped)
|
|
84
|
+
and `getConnectionUsage` accepts an optional `{ toolkit }` parameter so
|
|
85
|
+
toolkit-scoped connection lookups disambiguate correctly server-side.
|
|
86
|
+
|
|
87
|
+
- Improved observability and error isolation in the v1 ToolProvider runtime. ([#17248](https://github.com/mastra-ai/mastra/pull/17248))
|
|
88
|
+
|
|
89
|
+
**Better visibility into connection-scope misconfiguration**
|
|
90
|
+
|
|
91
|
+
When an agent runs with a stored ToolProvider connection whose scope cannot be resolved from the request context, the runtime now logs a one-shot warning and falls back to a shared bucket instead of silently routing every caller to the same OAuth account. Multi-tenant deployments get a clear signal when their identity wiring isn't reaching the runtime.
|
|
92
|
+
|
|
93
|
+
**One bad toolkit no longer disables sibling providers**
|
|
94
|
+
|
|
95
|
+
If a provider returns more connections for a toolkit than its declared capabilities allow, the runtime now logs and skips that toolkit instead of throwing. Other providers and other toolkits on the same agent continue to resolve normally.
|
|
96
|
+
|
|
97
|
+
- Updated dependencies [[`50ed00c`](https://github.com/mastra-ai/mastra/commit/50ed00caa914a85969b33de83f26b48e328ef641), [`9283971`](https://github.com/mastra-ai/mastra/commit/928397157009b4aef4d5fdf3a0a273cb371beb55), [`0bf2d93`](https://github.com/mastra-ai/mastra/commit/0bf2d932d20e2936f2d9abb8c0a86e24fbc97ec6), [`94dfef6`](https://github.com/mastra-ai/mastra/commit/94dfef6e2bf19a88467ea3940afcbce88a433f0f), [`a122f79`](https://github.com/mastra-ai/mastra/commit/a122f79427ae225ec79c7b2ed46278da48d04b17), [`4c02027`](https://github.com/mastra-ai/mastra/commit/4c020277235eaa6b1dc957c90ad0639eef213992), [`6855012`](https://github.com/mastra-ai/mastra/commit/685501247cc4717506f3e89beed03509d63a5370), [`7fef31c`](https://github.com/mastra-ai/mastra/commit/7fef31c0d2a6d362a43a647a8a4f6ab893758a23), [`7fef31c`](https://github.com/mastra-ai/mastra/commit/7fef31c0d2a6d362a43a647a8a4f6ab893758a23)]:
|
|
98
|
+
- @mastra/core@1.38.0-alpha.4
|
|
99
|
+
|
|
100
|
+
## 1.22.0-alpha.3
|
|
101
|
+
|
|
102
|
+
### Minor Changes
|
|
103
|
+
|
|
104
|
+
- Add fire-and-forget workflow resume that returns immediately with `{ runId }` without awaiting the run output. ([#17230](https://github.com/mastra-ai/mastra/pull/17230))
|
|
105
|
+
|
|
106
|
+
For `@mastra/inngest`, this skips the `getRunOutput()` polling that previously raced a realtime subscription against the Inngest runs API and could surface spurious 404s even though the durable workflow was running fine.
|
|
107
|
+
- `Run.resumeAsync()` added to core: dispatches the resume in the background and returns `{ runId }` immediately. Engines that poll for results (Inngest) override it to skip polling entirely.
|
|
108
|
+
- `InngestRun.resumeAsync()` sends the resume event and returns `{ runId }`, skipping polling. Send-time failures (bad payload, event send failure) still reject synchronously and roll back the snapshot.
|
|
109
|
+
- New `POST /workflows/:workflowId/resume-no-wait` and `POST /agent-builder/:actionId/resume-no-wait` routes return `{ runId }` immediately.
|
|
110
|
+
- New client SDK `run.resumeNoWait()` resolves with `{ runId }`.
|
|
111
|
+
|
|
112
|
+
The existing `resumeAsync()` client/server surface is unchanged and still resolves with the full workflow result, so there is no breaking change.
|
|
113
|
+
|
|
114
|
+
`resumeNoWait` is intentionally additive in v1. In Mastra v2 the fire-and-forget behavior is planned to become the default behavior of `resumeAsync()` (mirroring `start`/`resume` semantics), at which point `resumeNoWait` and the `resume-no-wait` routes will be removed. The code paths carry `TODO(v2)` comments documenting this consolidation.
|
|
115
|
+
|
|
116
|
+
### Patch Changes
|
|
117
|
+
|
|
118
|
+
- Workflows now support an optional `metadata` field for attaching custom key-value data such as `displayName`, `author`, or `category`. Metadata is preserved through serialization and returned in workflow info API responses. ([#17355](https://github.com/mastra-ai/mastra/pull/17355))
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// Define a workflow with metadata
|
|
122
|
+
const myWorkflow = createWorkflow({
|
|
123
|
+
id: 'data-processing',
|
|
124
|
+
metadata: {
|
|
125
|
+
displayName: 'Data Processing Pipeline',
|
|
126
|
+
|
|
127
|
+
category: 'ETL',
|
|
128
|
+
},
|
|
129
|
+
inputSchema: z.object({ ... }),
|
|
130
|
+
outputSchema: z.object({ ... }),
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Retrieve workflow info with metadata via the Mastra Server API
|
|
134
|
+
const workflowInfo = await mastraClient.getWorkflow('data-processing');
|
|
135
|
+
console.log(workflowInfo.metadata?.displayName); // "Data Processing Pipeline"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
- Updated dependencies [[`00eca42`](https://github.com/mastra-ai/mastra/commit/00eca4252393aa114dc8c9a5e1da68df91fa06cf), [`8ace89d`](https://github.com/mastra-ai/mastra/commit/8ace89df77f762e622d3b9f7f65ad7524350d050), [`fa63872`](https://github.com/mastra-ai/mastra/commit/fa6387280954e6b667bec5714b55ba082bc627ff), [`f07b646`](https://github.com/mastra-ai/mastra/commit/f07b64604ab7d25391179790b7fd4823df9e2dff), [`d8838ae`](https://github.com/mastra-ai/mastra/commit/d8838ae80b69780361693d27098f7f6684af12fe), [`40f9297`](https://github.com/mastra-ai/mastra/commit/40f9297003b921c62373d3e8d3a4bda76c9f6de3), [`0f0d1ba`](https://github.com/mastra-ai/mastra/commit/0f0d1ba67bfcb2204e571401662f1eceefc03357), [`8c31bcd`](https://github.com/mastra-ai/mastra/commit/8c31bcdb00e597880d5939b1b7d7566fbe5dacae), [`95b14cd`](https://github.com/mastra-ai/mastra/commit/95b14cdd820e86d97ac05fe568424c513a252e31), [`aa36be2`](https://github.com/mastra-ai/mastra/commit/aa36be23aa513b7dc53cb8ca16b7fab8f20e43ad), [`212c635`](https://github.com/mastra-ai/mastra/commit/212c635203e61d036ab41db8ff86c3893dc795b3), [`d8838ae`](https://github.com/mastra-ai/mastra/commit/d8838ae80b69780361693d27098f7f6684af12fe), [`9aa5a73`](https://github.com/mastra-ai/mastra/commit/9aa5a73e7e110f6e9365eec69364a33d5f03bb56), [`f73c789`](https://github.com/mastra-ai/mastra/commit/f73c789e8ef21561580395d2c410119cab5848c8), [`8bd16da`](https://github.com/mastra-ai/mastra/commit/8bd16da73a4cb874d739373643dbd6a6e7f88684), [`c8630f8`](https://github.com/mastra-ai/mastra/commit/c8630f80d4f40cb5d22e60ab162b618b1907167a), [`47f71dc`](https://github.com/mastra-ai/mastra/commit/47f71dc6fbcbd12d71e21a979e676e20a02bd77d), [`50ceae2`](https://github.com/mastra-ai/mastra/commit/50ceae270878e2f8fb2b2c6c2faab09df0007c8a), [`8cdde58`](https://github.com/mastra-ai/mastra/commit/8cdde5875bbba6702d9df226f2b20232b8d75d6c), [`847ff1e`](https://github.com/mastra-ai/mastra/commit/847ff1e0d94368d94b2e173e4e0908e115568ef3), [`259d409`](https://github.com/mastra-ai/mastra/commit/259d409a514174299dbde1ff5e1121209b3ba850), [`9e16c68`](https://github.com/mastra-ai/mastra/commit/9e16c6818b6485ccb43df28aba6f3a2219d28662), [`cefca33`](https://github.com/mastra-ai/mastra/commit/cefca33ae666e69810c935fedf95a929c173d1d7), [`d00e8c5`](https://github.com/mastra-ai/mastra/commit/d00e8c50daebe5bce5bf2f48bde39c86fc3d2fe4), [`36fa7e2`](https://github.com/mastra-ai/mastra/commit/36fa7e24d14e58a1eb46147097b32f583e5b8775), [`87e9774`](https://github.com/mastra-ai/mastra/commit/87e97741c1e493cd6d62f478eb810b49bda4d57c), [`65a72e7`](https://github.com/mastra-ai/mastra/commit/65a72e70c25eedea8ff985a6624b96be2850236b), [`0f77241`](https://github.com/mastra-ai/mastra/commit/0f7724108806703799a8ba80ad0f09414afd5066), [`92ff509`](https://github.com/mastra-ai/mastra/commit/92ff5098ef8a990438ca038077021a5f7541ec1d), [`3fce5e7`](https://github.com/mastra-ai/mastra/commit/3fce5e70d011d289043e75003ef3336ed4aa43c3), [`a763592`](https://github.com/mastra-ai/mastra/commit/a763592c3db46963ef1011cfe16fe372816e775e), [`80c7737`](https://github.com/mastra-ai/mastra/commit/80c7737e32d7917b5f356957d67c169d01744fd3), [`3f1cf47`](https://github.com/mastra-ai/mastra/commit/3f1cf476f74c1e4cc2df908837e05853a5347e31), [`ff9d743`](https://github.com/mastra-ai/mastra/commit/ff9d743f71d7e072927725c0d700632aca0c1fee)]:
|
|
139
|
+
- @mastra/schema-compat@1.2.11-alpha.0
|
|
140
|
+
- @mastra/core@1.38.0-alpha.3
|
|
141
|
+
|
|
3
142
|
## 1.21.2-alpha.2
|
|
4
143
|
|
|
5
144
|
### Patch Changes
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -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.
|
|
6
|
+
version: "1.22.0-alpha.4"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## When to use
|
|
@@ -17,7 +17,7 @@ Read the individual reference documents for detailed explanations and code examp
|
|
|
17
17
|
### Docs
|
|
18
18
|
|
|
19
19
|
- [A2A](references/docs-agents-a2a.md) - Expose and call remote Mastra agents over the Agent-to-Agent protocol.
|
|
20
|
-
- [Signals](references/docs-agents-signals.md) - Learn how to send real-time context into a Mastra agent thread.
|
|
20
|
+
- [Signals](references/docs-agents-signals.md) - Learn how to send real-time messages and context into a Mastra agent thread.
|
|
21
21
|
- [Editor overview](references/docs-editor-overview.md) - Let non-technical team members iterate on agents, version every change, and run experiments without redeploying.
|
|
22
22
|
- [Auth0](references/docs-server-auth-auth0.md) - Documentation for the @mastra/auth-auth0 package, which authenticates Mastra applications using Auth0 authentication.
|
|
23
23
|
- [Clerk](references/docs-server-auth-clerk.md) - Documentation for the `@mastra/auth-clerk` package, which authenticates Mastra applications using Clerk authentication.
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
> **Experimental:** This feature is in alpha. Breaking changes may occur without a major version bump until the API is stable.
|
|
4
4
|
|
|
5
|
-
Signals are a way to interact with an agent through a thread. Instead of starting every interaction with `agent.stream()`, subscribe to a thread and send signals. Mastra either wakes the agent when the thread is idle
|
|
5
|
+
Signals are a way to interact with an agent through a thread. Instead of starting every interaction with `agent.stream()`, subscribe to a thread and send messages or signals. Mastra either wakes the agent when the thread is idle, drops input into the running agent loop, or queues input for the next turn.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Use message APIs for user-authored input. Use `sendSignal()` for lower-level system context, such as background task notifications, policy reminders, or processor-generated context.
|
|
8
8
|
|
|
9
9
|
## Quickstart
|
|
10
10
|
|
|
11
|
-
Subscribe to the thread before sending
|
|
11
|
+
Subscribe to the thread before sending messages. The subscription receives the active stream when the message wakes the agent or enters a running loop.
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
14
|
const subscription = await agent.subscribeToThread({
|
|
@@ -16,33 +16,65 @@ const subscription = await agent.subscribeToThread({
|
|
|
16
16
|
threadId: 'thread_456',
|
|
17
17
|
})
|
|
18
18
|
|
|
19
|
-
agent.
|
|
19
|
+
agent.sendMessage('Compare that with the previous option.', {
|
|
20
|
+
resourceId: 'user_123',
|
|
21
|
+
threadId: 'thread_456',
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
for await (const chunk of subscription.stream) {
|
|
25
|
+
console.log(chunk)
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
When the thread has a running agent stream, `sendMessage()` becomes new input inside that agent loop. When the thread is idle, Mastra starts a stream with the message as the first input.
|
|
30
|
+
|
|
31
|
+
## Send a message now
|
|
32
|
+
|
|
33
|
+
Use `sendMessage()` when the user expects the active agent to see the message immediately.
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
agent.sendMessage(
|
|
20
37
|
{
|
|
21
|
-
|
|
22
|
-
|
|
38
|
+
contents: 'Use the latest customer note too.',
|
|
39
|
+
attributes: { name: 'Jane', sentFrom: 'slack' },
|
|
23
40
|
},
|
|
24
41
|
{
|
|
25
42
|
resourceId: 'user_123',
|
|
26
43
|
threadId: 'thread_456',
|
|
27
44
|
},
|
|
28
45
|
)
|
|
46
|
+
```
|
|
29
47
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
48
|
+
The model receives attributed messages as XML-wrapped user input:
|
|
49
|
+
|
|
50
|
+
```xml
|
|
51
|
+
<user name="Jane" sentFrom="slack">Use the latest customer note too.</user>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Messages without attributes are sent as plain user input.
|
|
55
|
+
|
|
56
|
+
## Queue a message for the next turn
|
|
57
|
+
|
|
58
|
+
Use `queueMessage()` when a user sends a follow-up but the active model call should finish first. Mastra waits for the active run to complete, then starts a new run on the same thread.
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
agent.queueMessage('Also check whether the tests need updates.', {
|
|
62
|
+
resourceId: 'user_123',
|
|
63
|
+
threadId: 'thread_456',
|
|
64
|
+
})
|
|
33
65
|
```
|
|
34
66
|
|
|
35
|
-
When the thread
|
|
67
|
+
When the thread is idle, `queueMessage()` starts a run immediately. When the thread is active, it preserves turn order by starting a new run after the active run completes.
|
|
36
68
|
|
|
37
|
-
## Control signal behavior
|
|
69
|
+
## Control low-level signal behavior
|
|
38
70
|
|
|
39
|
-
By default, Mastra delivers signals to active runs and wakes idle threads. Use `ifActive.behavior` and `ifIdle.behavior` to change that behavior.
|
|
71
|
+
Use `sendSignal()` when you need to send system-generated context instead of user-authored input. For external events, use `type: 'notification'`. By default, Mastra delivers signals to active runs and wakes idle threads. Use `ifActive.behavior` and `ifIdle.behavior` to change that behavior.
|
|
40
72
|
|
|
41
73
|
```typescript
|
|
42
74
|
const result = agent.sendSignal(
|
|
43
75
|
{
|
|
44
|
-
type: '
|
|
45
|
-
contents: '
|
|
76
|
+
type: 'notification',
|
|
77
|
+
contents: 'GitHub CI failed on PR #123: 3 tests failed.',
|
|
46
78
|
},
|
|
47
79
|
{
|
|
48
80
|
resourceId: 'user_123',
|
|
@@ -58,44 +90,43 @@ await result.persisted
|
|
|
58
90
|
|
|
59
91
|
The behavior options are:
|
|
60
92
|
|
|
61
|
-
- `ifActive.behavior: 'deliver'`: Add the signal to the running agent loop. This is the default.
|
|
62
|
-
- `ifActive.behavior: 'persist'`: Save the signal to memory without adding it to the running loop.
|
|
63
|
-
- `ifActive.behavior: 'discard'`: Ignore the signal while the thread is active.
|
|
64
|
-
- `ifIdle.behavior: 'wake'`: Start a stream with the signal as the first input. This is the default.
|
|
65
|
-
- `ifIdle.behavior: 'persist'`: Save the signal to memory without starting a stream.
|
|
66
|
-
- `ifIdle.behavior: 'discard'`: Ignore the signal while the thread is idle.
|
|
93
|
+
- `ifActive.behavior: 'deliver'`: Add the signal or message to the running agent loop. This is the default.
|
|
94
|
+
- `ifActive.behavior: 'persist'`: Save the signal or message to memory without adding it to the running loop.
|
|
95
|
+
- `ifActive.behavior: 'discard'`: Ignore the signal or message while the thread is active.
|
|
96
|
+
- `ifIdle.behavior: 'wake'`: Start a stream with the signal or message as the first input. This is the default.
|
|
97
|
+
- `ifIdle.behavior: 'persist'`: Save the signal or message to memory without starting a stream.
|
|
98
|
+
- `ifIdle.behavior: 'discard'`: Ignore the signal or message while the thread is idle.
|
|
67
99
|
|
|
68
100
|
Pass `ifIdle.streamOptions` when the idle wake-up stream needs options such as model settings, tools, or runtime context. You do not need to repeat `memory.resource` or `memory.thread`; Mastra uses the top-level `resourceId` and `threadId` for the thread.
|
|
69
101
|
|
|
70
102
|
```typescript
|
|
71
|
-
agent.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
threadId: 'thread_456',
|
|
79
|
-
ifIdle: {
|
|
80
|
-
behavior: 'wake',
|
|
81
|
-
streamOptions: {
|
|
82
|
-
maxSteps: 3,
|
|
83
|
-
},
|
|
103
|
+
agent.sendMessage('Continue with the next step.', {
|
|
104
|
+
resourceId: 'user_123',
|
|
105
|
+
threadId: 'thread_456',
|
|
106
|
+
ifIdle: {
|
|
107
|
+
behavior: 'wake',
|
|
108
|
+
streamOptions: {
|
|
109
|
+
maxSteps: 3,
|
|
84
110
|
},
|
|
85
111
|
},
|
|
86
|
-
)
|
|
112
|
+
})
|
|
87
113
|
```
|
|
88
114
|
|
|
89
|
-
##
|
|
115
|
+
## Send notification context
|
|
116
|
+
|
|
117
|
+
Signals have a semantic `type` and an LLM-facing `tagName`. Use `type` to describe the signal category. Use `tagName` to control the XML tag the model sees.
|
|
90
118
|
|
|
91
|
-
|
|
119
|
+
For external events, use `type: 'notification'`. Reactive signals are reserved for processor- or runtime-generated context, such as policy guidance, background task results, and auto-loaded instructions.
|
|
92
120
|
|
|
93
121
|
```typescript
|
|
94
122
|
agent.sendSignal(
|
|
95
123
|
{
|
|
96
|
-
type: '
|
|
97
|
-
contents: '
|
|
98
|
-
attributes: {
|
|
124
|
+
type: 'notification',
|
|
125
|
+
contents: 'PR #123 has a new review comment from User X about the API surface.',
|
|
126
|
+
attributes: {
|
|
127
|
+
source: 'github',
|
|
128
|
+
pr: '123',
|
|
129
|
+
},
|
|
99
130
|
},
|
|
100
131
|
{
|
|
101
132
|
resourceId: 'user_123',
|
|
@@ -104,51 +135,67 @@ agent.sendSignal(
|
|
|
104
135
|
)
|
|
105
136
|
```
|
|
106
137
|
|
|
107
|
-
The model receives:
|
|
138
|
+
The model receives the signal as context like this:
|
|
108
139
|
|
|
109
140
|
```xml
|
|
110
|
-
<
|
|
141
|
+
<notification source="github" pr="123">PR #123 has a new review comment from User X about the API surface.</notification>
|
|
111
142
|
```
|
|
112
143
|
|
|
113
|
-
|
|
144
|
+
Use XML-safe `tagName` and attribute names. They can contain letters, numbers, underscores, periods, and hyphens. They must start with a letter or underscore.
|
|
145
|
+
|
|
146
|
+
## Send processor context
|
|
114
147
|
|
|
115
|
-
|
|
148
|
+
Processors can send reactive signals during a run. A processor should inspect the chat history, react to a specific trigger, and avoid sending the same context more than once.
|
|
116
149
|
|
|
117
|
-
|
|
150
|
+
The following example demonstrates a processor that injects `AGENTS.md` instructions after a tool call reads an `AGENTS.md` file.
|
|
118
151
|
|
|
119
152
|
```typescript
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
153
|
+
import type { Processor, ProcessInputStepArgs } from '@mastra/core/processors'
|
|
154
|
+
|
|
155
|
+
export const agentsMdReminderProcessor: Processor = {
|
|
156
|
+
id: 'agents-md-reminder',
|
|
157
|
+
async processInputStep({ messageList, sendSignal }: ProcessInputStepArgs) {
|
|
158
|
+
const messages = messageList.get.all.db()
|
|
159
|
+
const agentsMdPath = findAgentsMdPathFromToolCalls(messages)
|
|
160
|
+
|
|
161
|
+
if (!agentsMdPath || hasAlreadySentAgentsMdReminder(messages, agentsMdPath)) {
|
|
162
|
+
return messageList
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
await sendSignal?.({
|
|
166
|
+
type: 'reactive',
|
|
167
|
+
contents: readAgentsMdInstructions(agentsMdPath),
|
|
168
|
+
attributes: {
|
|
169
|
+
type: 'dynamic-agents-md',
|
|
170
|
+
path: agentsMdPath,
|
|
171
|
+
},
|
|
172
|
+
metadata: {
|
|
173
|
+
path: agentsMdPath,
|
|
174
|
+
},
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
return messageList
|
|
132
178
|
},
|
|
133
|
-
|
|
179
|
+
}
|
|
134
180
|
```
|
|
135
181
|
|
|
136
|
-
|
|
182
|
+
Reactive signals default to `tagName: 'system-reminder'`, so the model receives this context as
|
|
137
183
|
|
|
138
184
|
```xml
|
|
139
|
-
<system-reminder
|
|
185
|
+
<system-reminder type="dynamic-agents-md" path="packages/ui/AGENTS.md">
|
|
186
|
+
$agentsMdFileContents
|
|
187
|
+
</system-reminder>
|
|
140
188
|
```
|
|
141
189
|
|
|
142
|
-
|
|
190
|
+
Awaiting `sendSignal()` preserves stream echo ordering when a subscribed thread is active.
|
|
143
191
|
|
|
144
|
-
##
|
|
192
|
+
## Conditional attributes
|
|
145
193
|
|
|
146
|
-
Use `ifActive.attributes` and `ifIdle.attributes` to tag
|
|
194
|
+
Use `ifActive.attributes` and `ifIdle.attributes` to tag input with context that depends on whether the agent is active or idle at delivery time. Mastra resolves the correct branch when the input is accepted.
|
|
147
195
|
|
|
148
196
|
```typescript
|
|
149
|
-
agent.
|
|
197
|
+
agent.sendMessage(
|
|
150
198
|
{
|
|
151
|
-
type: 'user-message',
|
|
152
199
|
contents: 'Also cover the edge cases.',
|
|
153
200
|
attributes: { source: 'chat' },
|
|
154
201
|
},
|
|
@@ -156,7 +203,7 @@ agent.sendSignal(
|
|
|
156
203
|
resourceId: 'user_123',
|
|
157
204
|
threadId: 'thread_456',
|
|
158
205
|
ifActive: { attributes: { delivery: 'while-active' } },
|
|
159
|
-
ifIdle: { attributes: { delivery: 'message' } },
|
|
206
|
+
ifIdle: { attributes: { delivery: 'new-message' } },
|
|
160
207
|
},
|
|
161
208
|
)
|
|
162
209
|
```
|
|
@@ -164,24 +211,35 @@ agent.sendSignal(
|
|
|
164
211
|
When the agent is working, the model sees:
|
|
165
212
|
|
|
166
213
|
```xml
|
|
167
|
-
<user
|
|
214
|
+
<user source="chat" delivery="while-active">Also cover the edge cases.</user>
|
|
168
215
|
```
|
|
169
216
|
|
|
170
217
|
When the agent is idle:
|
|
171
218
|
|
|
172
219
|
```xml
|
|
173
|
-
<user
|
|
220
|
+
<user source="chat" delivery="new-message">Also cover the edge cases.</user>
|
|
174
221
|
```
|
|
175
222
|
|
|
176
|
-
Top-level `attributes` always apply. The selected branch's `attributes` are merged into them at delivery time. The `
|
|
223
|
+
Top-level `attributes` always apply. The selected branch's `attributes` are merged into them at delivery time. The `delivery` name shown above is not a special Mastra API field. It is a custom attribute name used for this example, you can add any attribute names that suit your use case.
|
|
224
|
+
|
|
225
|
+
## Compatibility
|
|
226
|
+
|
|
227
|
+
Mastra still accepts legacy signal payloads such as `type: 'user-message'` and `type: 'system-reminder'`. It normalizes them internally to the new category and tag shape:
|
|
228
|
+
|
|
229
|
+
- `type: 'user-message'`: Normalizes to `type: 'user'` and `tagName: 'user'`
|
|
230
|
+
- `type: 'system-reminder'`: Normalizes to `type: 'reactive'` and `tagName: 'system-reminder'`
|
|
231
|
+
|
|
232
|
+
Existing stored signal rows and older clients continue to load through the compatibility layer.
|
|
233
|
+
|
|
234
|
+
> **Note:** Visit [Agent signals reference](https://mastra.ai/reference/agents/agent) for the full message, signal, and subscription types.
|
|
177
235
|
|
|
178
|
-
|
|
236
|
+
## Use HTTP routes
|
|
179
237
|
|
|
180
|
-
|
|
238
|
+
If you call Mastra over HTTP directly, use `POST /api/agents/:agentId/send-message` for immediate messages and `POST /api/agents/:agentId/queue-message` for next-turn messages. See [Server routes reference](https://mastra.ai/reference/server/routes) for request and response schemas.
|
|
181
239
|
|
|
182
240
|
## Use the client SDK
|
|
183
241
|
|
|
184
|
-
The JavaScript client exposes
|
|
242
|
+
The JavaScript client exposes thread signal APIs. Use `subscribeToThread()` before sending thread input so the client can render the stream that wakes from, or receives, the input.
|
|
185
243
|
|
|
186
244
|
```typescript
|
|
187
245
|
const agent = client.getAgent('supportAgent')
|
|
@@ -230,7 +288,10 @@ Use heartbeats together with client-side reconnect logic. Heartbeats reduce idle
|
|
|
230
288
|
|
|
231
289
|
## Related
|
|
232
290
|
|
|
291
|
+
- [`Agent.sendMessage()`](https://mastra.ai/reference/agents/agent)
|
|
292
|
+
- [`Agent.queueMessage()`](https://mastra.ai/reference/agents/agent)
|
|
233
293
|
- [`Agent.sendSignal()`](https://mastra.ai/reference/agents/agent)
|
|
234
294
|
- [`Agent.subscribeToThread()`](https://mastra.ai/reference/agents/agent)
|
|
295
|
+
- [Server agent routes](https://mastra.ai/reference/server/routes)
|
|
235
296
|
- [`client.getAgent().sendSignal()`](https://mastra.ai/reference/client-js/agents)
|
|
236
297
|
- [`client.getAgent().subscribeToThread()`](https://mastra.ai/reference/client-js/agents)
|