@mastra/mcp-docs-server 1.1.42 → 1.1.43
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/acp.md +21 -158
- package/.docs/docs/agents/processors.md +143 -0
- package/.docs/docs/agents/signals.md +229 -9
- package/.docs/docs/build-with-ai/skills.md +3 -3
- package/.docs/docs/editor/overview.md +11 -10
- package/.docs/docs/getting-started/build-with-ai.md +37 -0
- package/.docs/docs/mastra-platform/observability.md +4 -4
- package/.docs/docs/memory/multi-user-threads.md +1 -1
- package/.docs/docs/memory/working-memory.md +27 -0
- package/.docs/docs/observability/metrics/querying.md +1 -1
- package/.docs/docs/server/pubsub.md +124 -0
- package/.docs/docs/studio/auth.md +20 -0
- package/.docs/reference/acp/acp-agent.md +228 -0
- package/.docs/reference/acp/create-acp-tool.md +131 -0
- package/.docs/reference/agents/agent.md +51 -1
- package/.docs/reference/agents/durable-agent.md +239 -0
- package/.docs/reference/cli/mastra.md +5 -5
- package/.docs/reference/client-js/agents.md +41 -7
- package/.docs/reference/index.md +9 -0
- package/.docs/reference/processors/response-cache.md +2 -2
- package/.docs/reference/pubsub/base.md +168 -0
- package/.docs/reference/pubsub/caching-pubsub.md +102 -0
- package/.docs/reference/pubsub/event-emitter.md +72 -0
- package/.docs/reference/pubsub/google-cloud-pubsub.md +94 -0
- package/.docs/reference/pubsub/redis-streams.md +108 -0
- package/.docs/reference/pubsub/unix-socket-pubsub.md +52 -0
- package/.docs/reference/storage/libsql.md +6 -0
- package/.docs/reference/storage/mongodb.md +3 -0
- package/.docs/reference/storage/postgresql.md +3 -0
- package/CHANGELOG.md +16 -0
- package/package.json +6 -6
- package/.docs/docs/agents/response-caching.md +0 -150
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# RedisStreamsPubSub
|
|
2
|
+
|
|
3
|
+
`RedisStreamsPubSub` is a [`PubSub`](https://mastra.ai/reference/pubsub/base) implementation backed by [Redis Streams](https://redis.io/docs/latest/develop/data-types/streams/). It delivers events across processes and hosts, with persistence, consumer groups, and redelivery on failure.
|
|
4
|
+
|
|
5
|
+
Use it for distributed deployments where several services share an event stream. For single-process delivery, use [`EventEmitterPubSub`](https://mastra.ai/reference/pubsub/event-emitter). For Google Cloud, use [`GoogleCloudPubSub`](https://mastra.ai/reference/pubsub/google-cloud-pubsub).
|
|
6
|
+
|
|
7
|
+
Each topic maps to a Redis stream key. Subscriptions with a group use a Redis consumer group, so members share work round-robin. Subscriptions without a group create a private consumer group, so every subscriber receives every event.
|
|
8
|
+
|
|
9
|
+
`RedisStreamsPubSub` is a pull transport: consumers read events with `XREADGROUP`, so Mastra runs an orchestration worker to read on its behalf.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
**npm**:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @mastra/redis-streams
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**pnpm**:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pnpm add @mastra/redis-streams
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Yarn**:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
yarn add @mastra/redis-streams
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Bun**:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bun add @mastra/redis-streams
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Usage example
|
|
38
|
+
|
|
39
|
+
Provide a Redis connection URL.
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { Mastra } from '@mastra/core'
|
|
43
|
+
import { RedisStreamsPubSub } from '@mastra/redis-streams'
|
|
44
|
+
|
|
45
|
+
export const mastra = new Mastra({
|
|
46
|
+
pubsub: new RedisStreamsPubSub({
|
|
47
|
+
url: 'redis://localhost:6379',
|
|
48
|
+
}),
|
|
49
|
+
})
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Constructor parameters
|
|
53
|
+
|
|
54
|
+
**url** (`string`): Redis connection URL. Falls back to \`redisOptions.url\`. (Default: `redis://localhost:6379`)
|
|
55
|
+
|
|
56
|
+
**keyPrefix** (`string`): Prefix for stream keys. Each topic maps to \`\<keyPrefix>:\<topic>\`. (Default: `mastra:topic`)
|
|
57
|
+
|
|
58
|
+
**blockMs** (`number`): How long, in milliseconds, each read blocks while waiting for new events. (Default: `1000`)
|
|
59
|
+
|
|
60
|
+
**redisOptions** (`RedisClientOptions`): Options passed to the underlying \`redis\` client for advanced configuration.
|
|
61
|
+
|
|
62
|
+
**maxStreamLength** (`number`): Approximate maximum number of entries kept per stream. Set to 0 to disable trimming. (Default: `10000`)
|
|
63
|
+
|
|
64
|
+
**reclaimIntervalMs** (`number`): How often, in milliseconds, a subscription reclaims events that an earlier consumer read but never acknowledged. Set to 0 to disable. (Default: `30000`)
|
|
65
|
+
|
|
66
|
+
**reclaimIdleMs** (`number`): Minimum idle time, in milliseconds, before a pending event is eligible for reclaim. Keep this well above typical processing time to avoid double delivery. (Default: `60000`)
|
|
67
|
+
|
|
68
|
+
**maxDeliveryAttempts** (`number`): Maximum times an event is redelivered through \`nack\` before it is dropped. Pass \`Infinity\` to disable the cap. (Default: `5`)
|
|
69
|
+
|
|
70
|
+
**logger** (`{ debug?: Function; warn?: Function }`): Optional logger for diagnostics. When omitted, suppressed errors are silent.
|
|
71
|
+
|
|
72
|
+
## Properties
|
|
73
|
+
|
|
74
|
+
**supportedModes** (`ReadonlyArray<"pull" | "push">`): Returns \`\["pull"]\`.
|
|
75
|
+
|
|
76
|
+
## Methods
|
|
77
|
+
|
|
78
|
+
`RedisStreamsPubSub` implements the [`PubSub`](https://mastra.ai/reference/pubsub/base) contract. The methods below have behavior specific to this implementation.
|
|
79
|
+
|
|
80
|
+
### `subscribe(topic, cb, options?)`
|
|
81
|
+
|
|
82
|
+
Subscribes to a topic. With `options.group`, members of the group share events through a Redis consumer group. Without a group, the subscriber receives every event through a private consumer group.
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
await pubsub.subscribe('workflow.events', (event, ack, nack) => {
|
|
86
|
+
console.log(event)
|
|
87
|
+
})
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### `flush()`
|
|
91
|
+
|
|
92
|
+
Waits for in-flight publishes to complete.
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
await pubsub.flush()
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### `close()`
|
|
99
|
+
|
|
100
|
+
Closes the Redis connections and stops all subscriptions. Call this during graceful shutdown.
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
await pubsub.close()
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Redelivery and reclaim
|
|
107
|
+
|
|
108
|
+
When a subscriber calls `nack`, the event is republished with an incremented `deliveryAttempt` and the original is acknowledged. Once an event reaches `maxDeliveryAttempts`, it is dropped instead of redelivered. Separately, each subscription periodically reclaims events that an earlier consumer in the group read but never acknowledged, controlled by `reclaimIntervalMs` and `reclaimIdleMs`.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# UnixSocketPubSub
|
|
2
|
+
|
|
3
|
+
`UnixSocketPubSub` is a [`PubSub`](https://mastra.ai/reference/pubsub/base) implementation that delivers events across processes on a single host using a Unix domain socket. It elects one process as a broker, and other processes connect to it as clients. If the broker exits, the remaining clients elect a new broker automatically.
|
|
4
|
+
|
|
5
|
+
Use it when several local processes need to share a stream, such as coordinating thread streams across the Mastra Code terminal interface. For single-process delivery, use [`EventEmitterPubSub`](https://mastra.ai/reference/pubsub/event-emitter). For distributed delivery across hosts, use [`RedisStreamsPubSub`](https://mastra.ai/reference/pubsub/redis-streams) or [`GoogleCloudPubSub`](https://mastra.ai/reference/pubsub/google-cloud-pubsub).
|
|
6
|
+
|
|
7
|
+
`UnixSocketPubSub` is a push transport: events arrive without a read loop, so Mastra does not run a pull worker for it.
|
|
8
|
+
|
|
9
|
+
## Usage example
|
|
10
|
+
|
|
11
|
+
Pass a socket path that every participating process shares.
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { Mastra } from '@mastra/core'
|
|
15
|
+
import { UnixSocketPubSub } from '@mastra/core/events'
|
|
16
|
+
|
|
17
|
+
export const mastra = new Mastra({
|
|
18
|
+
pubsub: new UnixSocketPubSub('/tmp/mastra/events.sock'),
|
|
19
|
+
})
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Constructor parameters
|
|
23
|
+
|
|
24
|
+
**socketPath** (`string`): Path to the Unix domain socket. All processes that share a stream must use the same path.
|
|
25
|
+
|
|
26
|
+
**options** (`UnixSocketPubSubOptions`): Optional configuration.
|
|
27
|
+
|
|
28
|
+
## Properties
|
|
29
|
+
|
|
30
|
+
**socketPath** (`string`): The socket path passed to the constructor.
|
|
31
|
+
|
|
32
|
+
**supportedModes** (`ReadonlyArray<"pull" | "push">`): Returns \`\["push"]\`.
|
|
33
|
+
|
|
34
|
+
**isBroker** (`boolean`): Whether this instance currently acts as the broker.
|
|
35
|
+
|
|
36
|
+
**remoteClientCount** (`number`): Number of remote clients connected to this broker. Always 0 when this instance is not the broker.
|
|
37
|
+
|
|
38
|
+
## Methods
|
|
39
|
+
|
|
40
|
+
`UnixSocketPubSub` implements the [`PubSub`](https://mastra.ai/reference/pubsub/base) contract. The method below is specific to this implementation.
|
|
41
|
+
|
|
42
|
+
### `close()`
|
|
43
|
+
|
|
44
|
+
Closes the socket connection and, when this instance is the broker, releases the broker role. Call this during graceful shutdown.
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
await pubsub.close()
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Broker election
|
|
51
|
+
|
|
52
|
+
The first process to bind the socket becomes the broker and routes events between all connected clients. Other processes connect as clients. When the broker exits, an exclusive lock file serializes the next election so exactly one client becomes the new broker, and the remaining clients resubscribe to it. This avoids a split-brain state where two processes both act as broker.
|
|
@@ -93,6 +93,12 @@ storage: new LibSQLStore({
|
|
|
93
93
|
|
|
94
94
|
**authToken** (`string`): Authentication token for remote libSQL databases.
|
|
95
95
|
|
|
96
|
+
## Managed tables
|
|
97
|
+
|
|
98
|
+
The storage implementation creates the core storage tables automatically, including `mastra_notifications` for notification inbox records and delivery metadata.
|
|
99
|
+
|
|
100
|
+
`LibSQLStore` exposes notification storage through `getStore('notifications')`.
|
|
101
|
+
|
|
96
102
|
## Initialization
|
|
97
103
|
|
|
98
104
|
When you pass storage to the Mastra class, `init()` is called automatically to create the [core schema](https://mastra.ai/reference/storage/overview):
|
|
@@ -97,6 +97,9 @@ The storage implementation handles collection creation and management automatica
|
|
|
97
97
|
- `mastra_traces`: Stores telemetry and tracing data
|
|
98
98
|
- `mastra_scorers`: Stores scoring and evaluation data
|
|
99
99
|
- `mastra_resources`: Stores resource working memory data
|
|
100
|
+
- `mastra_notifications`: Stores notification inbox records and delivery metadata
|
|
101
|
+
|
|
102
|
+
`MongoDBStore` exposes notification storage through `getStore('notifications')`.
|
|
100
103
|
|
|
101
104
|
### Initialization
|
|
102
105
|
|
|
@@ -132,6 +132,9 @@ The storage implementation handles schema creation and updates automatically. It
|
|
|
132
132
|
- `mastra_traces`: Stores telemetry and tracing data
|
|
133
133
|
- `mastra_scorers`: Stores scoring and evaluation data
|
|
134
134
|
- `mastra_resources`: Stores resource working memory data
|
|
135
|
+
- `mastra_notifications`: Stores notification inbox records and delivery metadata
|
|
136
|
+
|
|
137
|
+
`PostgresStore` exposes notification storage through `getStore('notifications')`.
|
|
135
138
|
|
|
136
139
|
### Observability
|
|
137
140
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @mastra/mcp-docs-server
|
|
2
2
|
|
|
3
|
+
## 1.1.43
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`c973db4`](https://github.com/mastra-ai/mastra/commit/c973db428df1b564ff0c35d4b2a90e8f4f1e13fd), [`552285e`](https://github.com/mastra-ai/mastra/commit/552285e5af43cfc680a0972032cab8de8776c6a0), [`77e686c`](https://github.com/mastra-ai/mastra/commit/77e686c264e493e99ae5024e4dfe3ea5d5a09718), [`ece8dba`](https://github.com/mastra-ai/mastra/commit/ece8dba7ec1a5089eee8c33167cd762bfa91e509), [`e751af2`](https://github.com/mastra-ai/mastra/commit/e751af219433fbf4c7035b2d771b4c9ec8813b05), [`e2a8380`](https://github.com/mastra-ai/mastra/commit/e2a838017a7657850404c1e94c70d79ffdc6f14a), [`be3f1cd`](https://github.com/mastra-ai/mastra/commit/be3f1cd81f0e2a649e8eac15a024d542d814aef8), [`a34d9db`](https://github.com/mastra-ai/mastra/commit/a34d9dbc39fedb722f271318e9355ecee70489ab)]:
|
|
8
|
+
- @mastra/core@1.39.0
|
|
9
|
+
- @mastra/mcp@1.9.1
|
|
10
|
+
|
|
11
|
+
## 1.1.43-alpha.0
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [[`c973db4`](https://github.com/mastra-ai/mastra/commit/c973db428df1b564ff0c35d4b2a90e8f4f1e13fd), [`552285e`](https://github.com/mastra-ai/mastra/commit/552285e5af43cfc680a0972032cab8de8776c6a0), [`77e686c`](https://github.com/mastra-ai/mastra/commit/77e686c264e493e99ae5024e4dfe3ea5d5a09718), [`ece8dba`](https://github.com/mastra-ai/mastra/commit/ece8dba7ec1a5089eee8c33167cd762bfa91e509), [`e751af2`](https://github.com/mastra-ai/mastra/commit/e751af219433fbf4c7035b2d771b4c9ec8813b05), [`e2a8380`](https://github.com/mastra-ai/mastra/commit/e2a838017a7657850404c1e94c70d79ffdc6f14a), [`be3f1cd`](https://github.com/mastra-ai/mastra/commit/be3f1cd81f0e2a649e8eac15a024d542d814aef8), [`a34d9db`](https://github.com/mastra-ai/mastra/commit/a34d9dbc39fedb722f271318e9355ecee70489ab)]:
|
|
16
|
+
- @mastra/core@1.39.0-alpha.0
|
|
17
|
+
- @mastra/mcp@1.9.1-alpha.0
|
|
18
|
+
|
|
3
19
|
## 1.1.42
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/mcp-docs-server",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.43",
|
|
4
4
|
"description": "MCP server for accessing Mastra.ai documentation, changelogs, and news.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"jsdom": "^26.1.0",
|
|
29
29
|
"local-pkg": "^1.1.2",
|
|
30
30
|
"zod": "^4.4.3",
|
|
31
|
-
"@mastra/
|
|
32
|
-
"@mastra/
|
|
31
|
+
"@mastra/core": "1.39.0",
|
|
32
|
+
"@mastra/mcp": "^1.9.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@hono/node-server": "^1.19.11",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"tsx": "^4.21.0",
|
|
46
46
|
"typescript": "^6.0.3",
|
|
47
47
|
"vitest": "4.1.5",
|
|
48
|
-
"@internal/
|
|
49
|
-
"@
|
|
50
|
-
"@
|
|
48
|
+
"@internal/lint": "0.0.101",
|
|
49
|
+
"@mastra/core": "1.39.0",
|
|
50
|
+
"@internal/types-builder": "0.0.76"
|
|
51
51
|
},
|
|
52
52
|
"homepage": "https://mastra.ai",
|
|
53
53
|
"repository": {
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
# Response Caching
|
|
2
|
-
|
|
3
|
-
> **Alpha:** This feature is in alpha. Breaking changes may occur without a major version bump until the API is stable.
|
|
4
|
-
|
|
5
|
-
Response caching skips the LLM call and replays a previously cached response when an agent receives an identical request. Use it to reduce latency and avoid paying for repeated calls.
|
|
6
|
-
|
|
7
|
-
Caching is implemented as the [`ResponseCache`](https://mastra.ai/reference/processors/response-cache) input processor. Mastra doesn't provide an agent-level option. To enable caching, register the processor explicitly. This keeps the API surface small while Mastra collects feedback; per-call overrides flow through `RequestContext`.
|
|
8
|
-
|
|
9
|
-
## When to use response caching
|
|
10
|
-
|
|
11
|
-
Reach for it when the same request shape repeats across users or sessions, for example prompt templates, suggested-prompt buttons, agentic search re-asks, or guardrail LLMs that classify the same input over and over. Skip it when calls trigger external side effects through tools, since cache hits replay tool calls without re-executing them.
|
|
12
|
-
|
|
13
|
-
## Quickstart
|
|
14
|
-
|
|
15
|
-
Add a `ResponseCache` to the agent's `inputProcessors` and pass any `MastraServerCache` as the backend. For development, `InMemoryServerCache` works out of the box:
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
import { Agent } from '@mastra/core/agent'
|
|
19
|
-
import { InMemoryServerCache } from '@mastra/core/cache'
|
|
20
|
-
import { ResponseCache } from '@mastra/core/processors'
|
|
21
|
-
|
|
22
|
-
const cache = new InMemoryServerCache()
|
|
23
|
-
|
|
24
|
-
export const searchAgent = new Agent({
|
|
25
|
-
name: 'Search Agent',
|
|
26
|
-
instructions: 'You answer questions concisely.',
|
|
27
|
-
model: 'openai/gpt-5',
|
|
28
|
-
inputProcessors: [new ResponseCache({ cache, ttl: 600 })], // 10 minutes
|
|
29
|
-
})
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
The first call runs the LLM normally and writes the response to the cache. Subsequent calls with an identical resolved prompt return the cached response without invoking the LLM.
|
|
33
|
-
|
|
34
|
-
## Per-call overrides via RequestContext
|
|
35
|
-
|
|
36
|
-
Per-call config flows through `RequestContext`. Use `ResponseCache.context()` to build a fresh context, or `ResponseCache.applyContext()` to merge into one you already have:
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
import { ResponseCache } from '@mastra/core/processors'
|
|
40
|
-
import { RequestContext } from '@mastra/core/request-context'
|
|
41
|
-
|
|
42
|
-
// Fresh context with the override
|
|
43
|
-
await agent.stream('hello', {
|
|
44
|
-
requestContext: ResponseCache.context({ key: 'custom-key', bust: true }),
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
// Or merge into an existing context
|
|
48
|
-
const ctx = new RequestContext()
|
|
49
|
-
ctx.set('caller-meta', { userId: 'u-123' })
|
|
50
|
-
ResponseCache.applyContext(ctx, { bust: true })
|
|
51
|
-
await agent.stream('hello', { requestContext: ctx })
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Three fields are overridable per call:
|
|
55
|
-
|
|
56
|
-
- `key`: String or function. Overrides the auto-derived cache key for this request only.
|
|
57
|
-
- `scope`: String or `null`. Overrides the tenant/user scope for this request only. `null` opts out of scoping.
|
|
58
|
-
- `bust`: Boolean. Skips the cache read but still writes on completion (useful for "force refresh" buttons).
|
|
59
|
-
|
|
60
|
-
`cache`, `ttl`, and `agentId` stay on the constructor. They're instance-level concerns and not safe to vary per call.
|
|
61
|
-
|
|
62
|
-
## Tenant scoping
|
|
63
|
-
|
|
64
|
-
By default, `ResponseCache` looks up `MASTRA_RESOURCE_ID_KEY` on the request context and uses it as the cache scope. This means an agent that already populates the resource id (e.g. via memory) gets per-user isolation automatically. Two users never see each other's cached responses.
|
|
65
|
-
|
|
66
|
-
Override explicitly when you need a different scope:
|
|
67
|
-
|
|
68
|
-
```typescript
|
|
69
|
-
new Agent({
|
|
70
|
-
// ...
|
|
71
|
-
inputProcessors: [
|
|
72
|
-
new ResponseCache({
|
|
73
|
-
cache,
|
|
74
|
-
scope: 'org-123', // explicit tenant scope
|
|
75
|
-
}),
|
|
76
|
-
],
|
|
77
|
-
})
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Pass `scope: null` to deliberately share entries across all callers. Only use this for known-public, non-personalized content.
|
|
81
|
-
|
|
82
|
-
## Custom cache backend
|
|
83
|
-
|
|
84
|
-
`ResponseCache` accepts any `MastraServerCache`. For production, use `RedisCache` from `@mastra/redis`:
|
|
85
|
-
|
|
86
|
-
```typescript
|
|
87
|
-
import { Agent } from '@mastra/core/agent'
|
|
88
|
-
import { ResponseCache } from '@mastra/core/processors'
|
|
89
|
-
import { RedisCache } from '@mastra/redis'
|
|
90
|
-
|
|
91
|
-
const cache = new RedisCache({ url: process.env.REDIS_URL })
|
|
92
|
-
|
|
93
|
-
export const agent = new Agent({
|
|
94
|
-
name: 'Cached Agent',
|
|
95
|
-
instructions: '...',
|
|
96
|
-
model: 'openai/gpt-5',
|
|
97
|
-
inputProcessors: [new ResponseCache({ cache })],
|
|
98
|
-
})
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
For a custom backend, extend `MastraServerCache` and implement its abstract methods (the processor only calls `get` and `set`).
|
|
102
|
-
|
|
103
|
-
## How caching is implemented
|
|
104
|
-
|
|
105
|
-
`ResponseCache` hooks into `processLLMRequest` (cache lookup, short-circuits on hit) and `processLLMResponse` (cache write on completion). Both run inside the agentic loop _after_ memory has loaded and earlier input processors have transformed the prompt.
|
|
106
|
-
|
|
107
|
-
This means the cache key is derived from the resolved `LanguageModelV2Prompt` Mastra is about to send to the model. The key is created _after_ memory has loaded and earlier input processors have run, and each step in an agentic tool loop is independently cached.
|
|
108
|
-
|
|
109
|
-
## What's in the cache key
|
|
110
|
-
|
|
111
|
-
When you don't supply `key`, the processor derives one deterministically from the inputs that change the LLM's response at this step: `agentId`, `stepNumber` (so each step in a tool loop has its own cache entry), `scope`, model identity (`provider`, `modelId`, spec version), and the resolved `prompt` (post-memory + post-processors). Any change to these inputs automatically invalidates the cache.
|
|
112
|
-
|
|
113
|
-
### Customize the cache key
|
|
114
|
-
|
|
115
|
-
Pass `key` as a function on the constructor or per-call to derive your own cache key from any subset of those inputs. The function receives the same inputs the deterministic hash would have consumed and returns a string (or a `Promise<string>`):
|
|
116
|
-
|
|
117
|
-
```typescript
|
|
118
|
-
import { ResponseCache, buildResponseCacheKey } from '@mastra/core/processors'
|
|
119
|
-
|
|
120
|
-
await agent.stream(input, {
|
|
121
|
-
requestContext: ResponseCache.context({
|
|
122
|
-
// Cache only on the model id and the resolved prompt tail — ignore
|
|
123
|
-
// step number, scope, etc.
|
|
124
|
-
key: ({ model, prompt }) => `qa:${model.modelId}:${JSON.stringify(prompt).slice(-200)}`,
|
|
125
|
-
}),
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
// Or reuse the deterministic helper while overriding individual fields:
|
|
129
|
-
await agent.stream(input, {
|
|
130
|
-
requestContext: ResponseCache.context({
|
|
131
|
-
key: inputs => buildResponseCacheKey({ ...inputs, scope: 'global' }),
|
|
132
|
-
}),
|
|
133
|
-
})
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
If the function throws, the processor falls back to the default key derivation so the call still benefits from caching.
|
|
137
|
-
|
|
138
|
-
## How cache hits work
|
|
139
|
-
|
|
140
|
-
When the processor finds a cache hit, it short-circuits the LLM call by returning the cached chunks from `processLLMRequest`. The agentic loop synthesizes a stream from those chunks instead of calling the model. `agent.generate()` collects them into a `FullOutput`; `agent.stream()` returns a `MastraModelOutput` whose chunks come from the cached buffer, so consumers iterating `fullStream` or awaiting `text`, `usage`, and `finishReason` see the cached values.
|
|
141
|
-
|
|
142
|
-
Cache writes happen after the response completes. Failed runs (errors, tripwire activations) aren't cached, so the next call retries cleanly.
|
|
143
|
-
|
|
144
|
-
## Related
|
|
145
|
-
|
|
146
|
-
- [`ResponseCache` reference](https://mastra.ai/reference/processors/response-cache)
|
|
147
|
-
- [Processors](https://mastra.ai/docs/agents/processors)
|
|
148
|
-
- [Guardrails](https://mastra.ai/docs/agents/guardrails)
|
|
149
|
-
- [Agent.stream()](https://mastra.ai/reference/streaming/agents/stream)
|
|
150
|
-
- [Agent.generate()](https://mastra.ai/reference/agents/generate)
|