@mastra/mcp-docs-server 1.1.45 → 1.1.46-alpha.1
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 +64 -190
- 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 +15 -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
|
@@ -231,7 +231,7 @@ const customExporter = new CloudExporter({
|
|
|
231
231
|
### Documentation
|
|
232
232
|
|
|
233
233
|
- [Tracing Overview](https://mastra.ai/docs/observability/tracing/overview): Complete guide
|
|
234
|
-
- [Exporters](https://mastra.ai/docs/observability/
|
|
234
|
+
- [Exporters](https://mastra.ai/docs/observability/integrations/overview): Exporter concepts
|
|
235
235
|
|
|
236
236
|
### Other Exporters
|
|
237
237
|
|
|
@@ -120,7 +120,7 @@ const exporterWithLogger = new ConsoleExporter({
|
|
|
120
120
|
### Documentation
|
|
121
121
|
|
|
122
122
|
- [Tracing Overview](https://mastra.ai/docs/observability/tracing/overview): Complete guide
|
|
123
|
-
- [Exporters](https://mastra.ai/docs/observability/
|
|
123
|
+
- [Exporters](https://mastra.ai/docs/observability/integrations/overview): Exporter concepts
|
|
124
124
|
|
|
125
125
|
### Other Exporters
|
|
126
126
|
|
|
@@ -165,7 +165,7 @@ const customExporter = new DefaultExporter({
|
|
|
165
165
|
### Documentation
|
|
166
166
|
|
|
167
167
|
- [Tracing Overview](https://mastra.ai/docs/observability/tracing/overview): Complete guide
|
|
168
|
-
- [Exporters](https://mastra.ai/docs/observability/
|
|
168
|
+
- [Exporters](https://mastra.ai/docs/observability/integrations/overview): Exporter concepts
|
|
169
169
|
|
|
170
170
|
### Other Exporters
|
|
171
171
|
|
|
@@ -248,7 +248,7 @@ The original `CloudExporter` is preserved unchanged so dashboards or alert rules
|
|
|
248
248
|
### Documentation
|
|
249
249
|
|
|
250
250
|
- [Tracing Overview](https://mastra.ai/docs/observability/tracing/overview): Complete guide
|
|
251
|
-
- [Exporters](https://mastra.ai/docs/observability/
|
|
251
|
+
- [Exporters](https://mastra.ai/docs/observability/integrations/overview): Exporter concepts
|
|
252
252
|
|
|
253
253
|
### Other Exporters
|
|
254
254
|
|
|
@@ -179,7 +179,7 @@ The original `DefaultExporter` is preserved unchanged so dashboards or alert rul
|
|
|
179
179
|
### Documentation
|
|
180
180
|
|
|
181
181
|
- [Tracing Overview](https://mastra.ai/docs/observability/tracing/overview): Complete guide
|
|
182
|
-
- [Exporters](https://mastra.ai/docs/observability/
|
|
182
|
+
- [Exporters](https://mastra.ai/docs/observability/integrations/overview): Exporter concepts
|
|
183
183
|
|
|
184
184
|
### Other Exporters
|
|
185
185
|
|
|
@@ -198,6 +198,6 @@ Tags are stored as a JSON-stringified array in the `mastra.tags` span attribute
|
|
|
198
198
|
|
|
199
199
|
## Related
|
|
200
200
|
|
|
201
|
-
- [OtelExporter Guide](https://mastra.ai/docs/observability/
|
|
202
|
-
- [OtelBridge](https://mastra.ai/docs/observability/
|
|
201
|
+
- [OtelExporter Guide](https://mastra.ai/docs/observability/integrations/exporters/otel): Setup guide with provider configurations
|
|
202
|
+
- [OtelBridge](https://mastra.ai/docs/observability/integrations/bridges/otel): For bidirectional OTEL context integration
|
|
203
203
|
- [Tracing Overview](https://mastra.ai/docs/observability/tracing/overview): General tracing concepts
|
|
@@ -92,4 +92,4 @@ If `spanFilter` throws an error, Mastra keeps the span and logs the error to avo
|
|
|
92
92
|
|
|
93
93
|
- [Tracing overview](https://mastra.ai/docs/observability/tracing/overview) for setup and concepts
|
|
94
94
|
- [Configuration API](https://mastra.ai/reference/observability/tracing/configuration) for `ObservabilityInstanceConfig`
|
|
95
|
-
- [Sensitive data filter](https://mastra.ai/docs/observability/
|
|
95
|
+
- [Sensitive data filter](https://mastra.ai/docs/observability/integrations/processors/sensitive-data-filter) for redacting span data
|
|
@@ -75,6 +75,8 @@ await pubsub.publish('my-topic', {
|
|
|
75
75
|
|
|
76
76
|
Registers a callback to receive events published to a topic. When `options.group` is set, subscribers in the same group compete for messages and each event is delivered to one member. Without a group, every subscriber receives every event.
|
|
77
77
|
|
|
78
|
+
Pass `options.batch` to opt in to batched delivery. The callback signature is unchanged: a batch of N events is delivered as N consecutive `cb(event, ack, nack)` calls in publish order. Batching is honored only when the backend's [`supportsNativeBatching`](#properties) is `true`; other backends ignore the option and deliver events one at a time.
|
|
79
|
+
|
|
78
80
|
```typescript
|
|
79
81
|
await pubsub.subscribe('my-topic', (event, ack, nack) => {
|
|
80
82
|
console.log(event)
|
|
@@ -135,6 +137,8 @@ await pubsub.subscribeFromOffset('my-topic', 42, event => {
|
|
|
135
137
|
|
|
136
138
|
**supportedModes** (`ReadonlyArray<"pull" | "push">`): Delivery modes the implementation supports. Defaults to \`\["pull"]\`.
|
|
137
139
|
|
|
140
|
+
**supportsNativeBatching** (`boolean`): Whether the implementation honors \`options.batch\` on \`subscribe()\`. Defaults to \`false\`. Backends that integrate batching internally override this and return \`true\`.
|
|
141
|
+
|
|
138
142
|
## Types
|
|
139
143
|
|
|
140
144
|
### `Event`
|
|
@@ -157,6 +161,26 @@ await pubsub.subscribeFromOffset('my-topic', 42, event => {
|
|
|
157
161
|
|
|
158
162
|
**group** (`string`): When set, subscribers with the same group compete for messages and each event is delivered to one member. When omitted, every subscriber receives every event.
|
|
159
163
|
|
|
164
|
+
**batch** (`SubscribeBatchOptions`): Opt in to batched delivery for this subscription. When omitted, events are delivered one at a time. Honored only by backends where \`supportsNativeBatching\` is \`true\`.
|
|
165
|
+
|
|
166
|
+
### `SubscribeBatchOptions`
|
|
167
|
+
|
|
168
|
+
Per-subscription batching policy. The callback signature does not change; a batch of N events becomes N consecutive callback invocations in publish order.
|
|
169
|
+
|
|
170
|
+
**maxSize** (`number`): Maximum events held before forcing a flush.
|
|
171
|
+
|
|
172
|
+
**maxWaitMs** (`number`): Maximum time in milliseconds the oldest event may sit in the buffer. The timer starts when the buffer transitions from empty to non-empty.
|
|
173
|
+
|
|
174
|
+
**minIntervalMs** (`number`): Minimum time in milliseconds between consecutive batch deliveries. Even when \`maxSize\` or \`maxWaitMs\` would fire, the buffer holds until this interval has elapsed since the last delivery.
|
|
175
|
+
|
|
176
|
+
**isImmediate** (`(event: Event) => boolean`): When it returns \`true\` for an event, the buffer flushes immediately on publish, subject to \`minIntervalMs\`. A per-event escape hatch.
|
|
177
|
+
|
|
178
|
+
**coalesce** (`(events: Event[]) => Event[]`): Applied to the queued batch before delivery to drop superseded events. Must return a subset of its input by reference identity; returning freshly constructed \`Event\` objects is a contract violation and discards the whole batch. Ordering of kept events is preserved.
|
|
179
|
+
|
|
180
|
+
**maxBufferSize** (`number`): Maximum events the buffer may hold before overflow handling kicks in. Events flagged immediate are never dropped on overflow. (Default: `256`)
|
|
181
|
+
|
|
182
|
+
**overflow** (`"drop-oldest" | "drop-newest" | "coalesce-or-drop-oldest"`): Overflow strategy when the buffer exceeds \`maxBufferSize\`. \`coalesce-or-drop-oldest\` runs \`coalesce\` first, then drops oldest if still over budget. (Default: `coalesce-or-drop-oldest`)
|
|
183
|
+
|
|
160
184
|
### `EventCallback`
|
|
161
185
|
|
|
162
186
|
The callback signature for subscribers: `(event: Event, ack?: () => Promise<void>, nack?: () => Promise<void>) => void`.
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
Use it to build resumable streams on top of a transport that does not keep history, such as [`EventEmitterPubSub`](https://mastra.ai/reference/pubsub/event-emitter). Transports that already persist events, such as [`RedisStreamsPubSub`](https://mastra.ai/reference/pubsub/redis-streams), do not need this wrapper.
|
|
6
6
|
|
|
7
|
+
`CachingPubSub` is transparent to batching: `subscribe()` forwards `options.batch` to the inner pub/sub, and `supportsNativeBatching` mirrors the inner's value. Wrapping an inner that does not support batching results in unbatched delivery even when `options.batch` is passed.
|
|
8
|
+
|
|
7
9
|
## Usage example
|
|
8
10
|
|
|
9
11
|
Wrap an inner pub/sub and provide a server cache to store events.
|
|
@@ -38,6 +40,10 @@ const pubsub = withCaching(new EventEmitterPubSub(), new InMemoryServerCache())
|
|
|
38
40
|
|
|
39
41
|
**options** (`CachingPubSubOptions`): Optional configuration.
|
|
40
42
|
|
|
43
|
+
## Properties
|
|
44
|
+
|
|
45
|
+
**supportsNativeBatching** (`boolean`): Mirrors the inner pub/sub. Returns \`true\` only when the wrapped implementation supports batching.
|
|
46
|
+
|
|
41
47
|
## Methods
|
|
42
48
|
|
|
43
49
|
`CachingPubSub` implements the [`PubSub`](https://mastra.ai/reference/pubsub/base) contract. It overrides the replay methods to read cached events. The methods below describe the caching behavior.
|
|
@@ -29,14 +29,26 @@ const emitter = new EventEmitter()
|
|
|
29
29
|
const pubsub = new EventEmitterPubSub(emitter)
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
To surface batched-delivery errors, pass a logger:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { EventEmitterPubSub } from '@mastra/core/events'
|
|
36
|
+
|
|
37
|
+
const pubsub = new EventEmitterPubSub(undefined, { logger })
|
|
38
|
+
```
|
|
39
|
+
|
|
32
40
|
## Constructor parameters
|
|
33
41
|
|
|
34
42
|
**existingEmitter** (`EventEmitter`): An existing Node.js EventEmitter to use for delivery. When omitted, a new EventEmitter is created.
|
|
35
43
|
|
|
44
|
+
**options** (`EventEmitterPubSubOptions`): Optional configuration.
|
|
45
|
+
|
|
36
46
|
## Properties
|
|
37
47
|
|
|
38
48
|
**supportedModes** (`ReadonlyArray<"pull" | "push">`): Returns \`\["pull", "push"]\`. The emitter can serve a pull-style worker or push events directly to listeners.
|
|
39
49
|
|
|
50
|
+
**supportsNativeBatching** (`boolean`): Returns \`true\`. Subscribers can opt in to batched delivery with \`options.batch\`.
|
|
51
|
+
|
|
40
52
|
## Methods
|
|
41
53
|
|
|
42
54
|
`EventEmitterPubSub` implements the [`PubSub`](https://mastra.ai/reference/pubsub/base) contract. The methods below have behavior specific to this implementation.
|
|
@@ -45,6 +57,8 @@ const pubsub = new EventEmitterPubSub(emitter)
|
|
|
45
57
|
|
|
46
58
|
Registers a callback for a topic. Without `options.group`, every subscriber receives every event. With a group, events are distributed round-robin across members of that group.
|
|
47
59
|
|
|
60
|
+
Pass `options.batch` to opt in to batched delivery. See [Batching](#batching) below.
|
|
61
|
+
|
|
48
62
|
```typescript
|
|
49
63
|
await pubsub.subscribe('workflow.events', (event, ack, nack) => {
|
|
50
64
|
console.log(event)
|
|
@@ -69,4 +83,25 @@ await pubsub.close()
|
|
|
69
83
|
|
|
70
84
|
## Redelivery
|
|
71
85
|
|
|
72
|
-
When a grouped subscriber calls `nack`, the event is redelivered to the group after a short delay, and its `deliveryAttempt` count increases. Calling `ack` clears the tracking for that event. Fan-out subscribers receive no-op `ack` and `nack` functions, since each event reaches every subscriber once.
|
|
86
|
+
When a grouped subscriber calls `nack`, the event is redelivered to the group after a short delay, and its `deliveryAttempt` count increases. Calling `ack` clears the tracking for that event. Fan-out subscribers receive no-op `ack` and `nack` functions, since each event reaches every subscriber once.
|
|
87
|
+
|
|
88
|
+
## Batching
|
|
89
|
+
|
|
90
|
+
`EventEmitterPubSub` honors `options.batch` natively. When a subscriber opts in, events are held in a per-subscriber in-memory buffer and delivered as consecutive callback invocations once a flush condition is met. Both fan-out and group subscribers can batch. See [`SubscribeBatchOptions`](https://mastra.ai/reference/pubsub/base) for the full policy.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
await pubsub.subscribe(
|
|
94
|
+
'workflow.events',
|
|
95
|
+
event => {
|
|
96
|
+
console.log(event)
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
batch: {
|
|
100
|
+
maxSize: 10, // flush once 10 events have queued
|
|
101
|
+
maxWaitMs: 500, // ...or after 500ms, whichever comes first
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The buffer is in-memory and per-process, so batched state is not persisted and does not survive a restart. A flush triggered by `maxWaitMs` is best-effort: if a step such as a throwing `coalesce` fails, the error is surfaced through the configured `logger` rather than thrown. `flush()` drains every batched subscriber buffer before resolving.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# createNotificationInboxTool()
|
|
2
|
+
|
|
3
|
+
**Added in:** `@mastra/core@1.39.0`
|
|
4
|
+
|
|
5
|
+
`createNotificationInboxTool()` creates a Mastra tool that lets an agent inspect and manage notification inbox records for the current thread.
|
|
6
|
+
|
|
7
|
+
Use this tool with durable notification signals. For sending notification records, see [`Agent.sendNotificationSignal()`](https://mastra.ai/reference/agents/agent).
|
|
8
|
+
|
|
9
|
+
## Usage example
|
|
10
|
+
|
|
11
|
+
The following example adds the inbox tool to an agent.
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { Agent } from '@mastra/core/agent'
|
|
15
|
+
import { createNotificationInboxTool } from '@mastra/core/notifications'
|
|
16
|
+
|
|
17
|
+
const notificationsStorage = await storage.getStore('notifications')
|
|
18
|
+
|
|
19
|
+
export const supportAgent = new Agent({
|
|
20
|
+
id: 'support-agent',
|
|
21
|
+
name: 'Support Agent',
|
|
22
|
+
instructions: 'Help the user triage updates.',
|
|
23
|
+
model: 'openai/gpt-5.5',
|
|
24
|
+
tools: {
|
|
25
|
+
notificationInbox: createNotificationInboxTool({ storage: notificationsStorage }),
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Parameters
|
|
31
|
+
|
|
32
|
+
**options** (`object`): Tool configuration.
|
|
33
|
+
|
|
34
|
+
**options.storage** (`NotificationsStorage`): Notification storage domain returned by \`storage.getStore('notifications')\`.
|
|
35
|
+
|
|
36
|
+
## Tool input
|
|
37
|
+
|
|
38
|
+
The generated tool has the id `notification-inbox` and accepts these input fields.
|
|
39
|
+
|
|
40
|
+
**action** (`'list' | 'read' | 'markSeen' | 'dismiss' | 'archive' | 'search'`): Inbox action to perform.
|
|
41
|
+
|
|
42
|
+
**threadId** (`string`): Thread ID to inspect. Defaults to the current agent thread when available.
|
|
43
|
+
|
|
44
|
+
**id** (`string`): Notification ID. Required for \`markSeen\`, \`dismiss\`, and \`archive\`. Optional for \`read\`.
|
|
45
|
+
|
|
46
|
+
**status** (`'pending' | 'delivered' | 'seen' | 'dismissed' | 'archived' | 'discarded'`): Status filter for list, read, or search actions.
|
|
47
|
+
|
|
48
|
+
**priority** (`'low' | 'medium' | 'high' | 'urgent'`): Priority filter for list, read, or search actions.
|
|
49
|
+
|
|
50
|
+
**source** (`string`): Source filter for list, read, or search actions.
|
|
51
|
+
|
|
52
|
+
**query** (`string`): Search query. Required when \`action\` is \`search\`.
|
|
53
|
+
|
|
54
|
+
**limit** (`number`): Maximum number of notifications to return. Must be a positive integer.
|
|
55
|
+
|
|
56
|
+
## Actions
|
|
57
|
+
|
|
58
|
+
| Action | Description |
|
|
59
|
+
| ---------- | --------------------------------------------------------------------------------------- |
|
|
60
|
+
| `list` | Returns matching notifications. |
|
|
61
|
+
| `read` | Delivers readable notification contents as signals and marks delivered records as seen. |
|
|
62
|
+
| `markSeen` | Marks one notification as seen. |
|
|
63
|
+
| `dismiss` | Marks one notification as dismissed. |
|
|
64
|
+
| `archive` | Marks one notification as archived. |
|
|
65
|
+
| `search` | Searches notifications by query and optional filters. |
|
|
66
|
+
|
|
67
|
+
When `read` finds pending or delivered notifications, the tool delivers their contents as notification signals instead of returning the full contents as normal tool output. Use this after a `<notification-summary>` signal when the agent needs the full records behind the summary.
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
# SignalProvider
|
|
2
|
+
|
|
3
|
+
**Added in:** `@mastra/core@1.39.0`
|
|
4
|
+
|
|
5
|
+
Abstract base class for building signal providers. A signal provider monitors external sources (APIs, webhooks, event streams) and pushes notification signals into agent threads through a built-in subscription registry.
|
|
6
|
+
|
|
7
|
+
Signal providers aren't processors by default. Providers that need to intercept agent execution return processors from `getInputProcessors()` or `getOutputProcessors()`. Providers that expose agent-callable tools return them from `getTools()`.
|
|
8
|
+
|
|
9
|
+
For a ready-to-use webhook-based provider, see [`WebhookSignalProvider`](https://mastra.ai/reference/signals/webhook-signal-provider).
|
|
10
|
+
|
|
11
|
+
## Usage example
|
|
12
|
+
|
|
13
|
+
Polling provider that checks an API every 30 seconds:
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { SignalProvider } from '@mastra/core/signals'
|
|
17
|
+
import type { SignalSubscription } from '@mastra/core/signals'
|
|
18
|
+
|
|
19
|
+
class SlackSignals extends SignalProvider<'slack-signals'> {
|
|
20
|
+
readonly id = 'slack-signals'
|
|
21
|
+
readonly pollInterval = 30_000
|
|
22
|
+
|
|
23
|
+
async poll(subscriptions: SignalSubscription[]) {
|
|
24
|
+
for (const sub of subscriptions) {
|
|
25
|
+
const messages = await fetchSlackMessages(sub.externalResourceId)
|
|
26
|
+
if (messages.length > 0) {
|
|
27
|
+
await this.notify(
|
|
28
|
+
{
|
|
29
|
+
source: 'slack',
|
|
30
|
+
kind: 'new-messages',
|
|
31
|
+
summary: `${messages.length} new messages in ${sub.externalResourceId}`,
|
|
32
|
+
},
|
|
33
|
+
{ threadId: sub.threadId, resourceId: sub.resourceId },
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Register with an agent:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { Agent } from '@mastra/core/agent'
|
|
45
|
+
|
|
46
|
+
const agent = new Agent({
|
|
47
|
+
signals: [new SlackSignals()],
|
|
48
|
+
})
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The agent calls `connect(this)`, registers any processors or tools the provider returns, and starts polling.
|
|
52
|
+
|
|
53
|
+
## Constructor parameters
|
|
54
|
+
|
|
55
|
+
`SignalProvider` is abstract. Subclasses call `super()` with no arguments.
|
|
56
|
+
|
|
57
|
+
## Properties
|
|
58
|
+
|
|
59
|
+
**id** (`TId extends string`): Unique identifier for this provider. Subclasses must implement this as a readonly property.
|
|
60
|
+
|
|
61
|
+
**name** (`string`): Human-readable display name for the provider.
|
|
62
|
+
|
|
63
|
+
**pollInterval** (`number`): Poll interval in milliseconds. When set, the framework calls \`poll()\` on this interval. Leave \`undefined\` or \`0\` for webhook-only providers.
|
|
64
|
+
|
|
65
|
+
**isConnected** (`boolean`): Whether this provider is connected to an agent. Returns \`true\` after \`connect()\` is called. Used internally to skip re-wiring during \`Agent.\_\_fork()\`.
|
|
66
|
+
|
|
67
|
+
## Methods
|
|
68
|
+
|
|
69
|
+
### Connection
|
|
70
|
+
|
|
71
|
+
#### `connect(agent)`
|
|
72
|
+
|
|
73
|
+
Called by the Agent constructor. Establishes the bidirectional link so the provider can send signals back to the agent. Override to run additional setup after the link is established. Always call `super.connect(agent)`.
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
class MySignals extends SignalProvider<'my-signals'> {
|
|
77
|
+
readonly id = 'my-signals'
|
|
78
|
+
|
|
79
|
+
override connect(agent) {
|
|
80
|
+
super.connect(agent)
|
|
81
|
+
// additional setup after agent link is established
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### `__registerMastra(mastra)`
|
|
87
|
+
|
|
88
|
+
Called when the provider's agent is registered with a Mastra instance. Override to access storage or other Mastra services. Always call `super.__registerMastra(mastra)`.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
override __registerMastra(mastra) {
|
|
92
|
+
super.__registerMastra(mastra)
|
|
93
|
+
// this.mastra is now available
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Processor and tool integration
|
|
98
|
+
|
|
99
|
+
#### `getInputProcessors()`
|
|
100
|
+
|
|
101
|
+
Return input processors this provider needs to be registered with the agent. Override when your provider intercepts agent input steps (for example, injecting context hints or detecting tool calls).
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
getInputProcessors() {
|
|
105
|
+
return [this]
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Returns: `InputProcessorOrWorkflow[]`
|
|
110
|
+
|
|
111
|
+
#### `getOutputProcessors()`
|
|
112
|
+
|
|
113
|
+
Return output processors this provider needs to be registered with the agent. Override when your provider intercepts agent output steps.
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
getOutputProcessors() {
|
|
117
|
+
return [this]
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Returns: `OutputProcessorOrWorkflow[]`
|
|
122
|
+
|
|
123
|
+
#### `getTools()`
|
|
124
|
+
|
|
125
|
+
Return tools this provider exposes to the agent. Override when your provider adds agent-callable tools such as subscribe or unsubscribe commands.
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
getTools() {
|
|
129
|
+
return {
|
|
130
|
+
subscribe_pr: createTool({ /* ... */ }),
|
|
131
|
+
unsubscribe_pr: createTool({ /* ... */ }),
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Returns: `Record<string, unknown>`
|
|
137
|
+
|
|
138
|
+
### Subscription tracking
|
|
139
|
+
|
|
140
|
+
#### `subscribe(target, externalResourceId, metadata?)`
|
|
141
|
+
|
|
142
|
+
Subscribe a thread to an external resource. This is a protected method — call it from within your provider implementation.
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
const sub = this.subscribe(
|
|
146
|
+
{ threadId: 'thread-1', resourceId: 'user-1' },
|
|
147
|
+
'github:mastra-ai/mastra#123',
|
|
148
|
+
{ pr: 123 },
|
|
149
|
+
)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Returns: `SignalSubscription` — the created subscription, or the existing one with merged metadata.
|
|
153
|
+
|
|
154
|
+
**target** (`SignalProviderTarget`): The thread to subscribe. Must include \`threadId\` and \`resourceId\`.
|
|
155
|
+
|
|
156
|
+
**externalResourceId** (`string`): Provider-specific identifier for the external resource (for example, \`"github:owner/repo#123"\`).
|
|
157
|
+
|
|
158
|
+
**metadata** (`Record<string, unknown>`): Additional data to store with the subscription. Merged into existing metadata on duplicate subscribes.
|
|
159
|
+
|
|
160
|
+
#### `unsubscribe(target, externalResourceId)`
|
|
161
|
+
|
|
162
|
+
Remove a subscription.
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
const removed = this.unsubscribe(
|
|
166
|
+
{ threadId: 'thread-1', resourceId: 'user-1' },
|
|
167
|
+
'github:mastra-ai/mastra#123',
|
|
168
|
+
)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Returns: `boolean` — `true` if removed, `false` if no matching subscription existed.
|
|
172
|
+
|
|
173
|
+
#### `getSubscriptions()`
|
|
174
|
+
|
|
175
|
+
Return all active subscriptions for this provider.
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
const allSubs = this.getSubscriptions()
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Returns: `SignalSubscription[]`
|
|
182
|
+
|
|
183
|
+
#### `getSubscriptionsForResource(externalResourceId)`
|
|
184
|
+
|
|
185
|
+
Return all subscriptions for a specific external resource.
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
const subs = this.getSubscriptionsForResource('github:mastra-ai/mastra#123')
|
|
189
|
+
for (const sub of subs) {
|
|
190
|
+
await this.notify(
|
|
191
|
+
{ source: 'my-provider', kind: 'update', summary: 'Resource updated' },
|
|
192
|
+
{ threadId: sub.threadId, resourceId: sub.resourceId },
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Returns: `SignalSubscription[]`
|
|
198
|
+
|
|
199
|
+
#### `getSubscriptionsForThread(target)`
|
|
200
|
+
|
|
201
|
+
Return all subscriptions for a specific thread.
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
const subs = this.getSubscriptionsForThread({
|
|
205
|
+
threadId: 'thread-1',
|
|
206
|
+
resourceId: 'user-1',
|
|
207
|
+
})
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Returns: `SignalSubscription[]`
|
|
211
|
+
|
|
212
|
+
#### `hasSubscription(target, externalResourceId)`
|
|
213
|
+
|
|
214
|
+
Check whether a subscription exists.
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
if (this.hasSubscription(target, 'github:mastra-ai/mastra#123')) {
|
|
218
|
+
// already subscribed
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Returns: `boolean`
|
|
223
|
+
|
|
224
|
+
#### `unsubscribeAll(target)`
|
|
225
|
+
|
|
226
|
+
Remove all subscriptions for a thread.
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
const removed = this.unsubscribeAll({
|
|
230
|
+
threadId: 'thread-1',
|
|
231
|
+
resourceId: 'user-1',
|
|
232
|
+
})
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Returns: `number` — count of removed subscriptions.
|
|
236
|
+
|
|
237
|
+
#### `subscriptionCount`
|
|
238
|
+
|
|
239
|
+
Total number of active subscriptions for this provider.
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
if (this.subscriptionCount === 0) {
|
|
243
|
+
// nothing to poll
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Returns: `number`
|
|
248
|
+
|
|
249
|
+
### Polling
|
|
250
|
+
|
|
251
|
+
#### `poll(subscriptions)`
|
|
252
|
+
|
|
253
|
+
Called on each poll cycle with all active subscriptions. Override to check external sources and emit notifications. The framework prevents overlapping poll cycles — if a `poll()` call takes longer than `pollInterval`, the next cycle is skipped.
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
async poll(subscriptions: SignalSubscription[]) {
|
|
257
|
+
for (const sub of subscriptions) {
|
|
258
|
+
const events = await checkExternalSource(sub.externalResourceId)
|
|
259
|
+
for (const event of events) {
|
|
260
|
+
await this.notify(
|
|
261
|
+
{ source: 'my-provider', kind: event.type, summary: event.message },
|
|
262
|
+
{ threadId: sub.threadId, resourceId: sub.resourceId },
|
|
263
|
+
)
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
#### `startPolling()`
|
|
270
|
+
|
|
271
|
+
Start the polling timer. Called by the Agent after `connect()`. Idempotent — calling multiple times has no effect.
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
provider.startPolling()
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
#### `stopPolling()`
|
|
278
|
+
|
|
279
|
+
Stop the polling timer.
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
provider.stopPolling()
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Webhooks
|
|
286
|
+
|
|
287
|
+
#### `handleWebhook(request)`
|
|
288
|
+
|
|
289
|
+
Handle an incoming webhook request. Override to parse the payload, match it to subscriptions, and emit notification signals. See [`WebhookSignalProvider`](https://mastra.ai/reference/signals/webhook-signal-provider) for a ready-to-use implementation.
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
async handleWebhook(request) {
|
|
293
|
+
const payload = request.body as { repo: string, event: string }
|
|
294
|
+
const subs = this.getSubscriptionsForResource(payload.repo)
|
|
295
|
+
|
|
296
|
+
for (const sub of subs) {
|
|
297
|
+
await this.notify(
|
|
298
|
+
{ source: 'github', kind: payload.event, summary: `Event on ${payload.repo}` },
|
|
299
|
+
{ threadId: sub.threadId, resourceId: sub.resourceId },
|
|
300
|
+
)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return { status: 200, body: { matched: subs.length } }
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Returns: `Promise<{ status?: number; body?: unknown }>`
|
|
308
|
+
|
|
309
|
+
### Lifecycle
|
|
310
|
+
|
|
311
|
+
#### `start()`
|
|
312
|
+
|
|
313
|
+
Called after `connect()` to run async initialization. Override when setup requires the agent or Mastra instance to be available.
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
async start() {
|
|
317
|
+
await this.loadInitialState()
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
#### `stop()`
|
|
322
|
+
|
|
323
|
+
Called on shutdown. The default implementation stops polling and clears all subscriptions.
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
provider.stop()
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Notifications
|
|
330
|
+
|
|
331
|
+
#### `notify(notification, target)`
|
|
332
|
+
|
|
333
|
+
Send a notification signal to the connected agent. This is a protected convenience wrapper around `agent.sendNotificationSignal()`.
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
await this.notify(
|
|
337
|
+
{
|
|
338
|
+
source: 'my-provider',
|
|
339
|
+
kind: 'pr-updated',
|
|
340
|
+
summary: 'PR #123 was updated',
|
|
341
|
+
priority: 'high',
|
|
342
|
+
payload: { prNumber: 123 },
|
|
343
|
+
},
|
|
344
|
+
{ threadId: 'thread-1', resourceId: 'user-1' },
|
|
345
|
+
)
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**notification** (`object`): The notification payload.
|
|
349
|
+
|
|
350
|
+
**notification.source** (`string`): Identifier for the notification source.
|
|
351
|
+
|
|
352
|
+
**notification.kind** (`string`): Type of event (for example, \`"pr-updated"\`, \`"new-message"\`).
|
|
353
|
+
|
|
354
|
+
**notification.summary** (`string`): Human-readable summary of the event.
|
|
355
|
+
|
|
356
|
+
**notification.priority** (`"high" | "medium" | "low"`): Notification priority.
|
|
357
|
+
|
|
358
|
+
**notification.payload** (`unknown`): Arbitrary data attached to the notification.
|
|
359
|
+
|
|
360
|
+
**target** (`SignalProviderTarget`): The thread to notify. Must include \`threadId\` and \`resourceId\`.
|
|
361
|
+
|
|
362
|
+
## Types
|
|
363
|
+
|
|
364
|
+
### `SignalSubscription`
|
|
365
|
+
|
|
366
|
+
The subscription object returned by `subscribe()`.
|
|
367
|
+
|
|
368
|
+
**id** (`string`): Unique identifier for the subscription.
|
|
369
|
+
|
|
370
|
+
**providerId** (`string`): The provider that owns this subscription.
|
|
371
|
+
|
|
372
|
+
**threadId** (`string`): The thread receiving signals.
|
|
373
|
+
|
|
374
|
+
**resourceId** (`string`): The resource owning the thread.
|
|
375
|
+
|
|
376
|
+
**externalResourceId** (`string`): Provider-specific identifier for the external resource (for example, \`"github:owner/repo#123"\`).
|
|
377
|
+
|
|
378
|
+
**subscribedAt** (`Date`): When the subscription was created.
|
|
379
|
+
|
|
380
|
+
**metadata** (`Record<string, unknown>`): Provider-specific metadata stored with the subscription.
|
|
381
|
+
|
|
382
|
+
### `SignalProviderTarget`
|
|
383
|
+
|
|
384
|
+
Identifies a specific agent thread.
|
|
385
|
+
|
|
386
|
+
**threadId** (`string`): The thread to target.
|
|
387
|
+
|
|
388
|
+
**resourceId** (`string`): The resource owning the thread.
|
|
389
|
+
|
|
390
|
+
**agentId** (`string`): Agent identifier.
|
|
391
|
+
|
|
392
|
+
## Type guard
|
|
393
|
+
|
|
394
|
+
### `isSignalProvider(obj)`
|
|
395
|
+
|
|
396
|
+
Runtime check for `SignalProvider` instances.
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
import { isSignalProvider } from '@mastra/core/signals'
|
|
400
|
+
|
|
401
|
+
if (isSignalProvider(obj)) {
|
|
402
|
+
obj.connect(agent)
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
Returns: `boolean`
|