@mastra/mcp-docs-server 1.1.45 → 1.1.46-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.docs/docs/agents/code-mode.md +2 -0
- package/.docs/docs/agents/signal-providers.md +222 -0
- package/.docs/docs/agents/signals.md +63 -189
- package/.docs/docs/getting-started/build-with-ai.md +2 -2
- package/.docs/docs/mastra-platform/configuration.md +1 -1
- package/.docs/docs/mastra-platform/overview.md +1 -1
- package/.docs/docs/observability/config.md +139 -0
- package/.docs/docs/observability/{tracing → integrations}/bridges/datadog.md +7 -7
- package/.docs/docs/observability/{tracing → integrations}/bridges/otel.md +3 -3
- package/.docs/docs/observability/{tracing → integrations}/exporters/datadog.md +1 -1
- package/.docs/docs/observability/{tracing → integrations}/exporters/mastra-platform.md +1 -1
- package/.docs/docs/observability/{tracing → integrations}/exporters/mastra-storage.md +1 -1
- package/.docs/docs/observability/{tracing → integrations}/exporters/otel.md +4 -4
- package/.docs/docs/observability/{tracing → integrations}/exporters/posthog.md +16 -0
- package/.docs/docs/observability/integrations/overview.md +45 -0
- package/.docs/docs/observability/metrics/overview.md +1 -1
- package/.docs/docs/observability/metrics/querying.md +18 -0
- package/.docs/docs/observability/overview.md +8 -4
- package/.docs/docs/observability/storage.md +79 -0
- package/.docs/docs/observability/tracing/overview.md +98 -390
- package/.docs/guides/guide/signal-provider.md +217 -0
- package/.docs/guides/migrations/upgrade-to-v1/tracing.md +11 -11
- package/.docs/reference/agents/agent.md +150 -2
- package/.docs/reference/client-js/agents.md +4 -0
- package/.docs/reference/core/mastra-class.md +28 -0
- package/.docs/reference/harness/harness-class.md +1 -1
- package/.docs/reference/index.md +3 -0
- package/.docs/reference/observability/tracing/bridges/datadog.md +2 -2
- package/.docs/reference/observability/tracing/bridges/otel.md +2 -2
- package/.docs/reference/observability/tracing/configuration.md +1 -1
- package/.docs/reference/observability/tracing/exporters/arize.md +1 -1
- package/.docs/reference/observability/tracing/exporters/arthur.md +1 -1
- package/.docs/reference/observability/tracing/exporters/cloud-exporter.md +1 -1
- package/.docs/reference/observability/tracing/exporters/console-exporter.md +1 -1
- package/.docs/reference/observability/tracing/exporters/default-exporter.md +1 -1
- package/.docs/reference/observability/tracing/exporters/mastra-platform-exporter.md +1 -1
- package/.docs/reference/observability/tracing/exporters/mastra-storage-exporter.md +1 -1
- package/.docs/reference/observability/tracing/exporters/otel.md +2 -2
- package/.docs/reference/observability/tracing/span-filtering.md +1 -1
- package/.docs/reference/pubsub/base.md +24 -0
- package/.docs/reference/pubsub/caching-pubsub.md +6 -0
- package/.docs/reference/pubsub/event-emitter.md +36 -1
- package/.docs/reference/signals/create-notification-inbox-tool.md +67 -0
- package/.docs/reference/signals/signal-provider.md +406 -0
- package/.docs/reference/signals/webhook-signal-provider.md +137 -0
- package/.docs/reference/storage/clickhouse.md +3 -3
- package/.docs/reference/storage/composite.md +1 -1
- package/.docs/reference/storage/duckdb.md +1 -1
- package/.docs/reference/storage/libsql.md +1 -1
- package/.docs/reference/storage/postgresql.md +1 -1
- package/CHANGELOG.md +8 -0
- package/package.json +7 -7
- /package/.docs/docs/observability/{tracing → integrations}/exporters/arize.md +0 -0
- /package/.docs/docs/observability/{tracing → integrations}/exporters/arthur.md +0 -0
- /package/.docs/docs/observability/{tracing → integrations}/exporters/braintrust.md +0 -0
- /package/.docs/docs/observability/{tracing → integrations}/exporters/laminar.md +0 -0
- /package/.docs/docs/observability/{tracing → integrations}/exporters/langfuse.md +0 -0
- /package/.docs/docs/observability/{tracing → integrations}/exporters/langsmith.md +0 -0
- /package/.docs/docs/observability/{tracing → integrations}/exporters/sentry.md +0 -0
- /package/.docs/docs/observability/{tracing → integrations}/processors/sensitive-data-filter.md +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Code mode
|
|
2
2
|
|
|
3
|
+
**Added in:** `@mastra/core@1.38.0`
|
|
4
|
+
|
|
3
5
|
> **Alpha:** This feature is in alpha. Breaking changes may occur without a major version bump until the API is stable.
|
|
4
6
|
|
|
5
7
|
Code mode gives an agent a single tool that runs a short TypeScript program in a sandbox. Instead of calling tools one at a time, the model writes a program that orchestrates your existing tools as `external_*` functions, batching calls with `Promise.all`, aggregating with `reduce`, branching, and doing math in a real runtime, then returns a single result.
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Signal providers
|
|
2
|
+
|
|
3
|
+
**Added in:** `@mastra/core@1.39.0`
|
|
4
|
+
|
|
5
|
+
> **Alpha:** This feature is in alpha. Breaking changes may occur without a major version bump until the API is stable.
|
|
6
|
+
|
|
7
|
+
A signal provider monitors an external source, such as GitHub, Slack, continuous integration (CI), or your own API, and pushes [notification signals](https://mastra.ai/docs/agents/signals) into subscribed agent threads.
|
|
8
|
+
|
|
9
|
+
## When to use a signal provider
|
|
10
|
+
|
|
11
|
+
Use a signal provider when an external system produces events that an agent should react to, and you want Mastra to manage the subscription bookkeeping for you.
|
|
12
|
+
|
|
13
|
+
- The source emits events tied to a resource a thread cares about, such as a pull request, a channel, or a build.
|
|
14
|
+
- You want one place that tracks which threads watch which external resources.
|
|
15
|
+
- You want to receive events by polling, by webhook, or both.
|
|
16
|
+
|
|
17
|
+
If you only need to push a one-off event into a thread, call [`agent.sendNotificationSignal()`](https://mastra.ai/reference/agents/agent) directly instead.
|
|
18
|
+
|
|
19
|
+
## How signal providers work
|
|
20
|
+
|
|
21
|
+
A signal provider is the producing side of the [signals](https://mastra.ai/docs/agents/signals) system. It brings external events into a thread, while the signal APIs control how the thread consumes them.
|
|
22
|
+
|
|
23
|
+
A signal provider combines three capabilities:
|
|
24
|
+
|
|
25
|
+
- **Subscription tracking:** The `SignalProvider` base class keeps an in-memory registry that maps each agent thread to the external resources it watches.
|
|
26
|
+
- **Ingestion:** You override `poll()` for pull-based sources or `handleWebhook()` for push-based sources.
|
|
27
|
+
- **Delivery:** When an event matches a subscription, call the protected `notify()` helper to forward a notification signal to the connected agent's thread.
|
|
28
|
+
|
|
29
|
+
Register a provider by passing it to an agent. The agent connects the provider, starts polling if a `pollInterval` is set, and merges any processors or tools the provider exposes.
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { Agent } from '@mastra/core/agent'
|
|
33
|
+
import { CiSignals } from '../signals/ci-signals'
|
|
34
|
+
|
|
35
|
+
export const supportAgent = new Agent({
|
|
36
|
+
id: 'support-agent',
|
|
37
|
+
name: 'Support Agent',
|
|
38
|
+
instructions: 'Help the user triage updates.',
|
|
39
|
+
model: 'openai/gpt-5.5',
|
|
40
|
+
signals: [new CiSignals()],
|
|
41
|
+
})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
> **Note:** Notification delivery requires a storage adapter with notification support, such as [libSQL](https://mastra.ai/reference/storage/libsql), [PostgreSQL](https://mastra.ai/reference/storage/postgresql), or [MongoDB](https://mastra.ai/reference/storage/mongodb). Configure storage on the Mastra instance so `notify()` can store notification records.
|
|
45
|
+
|
|
46
|
+
## Quickstart
|
|
47
|
+
|
|
48
|
+
The following example demonstrates a polling provider that watches CI pipelines and emits a notification when a subscribed pipeline fails.
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { SignalProvider } from '@mastra/core/signals'
|
|
52
|
+
import type { SignalProviderTarget, SignalSubscription } from '@mastra/core/signals'
|
|
53
|
+
|
|
54
|
+
type BuildStatus = {
|
|
55
|
+
id: string
|
|
56
|
+
status: 'passed' | 'failed'
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const builds = new Map<string, BuildStatus>([
|
|
60
|
+
['acme-app-main', { id: 'build_123', status: 'failed' }],
|
|
61
|
+
])
|
|
62
|
+
|
|
63
|
+
async function fetchBuildStatus(pipeline: string): Promise<BuildStatus> {
|
|
64
|
+
return builds.get(pipeline) ?? { id: 'build_unknown', status: 'passed' }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export class CiSignals extends SignalProvider<'ci-signals'> {
|
|
68
|
+
readonly id = 'ci-signals' as const
|
|
69
|
+
readonly pollInterval = 30_000
|
|
70
|
+
|
|
71
|
+
watch(target: SignalProviderTarget, pipeline: string) {
|
|
72
|
+
return this.subscribe(target, pipeline)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
unwatch(target: SignalProviderTarget, pipeline: string) {
|
|
76
|
+
return this.unsubscribe(target, pipeline)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async poll(subscriptions: SignalSubscription[]) {
|
|
80
|
+
for (const sub of subscriptions) {
|
|
81
|
+
const build = await fetchBuildStatus(sub.externalResourceId)
|
|
82
|
+
if (build.status !== 'failed') continue
|
|
83
|
+
|
|
84
|
+
await this.notify(
|
|
85
|
+
{
|
|
86
|
+
source: this.id,
|
|
87
|
+
kind: 'ci-status',
|
|
88
|
+
priority: 'high',
|
|
89
|
+
summary: `Build failed for ${sub.externalResourceId}`,
|
|
90
|
+
payload: build,
|
|
91
|
+
dedupeKey: `${this.id}:${sub.externalResourceId}:${build.id}`,
|
|
92
|
+
},
|
|
93
|
+
{ resourceId: sub.resourceId, threadId: sub.threadId },
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Register the provider with an agent and subscribe a thread to the pipeline you want to watch.
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
import { Agent } from '@mastra/core/agent'
|
|
104
|
+
import { CiSignals } from '../signals/ci-signals'
|
|
105
|
+
|
|
106
|
+
export const ciSignals = new CiSignals()
|
|
107
|
+
|
|
108
|
+
export const supportAgent = new Agent({
|
|
109
|
+
id: 'support-agent',
|
|
110
|
+
name: 'Support Agent',
|
|
111
|
+
instructions: 'Help the user triage CI updates.',
|
|
112
|
+
model: 'openai/gpt-5.5',
|
|
113
|
+
signals: [ciSignals],
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
ciSignals.watch({ resourceId: 'user_123', threadId: 'thread_456' }, 'acme-app-main')
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Mastra calls `poll()` on the `pollInterval` with all active subscriptions. It skips a cycle when there are no subscriptions and doesn't overlap cycles, so a slow `poll()` doesn't run concurrently with itself.
|
|
120
|
+
|
|
121
|
+
> **Note:** For a complete polling-provider build with notification storage, agent registration, thread subscription, and testing, follow [Building a signal provider](https://mastra.ai/guides/guide/signal-provider).
|
|
122
|
+
|
|
123
|
+
## Polling and webhook providers
|
|
124
|
+
|
|
125
|
+
Use polling when the external source doesn't push events to your app. Set `pollInterval` and override `poll(subscriptions)`. Each subscription includes the thread target and the external resource id to inspect.
|
|
126
|
+
|
|
127
|
+
Use webhooks when the external source can call your app. Override `handleWebhook(request)`, parse the payload, find matching subscriptions, and call `notify()` for each match.
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import { SignalProvider } from '@mastra/core/signals'
|
|
131
|
+
import type { SignalProviderWebhookRequest } from '@mastra/core/signals'
|
|
132
|
+
|
|
133
|
+
export class CiSignals extends SignalProvider<'ci-signals'> {
|
|
134
|
+
readonly id = 'ci-signals' as const
|
|
135
|
+
|
|
136
|
+
async handleWebhook(request: SignalProviderWebhookRequest) {
|
|
137
|
+
const payload = request.body as { pipeline: string; status: string }
|
|
138
|
+
const subscriptions = this.getSubscriptionsForResource(payload.pipeline)
|
|
139
|
+
|
|
140
|
+
for (const sub of subscriptions) {
|
|
141
|
+
await this.notify(
|
|
142
|
+
{
|
|
143
|
+
source: this.id,
|
|
144
|
+
kind: 'ci-status',
|
|
145
|
+
priority: 'high',
|
|
146
|
+
summary: `Build ${payload.status} for ${payload.pipeline}`,
|
|
147
|
+
payload,
|
|
148
|
+
},
|
|
149
|
+
{ resourceId: sub.resourceId, threadId: sub.threadId },
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return { status: 200, body: { matched: subscriptions.length } }
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`handleWebhook()` is a provider method, not an auto-mounted HTTP route. Invoke it from your own endpoint, passing the request body, headers, and any route params.
|
|
159
|
+
|
|
160
|
+
> **Note:** Visit [`SignalProvider` reference](https://mastra.ai/reference/signals/signal-provider) for subscription, polling, lifecycle, and `notify()` details. For the complete notification payload shape, including deduplication and coalescing fields, visit [`Agent.sendNotificationSignal()` reference](https://mastra.ai/reference/agents/agent).
|
|
161
|
+
|
|
162
|
+
## Built-in webhook provider
|
|
163
|
+
|
|
164
|
+
For generic webhook sources, use [`WebhookSignalProvider`](https://mastra.ai/reference/signals/webhook-signal-provider) instead of writing a subclass. Configure it with a function that extracts a resource id from the payload, and an optional function that builds the notification.
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
import { Agent } from '@mastra/core/agent'
|
|
168
|
+
import { WebhookSignalProvider } from '@mastra/core/signals'
|
|
169
|
+
|
|
170
|
+
const webhooks = new WebhookSignalProvider({
|
|
171
|
+
extractResourceId: payload => (payload as { repository: string }).repository,
|
|
172
|
+
buildNotification: (payload, sub) => ({
|
|
173
|
+
source: 'ci',
|
|
174
|
+
kind: 'build-status',
|
|
175
|
+
priority: 'medium',
|
|
176
|
+
summary: `Build ${(payload as { status: string }).status} for ${sub.externalResourceId}`,
|
|
177
|
+
}),
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
export const supportAgent = new Agent({
|
|
181
|
+
id: 'support-agent',
|
|
182
|
+
name: 'Support Agent',
|
|
183
|
+
instructions: 'Help the user triage updates.',
|
|
184
|
+
model: 'openai/gpt-5.5',
|
|
185
|
+
signals: [webhooks],
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
webhooks.subscribeThread({ resourceId: 'user_123', threadId: 'thread_456' }, 'acme/app')
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
When a webhook arrives, call `webhooks.handleWebhook({ body, headers })` from your route. The provider matches the extracted resource id against its subscriptions and notifies each matching thread.
|
|
192
|
+
|
|
193
|
+
## Advanced provider capabilities
|
|
194
|
+
|
|
195
|
+
A provider can support more than event ingestion. Add only the capabilities your source needs.
|
|
196
|
+
|
|
197
|
+
- **Durable subscriptions:** The base registry is in-memory and per-process. Persist subscriptions yourself when they must survive a restart, then rehydrate them in [`start()`](https://mastra.ai/reference/signals/signal-provider).
|
|
198
|
+
- **Lifecycle hooks:** Override [`start()`](https://mastra.ai/reference/signals/signal-provider) for async setup and [`stop()`](https://mastra.ai/reference/signals/signal-provider) for cleanup. Call `super.stop()` when overriding `stop()` so the base provider can stop polling and clear its registry.
|
|
199
|
+
- **Processors and tools:** Return processors from [`getInputProcessors()`](https://mastra.ai/reference/signals/signal-provider) or [`getOutputProcessors()`](https://mastra.ai/reference/signals/signal-provider), and return agent-callable tools from [`getTools()`](https://mastra.ai/reference/signals/signal-provider).
|
|
200
|
+
|
|
201
|
+
The `@mastra/github-signals` package is a production signal provider that watches GitHub pull requests and notifies threads about comments, review state, continuous integration status, and merges. Use it as a reference for polling, durable subscriptions, tools, processors, and lifecycle hooks.
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
import { Agent } from '@mastra/core/agent'
|
|
205
|
+
import { GithubSignals } from '@mastra/github-signals'
|
|
206
|
+
|
|
207
|
+
export const devAgent = new Agent({
|
|
208
|
+
id: 'dev-agent',
|
|
209
|
+
name: 'Dev Agent',
|
|
210
|
+
instructions: 'Help triage pull request activity.',
|
|
211
|
+
model: 'openai/gpt-5.5',
|
|
212
|
+
signals: [new GithubSignals()],
|
|
213
|
+
})
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Related
|
|
217
|
+
|
|
218
|
+
- [Guide: Building a signal provider](https://mastra.ai/guides/guide/signal-provider)
|
|
219
|
+
- [Signals](https://mastra.ai/docs/agents/signals)
|
|
220
|
+
- [Notification signals](https://mastra.ai/docs/agents/signals)
|
|
221
|
+
- [`SignalProvider` reference](https://mastra.ai/reference/signals/signal-provider)
|
|
222
|
+
- [`WebhookSignalProvider` reference](https://mastra.ai/reference/signals/webhook-signal-provider)
|
|
@@ -1,25 +1,41 @@
|
|
|
1
1
|
# Signals
|
|
2
2
|
|
|
3
|
+
**Added in:** `@mastra/core@1.39.0`
|
|
4
|
+
|
|
3
5
|
> **Alpha:** This feature is in alpha. Breaking changes may occur without a major version bump until the API is stable.
|
|
4
6
|
|
|
5
7
|
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
8
|
|
|
7
9
|
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
10
|
|
|
11
|
+
## When to use signals
|
|
12
|
+
|
|
13
|
+
Use signals when an agent thread needs new input or context outside the original `stream()` call. Signals are useful when users send follow-up messages while a run is active, when background systems need to add context to a thread, or when external events should wake, update, or notify the agent.
|
|
14
|
+
|
|
15
|
+
Use `sendMessage()` and `queueMessage()` for user-authored input. Use `sendSignal()` for lower-level system context. Use `sendStateSignal()` for durable state lanes, and use `sendNotificationSignal()` when an external event should create a durable notification inbox record.
|
|
16
|
+
|
|
9
17
|
## Quickstart
|
|
10
18
|
|
|
11
|
-
|
|
19
|
+
Create an agent, subscribe to a thread, then send a message to that thread. The subscription receives the active stream when the message wakes the agent or enters a running loop.
|
|
12
20
|
|
|
13
21
|
```typescript
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
22
|
+
import { Agent } from '@mastra/core/agent'
|
|
23
|
+
|
|
24
|
+
const agent = new Agent({
|
|
25
|
+
id: 'support-agent',
|
|
26
|
+
name: 'Support Agent',
|
|
27
|
+
instructions: 'Help the user compare options.',
|
|
28
|
+
model: 'openai/gpt-5.5',
|
|
17
29
|
})
|
|
18
30
|
|
|
19
|
-
|
|
31
|
+
const thread = {
|
|
20
32
|
resourceId: 'user_123',
|
|
21
33
|
threadId: 'thread_456',
|
|
22
|
-
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const subscription = await agent.subscribeToThread(thread)
|
|
37
|
+
|
|
38
|
+
await agent.sendMessage('Compare that with the previous option.', thread)
|
|
23
39
|
|
|
24
40
|
for await (const chunk of subscription.stream) {
|
|
25
41
|
console.log(chunk)
|
|
@@ -28,7 +44,9 @@ for await (const chunk of subscription.stream) {
|
|
|
28
44
|
|
|
29
45
|
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
46
|
|
|
31
|
-
##
|
|
47
|
+
## Message input
|
|
48
|
+
|
|
49
|
+
### Send a message now
|
|
32
50
|
|
|
33
51
|
Use `sendMessage()` when the user expects the active agent to see the message immediately.
|
|
34
52
|
|
|
@@ -53,7 +71,7 @@ The model receives attributed messages as XML-wrapped user input:
|
|
|
53
71
|
|
|
54
72
|
Messages without attributes are sent as plain user input.
|
|
55
73
|
|
|
56
|
-
|
|
74
|
+
### Queue a message for the next turn
|
|
57
75
|
|
|
58
76
|
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
77
|
|
|
@@ -66,7 +84,9 @@ agent.queueMessage('Also check whether the tests need updates.', {
|
|
|
66
84
|
|
|
67
85
|
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.
|
|
68
86
|
|
|
69
|
-
##
|
|
87
|
+
## Signal context
|
|
88
|
+
|
|
89
|
+
### Control low-level signal behavior
|
|
70
90
|
|
|
71
91
|
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.
|
|
72
92
|
|
|
@@ -88,31 +108,11 @@ const result = agent.sendSignal(
|
|
|
88
108
|
await result.persisted
|
|
89
109
|
```
|
|
90
110
|
|
|
91
|
-
|
|
111
|
+
Pass `ifIdle.streamOptions` when the idle wake-up stream needs options such as model settings, tools, or runtime context.
|
|
92
112
|
|
|
93
|
-
|
|
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.
|
|
99
|
-
|
|
100
|
-
Pass `ifIdle.streamOptions` when the idle wake-up stream needs options such as model settings, tools, or runtime context. You don't need to repeat `memory.resource` or `memory.thread`; Mastra uses the top-level `resourceId` and `threadId` for the thread.
|
|
101
|
-
|
|
102
|
-
```typescript
|
|
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,
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
})
|
|
113
|
-
```
|
|
113
|
+
> **Note:** Visit [`Agent.sendSignal()` reference](https://mastra.ai/reference/agents/agent) for `ifActive`, `ifIdle`, branch attributes, and `streamOptions`.
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
### Send notification context
|
|
116
116
|
|
|
117
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.
|
|
118
118
|
|
|
@@ -143,11 +143,11 @@ The model receives the signal as context like this:
|
|
|
143
143
|
|
|
144
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
145
|
|
|
146
|
-
|
|
146
|
+
#### Storage support
|
|
147
147
|
|
|
148
148
|
Notification inbox storage is available in the storage adapters that support richer memory and signal workflows: [libSQL](https://mastra.ai/reference/storage/libsql), [PostgreSQL](https://mastra.ai/reference/storage/postgresql), and [MongoDB](https://mastra.ai/reference/storage/mongodb). These adapters expose notification records through `getStore('notifications')`.
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
### Send processor context
|
|
151
151
|
|
|
152
152
|
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.
|
|
153
153
|
|
|
@@ -193,50 +193,19 @@ Reactive signals default to `tagName: 'system-reminder'`, so the model receives
|
|
|
193
193
|
|
|
194
194
|
Awaiting `sendSignal()` preserves stream echo ordering when a subscribed thread is active.
|
|
195
195
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
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.
|
|
199
|
-
|
|
200
|
-
```typescript
|
|
201
|
-
agent.sendMessage(
|
|
202
|
-
{
|
|
203
|
-
contents: 'Also cover the edge cases.',
|
|
204
|
-
attributes: { source: 'chat' },
|
|
205
|
-
},
|
|
206
|
-
{
|
|
207
|
-
resourceId: 'user_123',
|
|
208
|
-
threadId: 'thread_456',
|
|
209
|
-
ifActive: { attributes: { delivery: 'while-active' } },
|
|
210
|
-
ifIdle: { attributes: { delivery: 'new-message' } },
|
|
211
|
-
},
|
|
212
|
-
)
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
When the agent is working, the model sees:
|
|
196
|
+
### Conditional attributes
|
|
216
197
|
|
|
217
|
-
|
|
218
|
-
<user source="chat" delivery="while-active">Also cover the edge cases.</user>
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
When the agent is idle:
|
|
198
|
+
Use `ifActive.attributes` and `ifIdle.attributes` to tag input with context that depends on whether the agent is active or idle at delivery time. Top-level `attributes` always apply, and Mastra merges the selected branch's `attributes` into them when the input is accepted.
|
|
222
199
|
|
|
223
|
-
|
|
224
|
-
<user source="chat" delivery="new-message">Also cover the edge cases.</user>
|
|
225
|
-
```
|
|
200
|
+
> **Note:** Visit [`Agent.sendMessage()` reference](https://mastra.ai/reference/agents/agent) and [`Agent.sendSignal()` reference](https://mastra.ai/reference/agents/agent) for branch-specific attributes.
|
|
226
201
|
|
|
227
|
-
|
|
202
|
+
## State and notification signals
|
|
228
203
|
|
|
229
|
-
|
|
204
|
+
### State signals
|
|
230
205
|
|
|
231
206
|
State signals expose named, thread-scoped context lanes. Use them for durable context that changes over time, such as browser state, editor state, or a background watcher result.
|
|
232
207
|
|
|
233
|
-
Each state signal
|
|
234
|
-
|
|
235
|
-
- `id`: The state lane name, such as `browser`.
|
|
236
|
-
- `cacheKey`: A producer-owned key for deduping the current state.
|
|
237
|
-
- `mode`: `snapshot` for an authoritative state copy, or `delta` for a change event.
|
|
238
|
-
|
|
239
|
-
Use `sendStateSignal()` when an external producer detects a state change.
|
|
208
|
+
Use `sendStateSignal()` when an external producer detects a state change. Each state signal identifies a state lane, a producer-owned cache key, and whether the update is a snapshot or delta.
|
|
240
209
|
|
|
241
210
|
```typescript
|
|
242
211
|
await agent.sendStateSignal(
|
|
@@ -258,16 +227,9 @@ await agent.sendStateSignal(
|
|
|
258
227
|
)
|
|
259
228
|
```
|
|
260
229
|
|
|
261
|
-
When Mastra accepts a state signal, it stores compact tracking metadata on the thread.
|
|
262
|
-
|
|
263
|
-
State signal fields have separate roles:
|
|
230
|
+
When Mastra accepts a state signal, it stores compact tracking metadata on the thread. If a producer sends the same `cacheKey` and mode again while that state is still current, Mastra skips the duplicate.
|
|
264
231
|
|
|
265
|
-
|
|
266
|
-
- `value`: The structured snapshot for `mode: 'snapshot'`.
|
|
267
|
-
- `delta`: The structured change for `mode: 'delta'`.
|
|
268
|
-
- `metadata.state`: The runtime tracking envelope with `id`, `mode`, `cacheKey`, `version`, and `threadId`.
|
|
269
|
-
|
|
270
|
-
Use `computeStateSignal()` when a processor owns a state lane. Mastra calls it once per model input step after `processInputStep()`. If the processor omits `id`, Mastra uses the processor id as the state lane id. Set `stateId` when the public state lane should differ from the processor id.
|
|
232
|
+
Use `computeStateSignal()` when a processor owns a state lane. Mastra calls it once per model input step after `processInputStep()`. Visit [`Agent.sendStateSignal()` reference](https://mastra.ai/reference/agents/agent) for state signal fields and return values.
|
|
271
233
|
|
|
272
234
|
```typescript
|
|
273
235
|
import type { ComputeStateSignalArgs, Processor } from '@mastra/core/processors'
|
|
@@ -304,31 +266,15 @@ Mastra passes `lastSnapshot` and `deltasSinceSnapshot` into `computeStateSignal(
|
|
|
304
266
|
|
|
305
267
|
The built-in browser context processor emits state under the `browser` id with snapshot and delta modes.
|
|
306
268
|
|
|
307
|
-
|
|
269
|
+
### Notification signals
|
|
308
270
|
|
|
309
271
|
Notification signals represent external events such as GitHub activity, email, Slack mentions, CI status, incidents, recordings, or direct messages. Use `agent.sendNotificationSignal()` when the event should create a durable inbox record.
|
|
310
272
|
|
|
311
|
-
Notification delivery has two phases
|
|
312
|
-
|
|
313
|
-
- **Ingress**: `agent.sendNotificationSignal()` stores a notification record, then resolves the agent's delivery policy.
|
|
314
|
-
- **Dispatch**: Mastra consumes due records stamped with `deliverAt` or `summaryAt` and emits full notification or summary signals.
|
|
315
|
-
|
|
316
|
-
A notification record stores the source, kind, priority, summary, payload, resource id, thread id, agent id, coalescing keys, and delivery metadata. The delivery decision controls what happens after ingress:
|
|
273
|
+
Notification delivery has two phases. During ingress, `agent.sendNotificationSignal()` stores a notification record and resolves the agent's delivery policy. During dispatch, Mastra consumes due records and emits full notification or summary signals.
|
|
317
274
|
|
|
318
|
-
-
|
|
319
|
-
- `defer`: Keep the record `pending` with `deliverAt`.
|
|
320
|
-
- `summarize`: Keep the record `pending` with `summaryAt`, or emit an immediate summary when the policy requests it.
|
|
321
|
-
- `persist`: Keep the record `pending` in the inbox without scheduled delivery.
|
|
322
|
-
- `discard`: Mark the record `discarded` and emit no signal.
|
|
275
|
+
The default delivery policy is priority-aware. Urgent notifications deliver immediately, while lower-priority notifications may be batched into summaries or wait until the thread is idle.
|
|
323
276
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
| Priority | Active thread | Idle thread |
|
|
327
|
-
| -------- | -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
328
|
-
| `urgent` | Deliver a full notification immediately | Deliver a full notification immediately |
|
|
329
|
-
| `high` | Emit a summary immediately, keep `deliverAt`, then deliver the full notification when the thread is idle | Deliver a full notification immediately |
|
|
330
|
-
| `medium` | Batch with `summaryAt` and later deliver one notification summary | Deliver a full notification immediately |
|
|
331
|
-
| `low` | Batch with `summaryAt` and later deliver one notification summary | Batch with `summaryAt` and later deliver one notification summary without waking the model loop |
|
|
277
|
+
> **Note:** Visit [`Agent.sendNotificationSignal()` reference](https://mastra.ai/reference/agents/agent) for notification fields, [`Agent` constructor reference](https://mastra.ai/reference/agents/agent) for `notifications.deliveryPolicy` configuration, and [`createNotificationInboxTool()` reference](https://mastra.ai/reference/signals/create-notification-inbox-tool) for inbox tool actions.
|
|
332
278
|
|
|
333
279
|
```typescript
|
|
334
280
|
await agent.sendNotificationSignal(
|
|
@@ -364,86 +310,21 @@ Notification summaries tell the model that inbox records are waiting:
|
|
|
364
310
|
|
|
365
311
|
When Mastra emits a summary, it clears `summaryAt` and sets `summarySignalId` on each summarized record. The records stay pending and readable. When Mastra emits a full notification, it sets `deliveredSignalId` and marks the record `delivered`. If the inbox tool reads a notification first, it can inject the full notification signal and mark the record `seen`, which prevents duplicate full delivery.
|
|
366
312
|
|
|
367
|
-
Configure a delivery policy on the agent when some notifications should wait for a different dispatch window or summary rollup.
|
|
313
|
+
Configure a delivery policy on the agent when some notifications should wait for a different dispatch window or summary rollup. Enable scheduled dispatch at the Mastra level when deferred notifications and summary rollups should be delivered automatically.
|
|
368
314
|
|
|
369
|
-
|
|
370
|
-
export const supportAgent = new Agent({
|
|
371
|
-
id: 'support-agent',
|
|
372
|
-
name: 'Support Agent',
|
|
373
|
-
instructions: 'Help the user triage updates.',
|
|
374
|
-
model: 'openai/gpt-5.5',
|
|
375
|
-
notifications: {
|
|
376
|
-
deliveryPolicy: {
|
|
377
|
-
priorities: {
|
|
378
|
-
urgent: 'deliver',
|
|
379
|
-
},
|
|
380
|
-
decide: ({ record }) => {
|
|
381
|
-
if (record.priority === 'low') {
|
|
382
|
-
return {
|
|
383
|
-
action: 'summarize',
|
|
384
|
-
summaryAt: new Date(Date.now() + 30 * 60 * 1000),
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
},
|
|
388
|
-
},
|
|
389
|
-
},
|
|
390
|
-
})
|
|
391
|
-
```
|
|
315
|
+
> **Note:** Visit [`Agent` constructor reference](https://mastra.ai/reference/agents/agent) for `notifications.deliveryPolicy` and [`Mastra` class reference](https://mastra.ai/reference/core/mastra-class) for runtime notification dispatch configuration.
|
|
392
316
|
|
|
393
|
-
|
|
317
|
+
#### Notification inbox tool
|
|
394
318
|
|
|
395
|
-
|
|
396
|
-
export const mastra = new Mastra({
|
|
397
|
-
agents: { supportAgent },
|
|
398
|
-
storage,
|
|
399
|
-
notifications: {
|
|
400
|
-
dispatch: {
|
|
401
|
-
enabled: true,
|
|
402
|
-
cron: '*/1 * * * *',
|
|
403
|
-
batchSize: 100,
|
|
404
|
-
},
|
|
405
|
-
},
|
|
406
|
-
})
|
|
407
|
-
```
|
|
319
|
+
Use `createNotificationInboxTool()` to give agents one tool for inbox actions instead of many CRUD tools. Use `read` after a `<notification-summary>` signal when the agent needs the full records behind the summary. The notification contents are delivered as signals, not as normal tool output.
|
|
408
320
|
|
|
409
|
-
|
|
321
|
+
> **Note:** Visit [`createNotificationInboxTool()` reference](https://mastra.ai/reference/signals/create-notification-inbox-tool) for the setup example, input schema, and action behavior.
|
|
410
322
|
|
|
411
|
-
|
|
323
|
+
`sendNotificationSignal()` requires a storage domain with `notifications` support. Use `sendSignal({ type: 'notification' })` only for lower-level notification-shaped context that should bypass inbox storage.
|
|
412
324
|
|
|
413
|
-
|
|
325
|
+
## Compatibility and APIs
|
|
414
326
|
|
|
415
|
-
|
|
416
|
-
import { createNotificationInboxTool } from '@mastra/core/notifications'
|
|
417
|
-
|
|
418
|
-
const notificationsStorage = await storage.getStore('notifications')
|
|
419
|
-
|
|
420
|
-
export const supportAgent = new Agent({
|
|
421
|
-
id: 'support-agent',
|
|
422
|
-
name: 'Support Agent',
|
|
423
|
-
instructions: 'Help the user triage updates.',
|
|
424
|
-
model: 'openai/gpt-5.5',
|
|
425
|
-
tools: {
|
|
426
|
-
notificationInbox: createNotificationInboxTool({ storage: notificationsStorage }),
|
|
427
|
-
},
|
|
428
|
-
})
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
The tool id is `notification-inbox`. It supports these actions:
|
|
432
|
-
|
|
433
|
-
- `list`: List notifications for the current thread.
|
|
434
|
-
- `read`: Deliver readable full notification signals into the chat when possible, then mark records `seen`.
|
|
435
|
-
- `markSeen`: Mark one record `seen`.
|
|
436
|
-
- `dismiss`: Mark one record `dismissed`.
|
|
437
|
-
- `archive`: Mark one record `archived`.
|
|
438
|
-
- `search`: Search notification summaries in the current thread.
|
|
439
|
-
|
|
440
|
-
The tool uses the current `threadId` from the tool execution context unless one is provided. Use `read` after a `<notification-summary>` signal when the agent needs the full records behind the summary. The `read` result reports how many notifications will be delivered; it doesn't use normal tool output as the main context channel for the notification contents.
|
|
441
|
-
|
|
442
|
-
`sendNotificationSignal()` requires a storage domain with `notifications` support. LibSQL supports notifications. Other storage adapters need matching notification domain support before they can store notification records.
|
|
443
|
-
|
|
444
|
-
Use `sendSignal({ type: 'notification' })` only for lower-level notification-shaped context that should bypass inbox storage.
|
|
445
|
-
|
|
446
|
-
## Compatibility
|
|
327
|
+
### Compatibility
|
|
447
328
|
|
|
448
329
|
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:
|
|
449
330
|
|
|
@@ -454,26 +335,17 @@ Existing stored signal rows and older clients continue to load through the compa
|
|
|
454
335
|
|
|
455
336
|
> **Note:** Visit [Agent signals reference](https://mastra.ai/reference/agents/agent) for the full message, signal, and subscription types.
|
|
456
337
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
When a subscribed run pauses for tool approval, approve or decline the tool call with the subscription-native methods. The call returns a JSON acknowledgement. The resumed chunks arrive through the existing thread subscription.
|
|
338
|
+
### Approve tool calls
|
|
460
339
|
|
|
461
|
-
|
|
462
|
-
await agent.sendToolApproval({
|
|
463
|
-
resourceId: 'user_123',
|
|
464
|
-
threadId: 'thread_456',
|
|
465
|
-
toolCallId: 'tool-call_456',
|
|
466
|
-
approved: true,
|
|
467
|
-
})
|
|
468
|
-
```
|
|
340
|
+
When a subscribed run pauses for tool approval, approve or decline the tool call with the subscription-native methods. The resumed chunks arrive through the existing thread subscription.
|
|
469
341
|
|
|
470
|
-
|
|
342
|
+
> **Note:** Visit [`client.getAgent().sendToolApproval()` reference](https://mastra.ai/reference/client-js/agents) and [server agent routes](https://mastra.ai/reference/server/routes) for request and response shapes.
|
|
471
343
|
|
|
472
|
-
|
|
344
|
+
### Use HTTP routes
|
|
473
345
|
|
|
474
346
|
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. For subscription-native tool approval, use `POST /api/agents/:agentId/send-tool-approval`. See [Server routes reference](https://mastra.ai/reference/server/routes) for request and response schemas.
|
|
475
347
|
|
|
476
|
-
|
|
348
|
+
### Use the client SDK
|
|
477
349
|
|
|
478
350
|
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.
|
|
479
351
|
|
|
@@ -499,9 +371,9 @@ await subscription.processDataStream({
|
|
|
499
371
|
})
|
|
500
372
|
```
|
|
501
373
|
|
|
502
|
-
Use `reconnect: true` for long-lived subscriptions.
|
|
374
|
+
Use `reconnect: true` for long-lived subscriptions. Visit [`client.getAgent().subscribeToThread()` reference](https://mastra.ai/reference/client-js/agents) for reconnect options.
|
|
503
375
|
|
|
504
|
-
|
|
376
|
+
### Keep custom SSE subscriptions alive
|
|
505
377
|
|
|
506
378
|
If you expose your own Server-Sent Events (SSE) endpoint for thread subscriptions, send periodic heartbeat frames while the stream is idle. This keeps browsers, proxies, and load balancers from closing the connection before the next signal or model chunk arrives.
|
|
507
379
|
|
|
@@ -524,7 +396,9 @@ Use heartbeats together with client-side reconnect logic. Heartbeats reduce idle
|
|
|
524
396
|
- [`Agent.sendMessage()`](https://mastra.ai/reference/agents/agent)
|
|
525
397
|
- [`Agent.queueMessage()`](https://mastra.ai/reference/agents/agent)
|
|
526
398
|
- [`Agent.sendSignal()`](https://mastra.ai/reference/agents/agent)
|
|
399
|
+
- [`Agent.sendStateSignal()`](https://mastra.ai/reference/agents/agent)
|
|
527
400
|
- [`Agent.subscribeToThread()`](https://mastra.ai/reference/agents/agent)
|
|
401
|
+
- [`createNotificationInboxTool()`](https://mastra.ai/reference/signals/create-notification-inbox-tool)
|
|
528
402
|
- [`client.getAgent().sendMessage()`](https://mastra.ai/reference/client-js/agents)
|
|
529
403
|
- [`client.getAgent().queueMessage()`](https://mastra.ai/reference/client-js/agents)
|
|
530
404
|
- [`client.getAgent().sendSignal()`](https://mastra.ai/reference/client-js/agents)
|
|
@@ -89,9 +89,9 @@ Each `dist/docs` includes:
|
|
|
89
89
|
|
|
90
90
|
## Context files
|
|
91
91
|
|
|
92
|
-
Mastra provides a root [`llms.txt`](https://mastra.ai/llms.txt) file that contains an overview of all available documentation pages.
|
|
92
|
+
Mastra provides a root [`llms.txt`](https://mastra.ai/llms.txt) file that contains an overview of all available documentation pages. It doesn't provide an `llms-full.txt` file as it's not useful to have all documentation in one file.
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
Instead, each documentation page has its own `llms.txt` file. These files are streamlined markdown files. At the end of each docs page you'll find a link to the corresponding `llms.txt` file.
|
|
95
95
|
|
|
96
96
|
Add `/llms.txt` to any Mastra docs URL to access it. You can also request it by adding a `.md` extension to the end of the URL.
|
|
97
97
|
|
|
@@ -71,4 +71,4 @@ cp .mastra-project.production.json .mastra-project.json
|
|
|
71
71
|
mastra studio deploy --env-file .env.production --yes
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
Each project has its own Studio URL and can send observability data to the Mastra platform. When using [`MastraPlatformExporter`](https://mastra.ai/docs/observability/
|
|
74
|
+
Each project has its own Studio URL and can send observability data to the Mastra platform. When using [`MastraPlatformExporter`](https://mastra.ai/docs/observability/integrations/exporters/mastra-platform), set `MASTRA_PROJECT_ID` and `MASTRA_PLATFORM_ACCESS_TOKEN` per environment so traces route to the matching platform project.
|
|
@@ -32,4 +32,4 @@ Once you're ready to deploy your application to production, use [`mastra studio
|
|
|
32
32
|
|
|
33
33
|
Follow the [Studio on Mastra platform](https://mastra.ai/docs/mastra-platform/studio) and [Server on Mastra platform](https://mastra.ai/docs/mastra-platform/server) docs for step-by-step instructions.
|
|
34
34
|
|
|
35
|
-
If you host your Mastra application on your own infrastructure, you can still send observability data to Mastra platform using the [MastraPlatformExporter](https://mastra.ai/docs/observability/
|
|
35
|
+
If you host your Mastra application on your own infrastructure, you can still send observability data to Mastra platform using the [MastraPlatformExporter](https://mastra.ai/docs/observability/integrations/exporters/mastra-platform).
|