@mastra/mcp-docs-server 1.2.19-alpha.0 → 1.2.19-alpha.14
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/channels.md +1 -0
- package/.docs/docs/deployment/mastra-server.md +19 -0
- package/.docs/docs/deployment/workers.md +2 -2
- package/.docs/docs/evals/built-in-scorers.md +1 -0
- package/.docs/docs/evals/multi-turn.md +84 -1
- package/.docs/docs/evals/overview.md +63 -1
- package/.docs/docs/harness/durable-agents.md +1 -1
- package/.docs/docs/mastra-platform/deploy.md +101 -0
- package/.docs/docs/mastra-platform/server.md +6 -11
- package/.docs/docs/mastra-platform/studio.md +8 -10
- package/.docs/docs/observability/integrations/exporters/mastra-storage.md +19 -14
- package/.docs/docs/sandbox/filesystem.md +8 -8
- package/.docs/docs/sandbox/overview.md +33 -66
- package/.docs/docs/server/middleware.md +4 -0
- package/.docs/docs/server/server-adapters.md +12 -8
- package/.docs/docs/storage.md +2 -0
- package/.docs/integrations/channels/imessage.md +150 -8
- package/.docs/integrations/databases/elasticsearch.md +156 -0
- package/.docs/integrations/databases/libsql.md +16 -0
- package/.docs/integrations/databases/mongodb.md +1 -1
- package/.docs/integrations/databases/postgresql.md +26 -0
- package/.docs/integrations/databases/valkey.md +99 -0
- package/.docs/integrations/deploy/render.md +47 -61
- package/.docs/integrations/sandboxes/e2b.md +2 -0
- package/.docs/integrations/tools/parallel.md +240 -0
- package/.docs/integrations.md +3 -0
- package/.docs/models/environment-variables.md +2 -0
- package/.docs/models/gateways/merge-gateway.md +2 -1
- package/.docs/models/gateways/netlify.md +10 -5
- package/.docs/models/gateways/openrouter.md +8 -9
- package/.docs/models/gateways/vercel.md +7 -6
- package/.docs/models/index.md +1 -1
- package/.docs/models/providers/agentrouter.md +17 -34
- package/.docs/models/providers/aki-io.md +14 -13
- package/.docs/models/providers/chutes.md +2 -2
- package/.docs/models/providers/crof.md +3 -8
- package/.docs/models/providers/crossmodel.md +56 -55
- package/.docs/models/providers/deepseek.md +8 -7
- package/.docs/models/providers/digitalocean.md +11 -11
- package/.docs/models/providers/edenai.md +14 -14
- package/.docs/models/providers/google.md +3 -3
- package/.docs/models/providers/hyper.md +7 -7
- package/.docs/models/providers/inceptron.md +1 -1
- package/.docs/models/providers/kilo.md +24 -20
- package/.docs/models/providers/llmgateway-providers.md +17 -8
- package/.docs/models/providers/llmgateway.md +3 -5
- package/.docs/models/providers/nano-gpt.md +24 -13
- package/.docs/models/providers/nvidia.md +3 -1
- package/.docs/models/providers/ofox.md +114 -110
- package/.docs/models/providers/opencode-go.md +26 -23
- package/.docs/models/providers/opencode.md +1 -1
- package/.docs/models/providers/opper.md +112 -0
- package/.docs/models/providers/requesty.md +1 -1
- package/.docs/models/providers/scaleway.md +2 -1
- package/.docs/models/providers.md +2 -0
- package/.docs/reference/agents/channels.md +1 -1
- package/.docs/reference/ai-sdk/handle-chat-stream.md +11 -0
- package/.docs/reference/ai-sdk/with-sse-heartbeat.md +47 -0
- package/.docs/reference/core/mastra-class.md +1 -1
- package/.docs/reference/evals/checks.md +6 -0
- package/.docs/reference/evals/multi-turn-judge.md +101 -0
- package/.docs/reference/index.md +4 -0
- package/.docs/reference/pubsub/valkey-streams.md +84 -0
- package/.docs/reference/rag/vector-databases.md +4 -4
- package/.docs/reference/server/express-adapter.md +6 -8
- package/.docs/reference/server/hono-adapter.md +19 -6
- package/.docs/reference/storage/turso.md +88 -0
- package/.docs/reference/streaming/ChunkType.md +29 -1
- package/.docs/reference/streaming/agents/stream.md +1 -3
- package/.docs/reference/tools/mcp-client.md +41 -9
- package/.docs/reference/vectors/mongodb.md +11 -11
- package/.docs/reference/vectors/pg.md +2 -0
- package/.docs/reference/workspace/sandbox.md +29 -1
- package/.docs/reference/workspace/workspace-class.md +15 -3
- package/CHANGELOG.md +66 -0
- package/package.json +5 -5
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
> Discover all available pages from the documentation index: https://mastra.ai/llms.txt
|
|
2
|
+
|
|
3
|
+
# Elasticsearch
|
|
4
|
+
|
|
5
|
+
The Elasticsearch storage implementation provides agent memory, workflow snapshot, and score storage on top of an Elasticsearch cluster using the official [`@elastic/elasticsearch`](https://github.com/elastic/elasticsearch-js) client. It shares the same connection configuration as `ElasticSearchVector`, so a single cluster (and even a single client instance) can serve both agent memory and semantic recall.
|
|
6
|
+
|
|
7
|
+
`ElasticSearchStore` currently implements the `memory`, `workflows`, and `scores` storage domains.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @mastra/elasticsearch
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Using a URL
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { ElasticSearchStore } from '@mastra/elasticsearch'
|
|
21
|
+
|
|
22
|
+
const storage = new ElasticSearchStore({
|
|
23
|
+
id: 'elasticsearch-storage',
|
|
24
|
+
url: 'http://localhost:9200',
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
await storage.init()
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Using authentication
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { ElasticSearchStore } from '@mastra/elasticsearch'
|
|
34
|
+
|
|
35
|
+
const storage = new ElasticSearchStore({
|
|
36
|
+
id: 'elasticsearch-storage',
|
|
37
|
+
url: 'https://my-cluster.example.com:9200',
|
|
38
|
+
auth: { apiKey: process.env.ELASTICSEARCH_API_KEY! },
|
|
39
|
+
})
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
`auth` also accepts `{ username, password }` or `{ bearer }`.
|
|
43
|
+
|
|
44
|
+
### Using a pre-configured client
|
|
45
|
+
|
|
46
|
+
For advanced configurations (cloud IDs, TLS options, custom transport), pass a pre-configured client. The same client can be shared with `ElasticSearchVector`:
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { Client } from '@elastic/elasticsearch'
|
|
50
|
+
import { ElasticSearchStore, ElasticSearchVector } from '@mastra/elasticsearch'
|
|
51
|
+
|
|
52
|
+
const client = new Client({
|
|
53
|
+
node: 'https://my-cluster.example.com:9200',
|
|
54
|
+
auth: { apiKey: process.env.ELASTICSEARCH_API_KEY! },
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
const storage = new ElasticSearchStore({ id: 'elasticsearch-storage', client })
|
|
58
|
+
const vector = new ElasticSearchVector({ id: 'elasticsearch-vector', client })
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
When you provide your own client, `storage.close()` does not close it — you remain responsible for its lifecycle.
|
|
62
|
+
|
|
63
|
+
## Parameters
|
|
64
|
+
|
|
65
|
+
**id** (`string`): Unique identifier for the storage instance
|
|
66
|
+
|
|
67
|
+
**url** (`string`): Elasticsearch node URL (e.g., http\://localhost:9200)
|
|
68
|
+
|
|
69
|
+
**auth** (`ElasticSearchAuth`): Authentication options: { apiKey }, { username, password }, or { bearer }
|
|
70
|
+
|
|
71
|
+
**client** (`Client`): Pre-configured Elasticsearch client (from @elastic/elasticsearch) for advanced setups
|
|
72
|
+
|
|
73
|
+
**disableInit** (`boolean`): Disable automatic initialization; call storage.init() explicitly before use
|
|
74
|
+
|
|
75
|
+
> **Note:** You must provide either `url` or `client`. These options are mutually exclusive.
|
|
76
|
+
|
|
77
|
+
## Additional Notes
|
|
78
|
+
|
|
79
|
+
### Index Structure
|
|
80
|
+
|
|
81
|
+
Each Mastra storage table maps to one Elasticsearch index of the same name (for example `mastra_threads`, `mastra_messages`, `mastra_workflow_snapshot`, `mastra_scorers`). Records are stored as opaque JSON documents with a keyword `key` field, so no index mappings need to be managed manually — indexes are created on first use.
|
|
82
|
+
|
|
83
|
+
### Consistency
|
|
84
|
+
|
|
85
|
+
Elasticsearch search is near-real-time. All writes are performed with an immediate refresh so subsequent reads and searches observe them, and point reads use real-time get-by-ID lookups.
|
|
86
|
+
|
|
87
|
+
### Closing Connections
|
|
88
|
+
|
|
89
|
+
When shutting down your application, close the connection:
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
await storage.close()
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
This only closes clients created by `ElasticSearchStore` from a `url`; user-provided clients are left open.
|
|
96
|
+
|
|
97
|
+
## Usage Example
|
|
98
|
+
|
|
99
|
+
### Adding memory to an agent
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import { Memory } from '@mastra/memory'
|
|
103
|
+
import { Agent } from '@mastra/core/agent'
|
|
104
|
+
import { ElasticSearchStore } from '@mastra/elasticsearch'
|
|
105
|
+
|
|
106
|
+
export const elasticsearchAgent = new Agent({
|
|
107
|
+
id: 'elasticsearch-agent',
|
|
108
|
+
name: 'Elasticsearch Agent',
|
|
109
|
+
instructions:
|
|
110
|
+
'You are an AI agent with the ability to automatically recall memories from previous interactions.',
|
|
111
|
+
model: 'openai/gpt-5.6-sol',
|
|
112
|
+
memory: new Memory({
|
|
113
|
+
storage: new ElasticSearchStore({
|
|
114
|
+
id: 'elasticsearch-agent-storage',
|
|
115
|
+
url: process.env.ELASTICSEARCH_URL!,
|
|
116
|
+
auth: { apiKey: process.env.ELASTICSEARCH_API_KEY! },
|
|
117
|
+
}),
|
|
118
|
+
options: {
|
|
119
|
+
lastMessages: 10,
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
})
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Using with Mastra instance
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { Mastra } from '@mastra/core'
|
|
129
|
+
import { ElasticSearchStore } from '@mastra/elasticsearch'
|
|
130
|
+
|
|
131
|
+
const storage = new ElasticSearchStore({
|
|
132
|
+
id: 'mastra-storage',
|
|
133
|
+
url: 'http://localhost:9200',
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
const mastra = new Mastra({
|
|
137
|
+
storage, // init() called automatically
|
|
138
|
+
})
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
If using storage directly without Mastra, call `init()` explicitly:
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
import { ElasticSearchStore } from '@mastra/elasticsearch'
|
|
145
|
+
|
|
146
|
+
const storage = new ElasticSearchStore({
|
|
147
|
+
id: 'elasticsearch-storage',
|
|
148
|
+
url: 'http://localhost:9200',
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
await storage.init()
|
|
152
|
+
|
|
153
|
+
// Access domain-specific stores via getStore()
|
|
154
|
+
const memoryStore = await storage.getStore('memory')
|
|
155
|
+
const thread = await memoryStore?.getThreadById({ threadId: '...' })
|
|
156
|
+
```
|
|
@@ -89,12 +89,28 @@ storage: new LibSQLStore({
|
|
|
89
89
|
|
|
90
90
|
> **Warning:** In-memory storage resets when the process changes. Only suitable for development.
|
|
91
91
|
|
|
92
|
+
Embedded replica synced with a remote primary (for example Turso):
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
storage: new LibSQLStore({
|
|
96
|
+
id: 'libsql-storage',
|
|
97
|
+
url: 'file:./replica.db',
|
|
98
|
+
syncUrl: 'libsql://your-db-name.aws-ap-northeast-1.turso.io',
|
|
99
|
+
authToken: process.env.TURSO_AUTH_TOKEN,
|
|
100
|
+
syncInterval: 60,
|
|
101
|
+
})
|
|
102
|
+
```
|
|
103
|
+
|
|
92
104
|
## Options
|
|
93
105
|
|
|
94
106
|
**url** (`string`): Database URL. Use :memory: for in-memory database, file:filename.db for a file database, or a libSQL connection string (e.g., libsql://your-database.turso.io) for remote storage.
|
|
95
107
|
|
|
96
108
|
**authToken** (`string`): Authentication token for remote libSQL databases.
|
|
97
109
|
|
|
110
|
+
**syncUrl** (`string`): URL of the remote primary database to sync from, enabling an embedded replica. Requires a local file: url.
|
|
111
|
+
|
|
112
|
+
**syncInterval** (`number`): Interval in seconds for automatic sync with the remote primary. Only applies when syncUrl is set.
|
|
113
|
+
|
|
98
114
|
## Managed tables
|
|
99
115
|
|
|
100
116
|
The storage implementation creates the core storage tables automatically, including `mastra_notifications` for notification inbox records and delivery metadata.
|
|
@@ -32,7 +32,7 @@ bun add @mastra/mongodb@latest
|
|
|
32
32
|
|
|
33
33
|
## Usage
|
|
34
34
|
|
|
35
|
-
Ensure you have a [MongoDB Atlas Local (via Docker)](https://www.mongodb.com/docs/atlas/cli/current/atlas-cli-deploy-docker/) or [MongoDB Atlas Cloud](https://www.mongodb.com/docs/atlas/cli/current/atlas-cli-getting-started/) instance with
|
|
35
|
+
Ensure you have a [MongoDB Atlas Local (via Docker)](https://www.mongodb.com/docs/atlas/cli/current/atlas-cli-deploy-docker/) or [MongoDB Atlas Cloud](https://www.mongodb.com/docs/atlas/cli/current/atlas-cli-getting-started/) instance with MongoDB Search enabled. MongoDB 7.0+ is recommended.
|
|
36
36
|
|
|
37
37
|
```typescript
|
|
38
38
|
import { MongoDBStore } from '@mastra/mongodb'
|
|
@@ -146,6 +146,32 @@ PostgreSQL supports observability and can handle low trace volumes. Throughput c
|
|
|
146
146
|
- Setting up table partitioning for efficient data retention
|
|
147
147
|
- Migrating observability to [ClickHouse via composite storage](https://mastra.ai/reference/storage/composite) if you need to scale further
|
|
148
148
|
|
|
149
|
+
`PostgresStoreVNext` uses the `event-sourced` [tracing strategy](https://mastra.ai/docs/observability/integrations/exporters/mastra-storage) instead. It writes one row when a span starts and another when it ends, never updating a row in place, and collapses those rows when a trace is read. Writes stay append-only, and traces appear in Studio while the run is still executing.
|
|
150
|
+
|
|
151
|
+
#### Filter suggestions
|
|
152
|
+
|
|
153
|
+
Studio's Traces, Logs, and Metrics pages offer filter values (tags, service names, environments, entity names, metric names and labels) discovered from your observability data. Those values are cached in the database and recomputed in the background when the cache goes stale.
|
|
154
|
+
|
|
155
|
+
To keep the refresh cheap on large datasets, it only scans events from the last 30 days. Values that appear exclusively in older events won't be suggested, though filtering by them still works. Use `discovery` to change the window or how often it refreshes:
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
import { PostgresStoreVNext } from '@mastra/pg'
|
|
159
|
+
|
|
160
|
+
const storage = new PostgresStoreVNext({
|
|
161
|
+
id: 'pg-storage',
|
|
162
|
+
connectionString: process.env.DATABASE_URL,
|
|
163
|
+
observability: {
|
|
164
|
+
connectionString: process.env.OBSERVABILITY_DATABASE_URL,
|
|
165
|
+
discovery: {
|
|
166
|
+
lookbackSeconds: 7 * 24 * 60 * 60, // scan the last 7 days; 0 scans all history
|
|
167
|
+
ttlSeconds: 15 * 60, // refresh at most every 15 minutes
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
})
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Lower `lookbackSeconds` if refreshes are slow, and raise `ttlSeconds` if they run more often than your filter values change. Only one process refreshes a given cache entry at a time, so adding server instances doesn't multiply the work.
|
|
174
|
+
|
|
149
175
|
### Initialization
|
|
150
176
|
|
|
151
177
|
When you pass storage to the Mastra class, `init()` is called automatically before any storage operation:
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
> Discover all available pages from the documentation index: https://mastra.ai/llms.txt
|
|
2
|
+
|
|
3
|
+
# Valkey
|
|
4
|
+
|
|
5
|
+
The Valkey storage implementation provides persistent storage and server-side caching through the [Valkey GLIDE](https://github.com/valkey-io/valkey-glide) client. Use it when your deployment runs Valkey or needs GLIDE features such as native Valkey configuration and authentication.
|
|
6
|
+
|
|
7
|
+
Use [`@mastra/redis`](https://mastra.ai/integrations/databases/redis) for Redis deployments that use the official `redis` client. The packages are tested independently against their respective servers.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
**npm**:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @mastra/valkey
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**pnpm**:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm add @mastra/valkey
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Yarn**:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
yarn add @mastra/valkey
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Bun**:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
bun add @mastra/valkey
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { Mastra } from '@mastra/core'
|
|
39
|
+
import { ValkeyStore } from '@mastra/valkey'
|
|
40
|
+
|
|
41
|
+
export const mastra = new Mastra({
|
|
42
|
+
storage: new ValkeyStore({
|
|
43
|
+
id: 'valkey-storage',
|
|
44
|
+
host: 'localhost',
|
|
45
|
+
port: 6379,
|
|
46
|
+
password: process.env.VALKEY_PASSWORD,
|
|
47
|
+
}),
|
|
48
|
+
})
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
You can also provide a native GLIDE configuration:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { ValkeyStore } from '@mastra/valkey'
|
|
55
|
+
|
|
56
|
+
const storage = new ValkeyStore({
|
|
57
|
+
id: 'valkey-storage',
|
|
58
|
+
config: {
|
|
59
|
+
addresses: [{ host: 'localhost', port: 6379 }],
|
|
60
|
+
useTLS: true,
|
|
61
|
+
},
|
|
62
|
+
})
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
For an existing `GlideClient`, connect it before passing it to `ValkeyStore`. The caller remains responsible for closing injected clients.
|
|
66
|
+
|
|
67
|
+
## Constructor parameters
|
|
68
|
+
|
|
69
|
+
**id** (`string`): Unique identifier for the storage instance.
|
|
70
|
+
|
|
71
|
+
**host** (`string`): Valkey host address. Use with the direct connection fields.
|
|
72
|
+
|
|
73
|
+
**port** (`number`): Valkey port. (Default: `6379`)
|
|
74
|
+
|
|
75
|
+
**username** (`string`): Valkey authentication username. (Default: `default`)
|
|
76
|
+
|
|
77
|
+
**password** (`string`): Valkey authentication password.
|
|
78
|
+
|
|
79
|
+
**db** (`number`): Valkey database number. (Default: `0`)
|
|
80
|
+
|
|
81
|
+
**useTLS** (`boolean`): Enables TLS for direct connections.
|
|
82
|
+
|
|
83
|
+
**config** (`GlideClientConfiguration`): Native GLIDE standalone client configuration.
|
|
84
|
+
|
|
85
|
+
**client** (`GlideClient`): Preconfigured GLIDE standalone client.
|
|
86
|
+
|
|
87
|
+
**disableInit** (`boolean`): Disables automatic storage initialization.
|
|
88
|
+
|
|
89
|
+
Provide exactly one connection form: `client`, `config`, or `host` with its optional direct connection fields.
|
|
90
|
+
|
|
91
|
+
## Closing connections
|
|
92
|
+
|
|
93
|
+
Close clients created by `ValkeyStore` during graceful shutdown:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
await storage.close()
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`close()` doesn't close an injected `GlideClient`.
|
|
@@ -12,7 +12,7 @@ Choose the deployment path that fits your application:
|
|
|
12
12
|
|
|
13
13
|
This guide builds an editorial pipeline that reviews a draft from three perspectives in parallel, then passes the feedback to an editor agent. Use the links above if you want to deploy a Mastra API or execute an entire Mastra workflow as one task.
|
|
14
14
|
|
|
15
|
-
## How Render Workflows
|
|
15
|
+
## How Render Workflows integrate with Mastra
|
|
16
16
|
|
|
17
17
|
Mastra supplies the agents and application logic, while Render Workflows defines the execution boundaries. A typical pipeline has three layers:
|
|
18
18
|
|
|
@@ -93,8 +93,6 @@ yarn add @renderinc/sdk tsx
|
|
|
93
93
|
bun add @renderinc/sdk tsx
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
> **Note:** Render Workflows requires `@renderinc/sdk@^0.5.0` or later.
|
|
97
|
-
|
|
98
96
|
Set the API key for your model provider. This example uses OpenAI:
|
|
99
97
|
|
|
100
98
|
```text
|
|
@@ -103,9 +101,9 @@ OPENAI_API_KEY=your_openai_api_key
|
|
|
103
101
|
|
|
104
102
|
Any supported [Mastra model provider](https://mastra.ai/models) works.
|
|
105
103
|
|
|
106
|
-
##
|
|
104
|
+
## Build a distributed agent pipeline
|
|
107
105
|
|
|
108
|
-
###
|
|
106
|
+
### Create the agents
|
|
109
107
|
|
|
110
108
|
In `src/mastra`, create an `agents` directory with `reviewer-agent.ts` and `editor-agent.ts`. Define both agents:
|
|
111
109
|
|
|
@@ -139,7 +137,7 @@ export const editorAgent = new Agent({
|
|
|
139
137
|
})
|
|
140
138
|
```
|
|
141
139
|
|
|
142
|
-
###
|
|
140
|
+
### Configure the Mastra instance
|
|
143
141
|
|
|
144
142
|
Add both agents to the Mastra instance in `src/mastra/index.ts`:
|
|
145
143
|
|
|
@@ -158,7 +156,7 @@ export const mastra = new Mastra({
|
|
|
158
156
|
|
|
159
157
|
Retrieving agents from the Mastra instance gives them access to shared application services such as logging, storage, and observability.
|
|
160
158
|
|
|
161
|
-
###
|
|
159
|
+
### Create the review task
|
|
162
160
|
|
|
163
161
|
In `src`, create a `tasks` directory. The reviewer agent handles one area of focus. Its compute plan, five-minute timeout, and retry policy apply only to that analysis. A temporary model-provider failure can trigger another attempt without restarting the other reviewers.
|
|
164
162
|
|
|
@@ -199,7 +197,7 @@ export const reviewDraft = task(
|
|
|
199
197
|
)
|
|
200
198
|
```
|
|
201
199
|
|
|
202
|
-
###
|
|
200
|
+
### Create the revision task
|
|
203
201
|
|
|
204
202
|
This task combines the feedback and produces a revised draft. It uses a larger compute plan and a longer timeout than each reviewer.
|
|
205
203
|
|
|
@@ -240,7 +238,7 @@ export const reviseDraft = task(
|
|
|
240
238
|
)
|
|
241
239
|
```
|
|
242
240
|
|
|
243
|
-
###
|
|
241
|
+
### Create the orchestration task
|
|
244
242
|
|
|
245
243
|
The parent dispatches three reviews in parallel with `Promise.all()`, then sends their combined feedback to the revision step. Retries are disabled at this level because each child defines its own policy. If you enable orchestration retries, ensure that another attempt cannot duplicate external side effects or other non-idempotent work.
|
|
246
244
|
|
|
@@ -268,7 +266,7 @@ export const editorialPipeline = task(
|
|
|
268
266
|
)
|
|
269
267
|
```
|
|
270
268
|
|
|
271
|
-
###
|
|
269
|
+
### Register the tasks
|
|
272
270
|
|
|
273
271
|
Create `src/index.ts` and import the editorial task:
|
|
274
272
|
|
|
@@ -278,7 +276,7 @@ import './tasks/editorial-task.js'
|
|
|
278
276
|
|
|
279
277
|
Running the entry point loads the module and registers every task defined with `task()`.
|
|
280
278
|
|
|
281
|
-
|
|
279
|
+
Change your `tsconfig.json`:
|
|
282
280
|
|
|
283
281
|
```json
|
|
284
282
|
{
|
|
@@ -292,7 +290,7 @@ Running the entry point loads the module and registers every task defined with `
|
|
|
292
290
|
}
|
|
293
291
|
```
|
|
294
292
|
|
|
295
|
-
Add these scripts
|
|
293
|
+
Add these scripts to `package.json`:
|
|
296
294
|
|
|
297
295
|
```json
|
|
298
296
|
{
|
|
@@ -304,13 +302,11 @@ Add these scripts next to the ones `create mastra` already added. `create mastra
|
|
|
304
302
|
}
|
|
305
303
|
```
|
|
306
304
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
Those files are the complete pipeline. [render-examples/render-workflows-mastra](https://github.com/render-examples/render-workflows-mastra) mirrors this `src/` layout and adds a web UI that starts the parent task. Its agents use the provider-specific model ID `openai/gpt-5.6-sol`. In this page's source, that value is represented by a documentation token that is replaced during the docs build. Clone it to skip copying the snippets before you run it.
|
|
305
|
+
Those files are the complete pipeline. [render-examples/render-workflows-mastra](https://github.com/render-examples/render-workflows-mastra) mirrors this `src/` layout and adds a web UI that starts the parent task.
|
|
310
306
|
|
|
311
|
-
##
|
|
307
|
+
## Run the pipeline
|
|
312
308
|
|
|
313
|
-
###
|
|
309
|
+
### Local
|
|
314
310
|
|
|
315
311
|
Start the local Render Workflows development server:
|
|
316
312
|
|
|
@@ -334,56 +330,56 @@ render workflows tasks start editorial_pipeline \
|
|
|
334
330
|
|
|
335
331
|
The local server keeps runs and their logs in memory, so you can inspect them after they finish with `render workflows runs list <task-name> --local`.
|
|
336
332
|
|
|
337
|
-
###
|
|
333
|
+
### Production
|
|
338
334
|
|
|
339
335
|
Running the pipeline on Render requires a _workflow service_. This is the Render service that holds your task definitions: it builds your repository, registers every task it finds, and provisions an instance for each run.
|
|
340
336
|
|
|
341
|
-
|
|
337
|
+
1. #### Push the project to a Git repository
|
|
342
338
|
|
|
343
|
-
Render builds workflow services from a repository on GitHub, GitLab, or Bitbucket, so push your project to one of those providers. The first time you use a provider, Render asks for permission to access your repositories.
|
|
339
|
+
Render builds workflow services from a repository on GitHub, GitLab, or Bitbucket, so push your project to one of those providers. The first time you use a provider, Render asks for permission to access your repositories.
|
|
344
340
|
|
|
345
|
-
|
|
341
|
+
2. #### Create the workflow service
|
|
346
342
|
|
|
347
|
-
In the [Render Dashboard](https://dashboard.render.com), click **New > Workflow** and link the repository from the previous step. Then complete the creation form:
|
|
343
|
+
In the [Render Dashboard](https://dashboard.render.com), click **New > Workflow** and link the repository from the previous step. Then complete the creation form:
|
|
348
344
|
|
|
349
|
-
| Field | Value |
|
|
350
|
-
| ----------------- | ------------------------------------------------------------- |
|
|
351
|
-
| **Language** | Node |
|
|
352
|
-
| **Region** | The region of any other Render services your tasks connect to |
|
|
353
|
-
| **Build Command** | `npm install && npm run build` |
|
|
354
|
-
| **Start Command** | `npm run start:workflows` |
|
|
345
|
+
| Field | Value |
|
|
346
|
+
| ----------------- | ------------------------------------------------------------- |
|
|
347
|
+
| **Language** | Node |
|
|
348
|
+
| **Region** | The region of any other Render services your tasks connect to |
|
|
349
|
+
| **Build Command** | `npm install && npm run build` |
|
|
350
|
+
| **Start Command** | `npm run start:workflows` |
|
|
355
351
|
|
|
356
|
-
Click **Deploy Workflow**. Render builds the project and registers `review_draft`, `revise_draft`, and `editorial_pipeline`, which then appear on the workflow's **Tasks** page.
|
|
352
|
+
Click **Deploy Workflow**. Render builds the project and registers `review_draft`, `revise_draft`, and `editorial_pipeline`, which then appear on the workflow's **Tasks** page.
|
|
357
353
|
|
|
358
|
-
The Render CLI creates the same service without leaving your terminal:
|
|
354
|
+
The Render CLI creates the same service without leaving your terminal:
|
|
359
355
|
|
|
360
|
-
```bash
|
|
361
|
-
render workflows create \
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
```
|
|
356
|
+
```bash
|
|
357
|
+
render workflows create \
|
|
358
|
+
--name mastra-workflows \
|
|
359
|
+
--repo . \
|
|
360
|
+
--runtime node \
|
|
361
|
+
--build-command "npm install && npm run build" \
|
|
362
|
+
--run-command "npm run start:workflows"
|
|
363
|
+
```
|
|
368
364
|
|
|
369
|
-
`--repo .` reads the `origin` remote of your local repository, so the project must already be pushed.
|
|
365
|
+
`--repo .` reads the `origin` remote of your local repository, so the project must already be pushed.
|
|
370
366
|
|
|
371
|
-
|
|
367
|
+
3. #### Set the workflow's environment variables
|
|
372
368
|
|
|
373
|
-
Add `OPENAI_API_KEY`, or the key for your chosen model provider, to the workflow service in the Dashboard before the first run.
|
|
369
|
+
Add `OPENAI_API_KEY`, or the key for your chosen model provider, to the workflow service in the Dashboard before the first run.
|
|
374
370
|
|
|
375
|
-
|
|
371
|
+
4. #### Start a run
|
|
376
372
|
|
|
377
|
-
```bash
|
|
378
|
-
render workflows tasks start mastra-workflows/editorial_pipeline \
|
|
379
|
-
|
|
380
|
-
```
|
|
373
|
+
```bash
|
|
374
|
+
render workflows tasks start mastra-workflows/editorial_pipeline \
|
|
375
|
+
--input='["Render Workflows runs long-running tasks outside the request lifecycle."]'
|
|
376
|
+
```
|
|
381
377
|
|
|
382
|
-
The first part of that identifier is your workflow's slug and the second is the task name. Both appear on the task's page in the Render Dashboard, so use the slug shown there if your workflow has a different name.
|
|
378
|
+
The first part of that identifier is your workflow's slug and the second is the task name. Both appear on the task's page in the Render Dashboard, so use the slug shown there if your workflow has a different name.
|
|
383
379
|
|
|
384
|
-
Open the workflow in the Render Dashboard to inspect each task run, attempt, result, and log stream.
|
|
380
|
+
Open the workflow in the Render Dashboard to inspect each task run, attempt, result, and log stream.
|
|
385
381
|
|
|
386
|
-
##
|
|
382
|
+
## Trigger from your application
|
|
387
383
|
|
|
388
384
|
You can trigger the pipeline asynchronously from a Mastra application, web service, or script with the Render SDK.
|
|
389
385
|
|
|
@@ -415,17 +411,6 @@ The task continues running after `startTask()` returns. Call `await run.get()` w
|
|
|
415
411
|
|
|
416
412
|
Returning the task run ID from a request handler lets the application respond without keeping the request open for the full pipeline.
|
|
417
413
|
|
|
418
|
-
## Constraints
|
|
419
|
-
|
|
420
|
-
These limits live in Render's docs and can change. Prefer those pages over this list:
|
|
421
|
-
|
|
422
|
-
- Task arguments and return values must be JSON serializable. Arguments to a single run cannot exceed 4 MB. See [defining tasks](https://render.com/docs/workflows-defining#task-arguments) and [Workflows limits](https://render.com/docs/workflows-limits).
|
|
423
|
-
- A task can run for up to 24 hours. The default timeout is two hours. See [timeouts](https://render.com/docs/workflows-defining#timeout).
|
|
424
|
-
- A workflow service can register up to 500 task definitions. See [Workflows limits](https://render.com/docs/workflows-limits).
|
|
425
|
-
- Render Workflows currently supports TypeScript and Python task definitions. See [defining tasks](https://render.com/docs/workflows-defining).
|
|
426
|
-
|
|
427
|
-
To run the pipeline on a schedule, create a [Render cron job](https://render.com/docs/cronjobs) whose command calls `render workflows tasks start` or `startTask()`.
|
|
428
|
-
|
|
429
414
|
## Related
|
|
430
415
|
|
|
431
416
|
- [Live demo](https://render-workflows-mastra.onrender.com)
|
|
@@ -433,4 +418,5 @@ To run the pipeline on a schedule, create a [Render cron job](https://render.com
|
|
|
433
418
|
- [Defining Render workflow tasks](https://render.com/docs/workflows-defining)
|
|
434
419
|
- [Triggering task runs](https://render.com/docs/workflows-running)
|
|
435
420
|
- [Render Workflows TypeScript SDK](https://render.com/docs/workflows-sdk-typescript)
|
|
436
|
-
- [Render Workflows limits and pricing](https://render.com/docs/workflows-limits)
|
|
421
|
+
- [Render Workflows limits and pricing](https://render.com/docs/workflows-limits)
|
|
422
|
+
- [Render cron jobs](https://render.com/docs/cronjobs)
|
|
@@ -60,6 +60,8 @@ const agent = new Agent({
|
|
|
60
60
|
|
|
61
61
|
**timeout** (`number`): Execution timeout in milliseconds (Default: `300000 (5 minutes)`)
|
|
62
62
|
|
|
63
|
+
**lifecycle** (`SandboxLifecycle`): Controls what happens when the sandbox timeout is reached. Defaults to pausing the sandbox so the next start resumes it. Pass { onTimeout: 'kill' } to destroy idle sandboxes instead, which suits stateless workspaces whose data is persisted outside the sandbox. An explicit stop() always pauses, regardless of this setting. (Default: `{ onTimeout: 'pause' }`)
|
|
64
|
+
|
|
63
65
|
**template** (`string | TemplateBuilder | function`): Sandbox template specification. Can be a template ID string, a TemplateBuilder, or a function that customizes the default template.
|
|
64
66
|
|
|
65
67
|
**env** (`Record<string, string>`): Environment variables to set in the sandbox
|