@mastra/pg 1.0.0-beta.11 → 1.0.0-beta.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,212 @@
1
1
  # @mastra/pg
2
2
 
3
+ ## 1.0.0-beta.13
4
+
5
+ ### Minor Changes
6
+
7
+ - Changed JSON columns from TEXT to JSONB in `mastra_threads` and `mastra_workflow_snapshot` tables. ([#11853](https://github.com/mastra-ai/mastra/pull/11853))
8
+
9
+ **Why this change?**
10
+
11
+ These were the last remaining columns storing JSON as TEXT. This change aligns them with other tables that already use JSONB, enabling native JSON operators and improved performance. See [#8978](https://github.com/mastra-ai/mastra/issues/8978) for details.
12
+
13
+ **Columns Changed:**
14
+ - `mastra_threads.metadata` - Thread metadata
15
+ - `mastra_workflow_snapshot.snapshot` - Workflow run state
16
+
17
+ **PostgreSQL**
18
+
19
+ Migration Required - PostgreSQL enforces column types, so existing tables must be migrated. Note: Migration will fail if existing column values contain invalid JSON.
20
+
21
+ ```sql
22
+ ALTER TABLE mastra_threads
23
+ ALTER COLUMN metadata TYPE jsonb
24
+ USING metadata::jsonb;
25
+
26
+ ALTER TABLE mastra_workflow_snapshot
27
+ ALTER COLUMN snapshot TYPE jsonb
28
+ USING snapshot::jsonb;
29
+ ```
30
+
31
+ **LibSQL**
32
+
33
+ No Migration Required - LibSQL now uses native SQLite JSONB format (added in SQLite 3.45) for ~3x performance improvement on JSON operations. The changes are fully backwards compatible:
34
+ - Existing TEXT JSON data continues to work
35
+ - New data is stored in binary JSONB format
36
+ - Both formats can coexist in the same table
37
+ - All JSON functions (`json_extract`, etc.) work on both formats
38
+
39
+ New installations automatically use JSONB. Existing applications continue to work without any changes.
40
+
41
+ ### Patch Changes
42
+
43
+ - Fix `listWorkflowRuns` failing with "unsupported Unicode escape sequence" error when filtering by status on snapshots containing null characters (`\u0000`) or unpaired Unicode surrogates (`\uD800-\uDFFF`). ([#11616](https://github.com/mastra-ai/mastra/pull/11616))
44
+
45
+ The fix uses `regexp_replace` to sanitize problematic escape sequences before casting to JSONB in the WHERE clause, while preserving the original data in the returned results.
46
+
47
+ - Fixed PostgreSQL migration errors when upgrading from v0.x to v1 ([#11633](https://github.com/mastra-ai/mastra/pull/11633))
48
+
49
+ **What changed:** PostgreSQL storage now automatically adds missing `spanId` and `requestContext` columns to the scorers table during initialization, preventing "column does not exist" errors when upgrading from v0.x to v1.0.0.
50
+
51
+ **Why:** Previously, upgrading to v1 could fail with errors like `column "requestContext" of relation "mastra_scorers" does not exist` if your database was created with an older version.
52
+
53
+ Related: #11631
54
+
55
+ - Aligned vector store configuration with underlying library APIs, giving you access to all library options directly. ([#11742](https://github.com/mastra-ai/mastra/pull/11742))
56
+
57
+ **Why this change?**
58
+
59
+ Previously, each vector store defined its own configuration types that only exposed a subset of the underlying library's options. This meant users couldn't access advanced features like authentication, SSL, compression, or custom headers without creating their own client instances. Now, the configuration types extend the library types directly, so all options are available.
60
+
61
+ **@mastra/libsql** (Breaking)
62
+
63
+ Renamed `connectionUrl` to `url` to match the `@libsql/client` API and align with LibSQLStorage.
64
+
65
+ ```typescript
66
+ // Before
67
+ new LibSQLVector({ id: 'my-vector', connectionUrl: 'file:./db.sqlite' });
68
+
69
+ // After
70
+ new LibSQLVector({ id: 'my-vector', url: 'file:./db.sqlite' });
71
+ ```
72
+
73
+ **@mastra/opensearch** (Breaking)
74
+
75
+ Renamed `url` to `node` and added support for all OpenSearch `ClientOptions` including authentication, SSL, and compression.
76
+
77
+ ```typescript
78
+ // Before
79
+ new OpenSearchVector({ id: 'my-vector', url: 'http://localhost:9200' });
80
+
81
+ // After
82
+ new OpenSearchVector({ id: 'my-vector', node: 'http://localhost:9200' });
83
+
84
+ // With authentication (now possible)
85
+ new OpenSearchVector({
86
+ id: 'my-vector',
87
+ node: 'https://localhost:9200',
88
+ auth: { username: 'admin', password: 'admin' },
89
+ ssl: { rejectUnauthorized: false },
90
+ });
91
+ ```
92
+
93
+ **@mastra/pinecone** (Breaking)
94
+
95
+ Removed `environment` parameter. Use `controllerHostUrl` instead (the actual Pinecone SDK field name). Added support for all `PineconeConfiguration` options.
96
+
97
+ ```typescript
98
+ // Before
99
+ new PineconeVector({ id: 'my-vector', apiKey: '...', environment: '...' });
100
+
101
+ // After
102
+ new PineconeVector({ id: 'my-vector', apiKey: '...' });
103
+
104
+ // With custom controller host (if needed)
105
+ new PineconeVector({ id: 'my-vector', apiKey: '...', controllerHostUrl: '...' });
106
+ ```
107
+
108
+ **@mastra/clickhouse**
109
+
110
+ Added support for all `ClickHouseClientConfigOptions` like `request_timeout`, `compression`, `keep_alive`, and `database`. Existing configurations continue to work unchanged.
111
+
112
+ **@mastra/cloudflare, @mastra/cloudflare-d1, @mastra/lance, @mastra/libsql, @mastra/mongodb, @mastra/pg, @mastra/upstash**
113
+
114
+ Improved logging by replacing `console.warn` with structured logger in workflow storage domains.
115
+
116
+ **@mastra/deployer-cloud**
117
+
118
+ Updated internal LibSQLVector configuration for compatibility with the new API.
119
+
120
+ - Fixed PostgreSQL storage issues after JSONB migration. ([#11906](https://github.com/mastra-ai/mastra/pull/11906))
121
+
122
+ **Bug Fixes**
123
+ - Fixed `clearTable()` using incorrect default schema. The method was checking for table existence in the 'mastra' schema instead of PostgreSQL's default 'public' schema, causing table truncation to be skipped and leading to duplicate key violations in tests and production code that uses `dangerouslyClearAll()`.
124
+ - Fixed `listWorkflowRuns()` status filter failing with "function regexp_replace(jsonb, ...) does not exist" error. After the TEXT to JSONB migration, the query tried to use `regexp_replace()` directly on a JSONB column. Now casts to text first: `regexp_replace(snapshot::text, ...)`.
125
+ - Added Unicode sanitization when persisting workflow snapshots to handle null characters (\u0000) and unpaired surrogates (\uD800-\uDFFF) that PostgreSQL's JSONB type rejects, preventing "unsupported Unicode escape sequence" errors.
126
+
127
+ - Updated dependencies [[`ebae12a`](https://github.com/mastra-ai/mastra/commit/ebae12a2dd0212e75478981053b148a2c246962d), [`c61a0a5`](https://github.com/mastra-ai/mastra/commit/c61a0a5de4904c88fd8b3718bc26d1be1c2ec6e7), [`69136e7`](https://github.com/mastra-ai/mastra/commit/69136e748e32f57297728a4e0f9a75988462f1a7), [`449aed2`](https://github.com/mastra-ai/mastra/commit/449aed2ba9d507b75bf93d427646ea94f734dfd1), [`eb648a2`](https://github.com/mastra-ai/mastra/commit/eb648a2cc1728f7678768dd70cd77619b448dab9), [`0131105`](https://github.com/mastra-ai/mastra/commit/0131105532e83bdcbb73352fc7d0879eebf140dc), [`9d5059e`](https://github.com/mastra-ai/mastra/commit/9d5059eae810829935fb08e81a9bb7ecd5b144a7), [`ef756c6`](https://github.com/mastra-ai/mastra/commit/ef756c65f82d16531c43f49a27290a416611e526), [`b00ccd3`](https://github.com/mastra-ai/mastra/commit/b00ccd325ebd5d9e37e34dd0a105caae67eb568f), [`3bdfa75`](https://github.com/mastra-ai/mastra/commit/3bdfa7507a91db66f176ba8221aa28dd546e464a), [`e770de9`](https://github.com/mastra-ai/mastra/commit/e770de941a287a49b1964d44db5a5763d19890a6), [`52e2716`](https://github.com/mastra-ai/mastra/commit/52e2716b42df6eff443de72360ae83e86ec23993), [`27b4040`](https://github.com/mastra-ai/mastra/commit/27b4040bfa1a95d92546f420a02a626b1419a1d6), [`610a70b`](https://github.com/mastra-ai/mastra/commit/610a70bdad282079f0c630e0d7bb284578f20151), [`8dc7f55`](https://github.com/mastra-ai/mastra/commit/8dc7f55900395771da851dc7d78d53ae84fe34ec), [`8379099`](https://github.com/mastra-ai/mastra/commit/8379099fc467af6bef54dd7f80c9bd75bf8bbddf), [`8c0ec25`](https://github.com/mastra-ai/mastra/commit/8c0ec25646c8a7df253ed1e5ff4863a0d3f1316c), [`ff4d9a6`](https://github.com/mastra-ai/mastra/commit/ff4d9a6704fc87b31a380a76ed22736fdedbba5a), [`69821ef`](https://github.com/mastra-ai/mastra/commit/69821ef806482e2c44e2197ac0b050c3fe3a5285), [`1ed5716`](https://github.com/mastra-ai/mastra/commit/1ed5716830867b3774c4a1b43cc0d82935f32b96), [`4186bdd`](https://github.com/mastra-ai/mastra/commit/4186bdd00731305726fa06adba0b076a1d50b49f), [`7aaf973`](https://github.com/mastra-ai/mastra/commit/7aaf973f83fbbe9521f1f9e7a4fd99b8de464617)]:
128
+ - @mastra/core@1.0.0-beta.22
129
+
130
+ ## 1.0.0-beta.12
131
+
132
+ ### Patch Changes
133
+
134
+ - Add embedded documentation support for Mastra packages ([#11472](https://github.com/mastra-ai/mastra/pull/11472))
135
+
136
+ Mastra packages now include embedded documentation in the published npm package under `dist/docs/`. This enables coding agents and AI assistants to understand and use the framework by reading documentation directly from `node_modules`.
137
+
138
+ Each package includes:
139
+ - **SKILL.md** - Entry point explaining the package's purpose and capabilities
140
+ - **SOURCE_MAP.json** - Machine-readable index mapping exports to types and implementation files
141
+ - **Topic folders** - Conceptual documentation organized by feature area
142
+
143
+ Documentation is driven by the `packages` frontmatter field in MDX files, which maps docs to their corresponding packages. CI validation ensures all docs include this field.
144
+
145
+ - Added `startExclusive` and `endExclusive` options to `dateRange` filter for message queries. ([#11479](https://github.com/mastra-ai/mastra/pull/11479))
146
+
147
+ **What changed:** The `filter.dateRange` parameter in `listMessages()` and `Memory.recall()` now supports `startExclusive` and `endExclusive` boolean options. When set to `true`, messages with timestamps exactly matching the boundary are excluded from results.
148
+
149
+ **Why this matters:** Enables cursor-based pagination for chat applications. When new messages arrive during a session, offset-based pagination can skip or duplicate messages. Using `endExclusive: true` with the oldest message's timestamp as a cursor ensures consistent pagination without gaps or duplicates.
150
+
151
+ **Example:**
152
+
153
+ ```typescript
154
+ // Get first page
155
+ const page1 = await memory.recall({
156
+ threadId: 'thread-123',
157
+ perPage: 10,
158
+ orderBy: { field: 'createdAt', direction: 'DESC' },
159
+ });
160
+
161
+ // Get next page using cursor-based pagination
162
+ const oldestMessage = page1.messages[page1.messages.length - 1];
163
+ const page2 = await memory.recall({
164
+ threadId: 'thread-123',
165
+ perPage: 10,
166
+ orderBy: { field: 'createdAt', direction: 'DESC' },
167
+ filter: {
168
+ dateRange: {
169
+ end: oldestMessage.createdAt,
170
+ endExclusive: true, // Excludes the cursor message
171
+ },
172
+ },
173
+ });
174
+ ```
175
+
176
+ - Fix thread timestamps being returned in incorrect timezone from listThreadsByResourceId ([#11498](https://github.com/mastra-ai/mastra/pull/11498))
177
+
178
+ The method was not using the timezone-aware columns (createdAtZ/updatedAtZ), causing timestamps to be interpreted in local timezone instead of UTC. Now correctly uses TIMESTAMPTZ columns with fallback for legacy data.
179
+
180
+ - Adds thread cloning to create independent copies of conversations that can diverge. ([#11517](https://github.com/mastra-ai/mastra/pull/11517))
181
+
182
+ ```typescript
183
+ // Clone a thread
184
+ const { thread, clonedMessages } = await memory.cloneThread({
185
+ sourceThreadId: 'thread-123',
186
+ title: 'My Clone',
187
+ options: {
188
+ messageLimit: 10, // optional: only copy last N messages
189
+ },
190
+ });
191
+
192
+ // Check if a thread is a clone
193
+ if (memory.isClone(thread)) {
194
+ const source = await memory.getSourceThread(thread.id);
195
+ }
196
+
197
+ // List all clones of a thread
198
+ const clones = await memory.listClones('thread-123');
199
+ ```
200
+
201
+ Includes:
202
+ - Storage implementations for InMemory, PostgreSQL, LibSQL, Upstash
203
+ - API endpoint: `POST /api/memory/threads/:threadId/clone`
204
+ - Embeddings created for cloned messages (semantic recall)
205
+ - Clone button in playground UI Memory tab
206
+
207
+ - Updated dependencies [[`d2d3e22`](https://github.com/mastra-ai/mastra/commit/d2d3e22a419ee243f8812a84e3453dd44365ecb0), [`bc72b52`](https://github.com/mastra-ai/mastra/commit/bc72b529ee4478fe89ecd85a8be47ce0127b82a0), [`05b8bee`](https://github.com/mastra-ai/mastra/commit/05b8bee9e50e6c2a4a2bf210eca25ee212ca24fa), [`c042bd0`](https://github.com/mastra-ai/mastra/commit/c042bd0b743e0e86199d0cb83344ca7690e34a9c), [`940a2b2`](https://github.com/mastra-ai/mastra/commit/940a2b27480626ed7e74f55806dcd2181c1dd0c2), [`e0941c3`](https://github.com/mastra-ai/mastra/commit/e0941c3d7fc75695d5d258e7008fd5d6e650800c), [`0c0580a`](https://github.com/mastra-ai/mastra/commit/0c0580a42f697cd2a7d5973f25bfe7da9055038a), [`28f5f89`](https://github.com/mastra-ai/mastra/commit/28f5f89705f2409921e3c45178796c0e0d0bbb64), [`e601b27`](https://github.com/mastra-ai/mastra/commit/e601b272c70f3a5ecca610373aa6223012704892), [`3d3366f`](https://github.com/mastra-ai/mastra/commit/3d3366f31683e7137d126a3a57174a222c5801fb), [`5a4953f`](https://github.com/mastra-ai/mastra/commit/5a4953f7d25bb15ca31ed16038092a39cb3f98b3), [`eb9e522`](https://github.com/mastra-ai/mastra/commit/eb9e522ce3070a405e5b949b7bf5609ca51d7fe2), [`20e6f19`](https://github.com/mastra-ai/mastra/commit/20e6f1971d51d3ff6dd7accad8aaaae826d540ed), [`4f0b3c6`](https://github.com/mastra-ai/mastra/commit/4f0b3c66f196c06448487f680ccbb614d281e2f7), [`74c4f22`](https://github.com/mastra-ai/mastra/commit/74c4f22ed4c71e72598eacc346ba95cdbc00294f), [`81b6a8f`](https://github.com/mastra-ai/mastra/commit/81b6a8ff79f49a7549d15d66624ac1a0b8f5f971), [`e4d366a`](https://github.com/mastra-ai/mastra/commit/e4d366aeb500371dd4210d6aa8361a4c21d87034), [`a4f010b`](https://github.com/mastra-ai/mastra/commit/a4f010b22e4355a5fdee70a1fe0f6e4a692cc29e), [`73b0bb3`](https://github.com/mastra-ai/mastra/commit/73b0bb394dba7c9482eb467a97ab283dbc0ef4db), [`5627a8c`](https://github.com/mastra-ai/mastra/commit/5627a8c6dc11fe3711b3fa7a6ffd6eb34100a306), [`3ff45d1`](https://github.com/mastra-ai/mastra/commit/3ff45d10e0c80c5335a957ab563da72feb623520), [`251df45`](https://github.com/mastra-ai/mastra/commit/251df4531407dfa46d805feb40ff3fb49769f455), [`f894d14`](https://github.com/mastra-ai/mastra/commit/f894d148946629af7b1f452d65a9cf864cec3765), [`c2b9547`](https://github.com/mastra-ai/mastra/commit/c2b9547bf435f56339f23625a743b2147ab1c7a6), [`580b592`](https://github.com/mastra-ai/mastra/commit/580b5927afc82fe460dfdf9a38a902511b6b7e7f), [`58e3931`](https://github.com/mastra-ai/mastra/commit/58e3931af9baa5921688566210f00fb0c10479fa), [`08bb631`](https://github.com/mastra-ai/mastra/commit/08bb631ae2b14684b2678e3549d0b399a6f0561e), [`4fba91b`](https://github.com/mastra-ai/mastra/commit/4fba91bec7c95911dc28e369437596b152b04cd0), [`12b0cc4`](https://github.com/mastra-ai/mastra/commit/12b0cc4077d886b1a552637dedb70a7ade93528c)]:
208
+ - @mastra/core@1.0.0-beta.20
209
+
3
210
  ## 1.0.0-beta.11
4
211
 
5
212
  ### Minor Changes
@@ -0,0 +1,36 @@
1
+ # @mastra/pg Documentation
2
+
3
+ > Embedded documentation for coding agents
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # Read the skill overview
9
+ cat docs/SKILL.md
10
+
11
+ # Get the source map
12
+ cat docs/SOURCE_MAP.json
13
+
14
+ # Read topic documentation
15
+ cat docs/<topic>/01-overview.md
16
+ ```
17
+
18
+ ## Structure
19
+
20
+ ```
21
+ docs/
22
+ ├── SKILL.md # Entry point
23
+ ├── README.md # This file
24
+ ├── SOURCE_MAP.json # Export index
25
+ ├── memory/ (4 files)
26
+ ├── processors/ (3 files)
27
+ ├── rag/ (4 files)
28
+ ├── storage/ (3 files)
29
+ ├── tools/ (1 files)
30
+ ├── vectors/ (1 files)
31
+ ```
32
+
33
+ ## Version
34
+
35
+ Package: @mastra/pg
36
+ Version: 1.0.0-beta.13
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: mastra-pg-docs
3
+ description: Documentation for @mastra/pg. Includes links to type definitions and readable implementation code in dist/.
4
+ ---
5
+
6
+ # @mastra/pg Documentation
7
+
8
+ > **Version**: 1.0.0-beta.13
9
+ > **Package**: @mastra/pg
10
+
11
+ ## Quick Navigation
12
+
13
+ Use SOURCE_MAP.json to find any export:
14
+
15
+ ```bash
16
+ cat docs/SOURCE_MAP.json
17
+ ```
18
+
19
+ Each export maps to:
20
+ - **types**: `.d.ts` file with JSDoc and API signatures
21
+ - **implementation**: `.js` chunk file with readable source
22
+ - **docs**: Conceptual documentation in `docs/`
23
+
24
+ ## Top Exports
25
+
26
+
27
+
28
+ See SOURCE_MAP.json for the complete list.
29
+
30
+ ## Available Topics
31
+
32
+ - [Memory](memory/) - 4 file(s)
33
+ - [Processors](processors/) - 3 file(s)
34
+ - [Rag](rag/) - 4 file(s)
35
+ - [Storage](storage/) - 3 file(s)
36
+ - [Tools](tools/) - 1 file(s)
37
+ - [Vectors](vectors/) - 1 file(s)
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": "1.0.0-beta.13",
3
+ "package": "@mastra/pg",
4
+ "exports": {},
5
+ "modules": {}
6
+ }
@@ -0,0 +1,215 @@
1
+ > Configure storage for Mastra
2
+
3
+ # Storage
4
+
5
+ For Mastra to remember previous interactions, you must configure a storage adapter. Mastra is designed to work with your preferred database provider - choose from the [supported providers](#supported-providers) and pass it to your Mastra instance.
6
+
7
+ ```typescript title="src/mastra/index.ts"
8
+ import { Mastra } from "@mastra/core";
9
+ import { LibSQLStore } from "@mastra/libsql";
10
+
11
+ export const mastra = new Mastra({
12
+ storage: new LibSQLStore({
13
+ id: 'mastra-storage',
14
+ url: "file:./mastra.db",
15
+ }),
16
+ });
17
+ ```
18
+ On first interaction, Mastra automatically creates the necessary tables following the [core schema](https://mastra.ai/reference/v1/storage/overview#core-schema). This includes tables for messages, threads, resources, workflows, traces, and evaluation datasets.
19
+
20
+ ## Supported providers
21
+
22
+ Each provider page includes installation instructions, configuration parameters, and usage examples:
23
+
24
+ - [libSQL Storage](https://mastra.ai/reference/v1/storage/libsql)
25
+ - [PostgreSQL Storage](https://mastra.ai/reference/v1/storage/postgresql)
26
+ - [MongoDB Storage](https://mastra.ai/reference/v1/storage/mongodb)
27
+ - [Upstash Storage](https://mastra.ai/reference/v1/storage/upstash)
28
+ - [Cloudflare D1](https://mastra.ai/reference/v1/storage/cloudflare-d1)
29
+ - [Cloudflare Durable Objects](https://mastra.ai/reference/v1/storage/cloudflare)
30
+ - [Convex](https://mastra.ai/reference/v1/storage/convex)
31
+ - [DynamoDB](https://mastra.ai/reference/v1/storage/dynamodb)
32
+ - [LanceDB](https://mastra.ai/reference/v1/storage/lance)
33
+ - [Microsoft SQL Server](https://mastra.ai/reference/v1/storage/mssql)
34
+
35
+ > **Note:**
36
+ libSQL is the easiest way to get started because it doesn’t require running a separate database server
37
+
38
+ ## Configuration scope
39
+
40
+ You can configure storage at two different scopes:
41
+
42
+ ### Instance-level storage
43
+
44
+ Add storage to your Mastra instance so all agents, workflows, observability traces and scores share the same memory provider:
45
+
46
+ ```typescript
47
+ import { Mastra } from "@mastra/core";
48
+ import { PostgresStore } from "@mastra/pg";
49
+
50
+ export const mastra = new Mastra({
51
+ storage: new PostgresStore({
52
+ id: 'mastra-storage',
53
+ connectionString: process.env.DATABASE_URL,
54
+ }),
55
+ });
56
+
57
+ // All agents automatically use this storage
58
+ const agent1 = new Agent({ id: "agent-1", memory: new Memory() });
59
+ const agent2 = new Agent({ id: "agent-2", memory: new Memory() });
60
+ ```
61
+
62
+ This is useful when all primitives share the same storage backend and have similar performance, scaling, and operational requirements.
63
+
64
+ #### Composite storage
65
+
66
+ Add storage to your Mastra instance using `MastraStorage` and configure individual storage domains to use different storage providers.
67
+
68
+ ```typescript title="src/mastra/index.ts"
69
+ import { Mastra } from "@mastra/core";
70
+ import { MastraStorage } from "@mastra/core/storage";
71
+ import { MemoryLibSQL } from "@mastra/libsql";
72
+ import { WorkflowsPG } from "@mastra/pg";
73
+ import { ObservabilityStorageClickhouse } from "@mastra/clickhouse";
74
+
75
+ export const mastra = new Mastra({
76
+ storage: new MastraStorage({
77
+ id: "composite",
78
+ domains: {
79
+ memory: new MemoryLibSQL({ url: "file:./memory.db" }),
80
+ workflows: new WorkflowsPG({ connectionString: process.env.DATABASE_URL }),
81
+ observability: new ObservabilityStorageClickhouse({
82
+ url: process.env.CLICKHOUSE_URL,
83
+ username: process.env.CLICKHOUSE_USERNAME,
84
+ password: process.env.CLICKHOUSE_PASSWORD,
85
+ }),
86
+ },
87
+ }),
88
+ });
89
+ ```
90
+
91
+ This is useful when different types of data have different performance or operational requirements, such as low-latency storage for memory, durable storage for workflows, and high-throughput storage for observability.
92
+
93
+ > **Note:**
94
+ See [Storage Domains](https://mastra.ai/reference/v1/storage/composite#storage-domains) for more information.
95
+
96
+ ### Agent-level storage
97
+
98
+ Agent-level storage overrides storage configured at the instance-level. Add storage to a specific agent when you need data boundaries or compliance requirements:
99
+
100
+ ```typescript title="src/mastra/agents/memory-agent.ts"
101
+ import { Agent } from "@mastra/core/agent";
102
+ import { Memory } from "@mastra/memory";
103
+ import { PostgresStore } from "@mastra/pg";
104
+
105
+ export const agent = new Agent({
106
+ id: "agent",
107
+ memory: new Memory({
108
+ storage: new PostgresStore({
109
+ id: 'agent-storage',
110
+ connectionString: process.env.AGENT_DATABASE_URL,
111
+ }),
112
+ }),
113
+ });
114
+ ```
115
+
116
+ This is useful when different agents need to store data in separate databases for security, compliance, or organizational reasons.
117
+
118
+ ## Threads and resources
119
+
120
+ Mastra organizes memory into threads using two identifiers:
121
+
122
+ - **Thread**: A conversation session containing a sequence of messages (e.g., `convo_123`)
123
+ - **Resource**: An identifier for the entity the thread belongs to, typically a user (e.g., `user_123`)
124
+
125
+ Both identifiers are required for agents to store and recall information:
126
+
127
+ ```typescript
128
+ const stream = await agent.stream("message for agent", {
129
+ memory: {
130
+ thread: "convo_123",
131
+ resource: "user_123",
132
+ },
133
+ });
134
+ ```
135
+
136
+ > **Note:**
137
+ [Studio](https://mastra.ai/docs/v1/getting-started/studio) automatically generates a thread and resource ID for you. Remember to to pass these explicitly when calling `stream` or `generate` yourself.
138
+
139
+ ### Thread title generation
140
+
141
+ Mastra can automatically generate descriptive thread titles based on the user's first message.
142
+
143
+ Use this option when implementing a ChatGPT-style chat interface to render a title alongside each thread in the conversation list (for example, in a sidebar) derived from the thread’s initial user message.
144
+
145
+ ```typescript
146
+ export const testAgent = new Agent({
147
+ id: "test-agent",
148
+ memory: new Memory({
149
+ options: {
150
+ generateTitle: true,
151
+ },
152
+ }),
153
+ });
154
+ ```
155
+
156
+ Title generation runs asynchronously after the agent responds and does not affect response time.
157
+
158
+ To optimize cost or behavior, provide a smaller `model` and custom `instructions`:
159
+
160
+ ```typescript
161
+ export const testAgent = new Agent({
162
+ id: "test-agent",
163
+ memory: new Memory({
164
+ options: {
165
+ generateTitle: {
166
+ model: "openai/gpt-4o-mini",
167
+ instructions: "Generate a concise title based on the user's first message",
168
+ },
169
+ },
170
+ }),
171
+ });
172
+ ```
173
+
174
+ ## Semantic recall
175
+
176
+ Semantic recall uses vector embeddings to retrieve relevant past messages based on meaning rather than recency. This requires a vector database instance, which can be configured at the instance or agent level.
177
+
178
+ The vector database doesn't have to be the same as your storage provider. For example, you might use PostgreSQL for storage and Pinecone for vectors:
179
+
180
+ ```typescript
181
+ import { Mastra } from "@mastra/core";
182
+ import { Agent } from "@mastra/core/agent";
183
+ import { Memory } from "@mastra/memory";
184
+ import { PostgresStore } from "@mastra/pg";
185
+ import { PineconeVector } from "@mastra/pinecone";
186
+
187
+ // Instance-level vector configuration
188
+ export const mastra = new Mastra({
189
+ storage: new PostgresStore({
190
+ id: 'mastra-storage',
191
+ connectionString: process.env.DATABASE_URL,
192
+ }),
193
+ });
194
+
195
+ // Agent-level vector configuration
196
+ export const agent = new Agent({
197
+ id: "agent",
198
+ memory: new Memory({
199
+ vector: new PineconeVector({
200
+ id: 'agent-vector',
201
+ apiKey: process.env.PINECONE_API_KEY,
202
+ }),
203
+ options: {
204
+ semanticRecall: {
205
+ topK: 5,
206
+ messageRange: 2,
207
+ },
208
+ },
209
+ }),
210
+ });
211
+ ```
212
+
213
+ We support all popular vector providers including [Pinecone](https://mastra.ai/reference/v1/vectors/pinecone), [Chroma](https://mastra.ai/reference/v1/vectors/chroma), [Qdrant](https://mastra.ai/reference/v1/vectors/qdrant), and many more.
214
+
215
+ For more information on configuring semantic recall, see the [Semantic Recall](./semantic-recall) documentation.