@mastra/pg 1.36.0-alpha.0 → 1.36.0-alpha.2
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/dist/docs/SKILL.md +2 -13
- package/dist/docs/assets/SOURCE_MAP.json +30 -30
- package/dist/docs/references/integrations-databases-neon.md +37 -1
- package/dist/docs/references/integrations-databases-postgresql.md +46 -0
- package/dist/docs/references/reference-memory-memory-class.md +1 -1
- package/dist/docs/references/reference-processors-semantic-recall-processor.md +5 -3
- package/dist/index.cjs +50 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +50 -33
- package/dist/index.js.map +1 -1
- package/dist/storage/db/index.d.ts +5 -0
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/db/schema-snapshot.d.ts +8 -0
- package/dist/storage/db/schema-snapshot.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/feedback.d.ts +1 -0
- package/dist/storage/domains/observability/v-next/feedback.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/index.d.ts +1 -0
- package/dist/storage/domains/observability/v-next/index.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/docs/references/docs-deployment-workers.md +0 -404
- package/dist/docs/references/docs-memory-semantic-recall.md +0 -485
- package/dist/docs/references/docs-memory-working-memory.md +0 -450
- package/dist/docs/references/docs-storage.md +0 -224
- package/dist/docs/references/reference-rag-retrieval.md +0 -672
- package/dist/docs/references/reference-rag-vector-databases.md +0 -808
- package/dist/docs/references/reference-storage-composite.md +0 -433
- package/dist/docs/references/reference-storage-retention.md +0 -310
package/dist/docs/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: mastra-pg
|
|
|
3
3
|
description: Documentation for @mastra/pg. Use when working with @mastra/pg APIs, configuration, or implementation.
|
|
4
4
|
metadata:
|
|
5
5
|
package: "@mastra/pg"
|
|
6
|
-
version: "1.36.0-alpha.
|
|
6
|
+
version: "1.36.0-alpha.2"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## When to use
|
|
@@ -14,18 +14,11 @@ Use this skill whenever you are working with @mastra/pg to obtain the domain-spe
|
|
|
14
14
|
|
|
15
15
|
Read the individual reference documents for detailed explanations and code examples.
|
|
16
16
|
|
|
17
|
-
### Docs
|
|
18
|
-
|
|
19
|
-
- [Workers](references/docs-deployment-workers.md) - Run Mastra workflow orchestration, schedules, and long-running background tasks in dedicated workers to keep API processes responsive under load.
|
|
20
|
-
- [Semantic recall](references/docs-memory-semantic-recall.md) - Retrieve relevant messages from past Mastra conversations with semantic recall, vector search, embeddings, metadata filters, and configurable storage.
|
|
21
|
-
- [Working memory](references/docs-memory-working-memory.md) - Persist user profiles, preferences, and application data with Mastra working memory using resource- or thread-scoped templates and storage adapters.
|
|
22
|
-
- [Storage](references/docs-storage.md) - Configure Mastra storage to persist memory, workflow state, observability data, evals, schedules, and long-running agent state across restarts.
|
|
23
|
-
|
|
24
17
|
### Integrations
|
|
25
18
|
|
|
26
19
|
- [ClickHouse Managed Postgres](references/integrations-databases-clickhouse-managed-postgres.md) - Store Mastra application data in ClickHouse Managed Postgres with PostgresStore and verified TLS.
|
|
27
20
|
- [DynamoDB](references/integrations-databases-dynamodb.md) - Persist Mastra data in Amazon DynamoDB with a single-table ElectroDB design, configurable indexes, TTL support, credentials, and table initialization.
|
|
28
|
-
- [Neon Postgres](references/integrations-databases-neon.md) - Connect Mastra to Neon Postgres with PostgresStore, pooled production connections, schema initialization, vector search, and Neon agent skills.
|
|
21
|
+
- [Neon Postgres](references/integrations-databases-neon.md) - Connect Mastra to Neon Postgres with PostgresStore, pooled production connections, schema initialization, vector search, and Neon agent skills, and give agents Neon tools through Mastra Connect.
|
|
29
22
|
- [PostgreSQL](references/integrations-databases-postgresql.md) - Persist Mastra application data in PostgreSQL with PostgresStore, configure connections and pools, initialize schemas, and enable observability.
|
|
30
23
|
- [PG](references/integrations-vectors-pg.md) - Run pgvector similarity search inside PostgreSQL from Mastra with HNSW or IVFFlat indexing, metadata filtering, and direct connection pool access.
|
|
31
24
|
|
|
@@ -38,10 +31,6 @@ Read the individual reference documents for detailed explanations and code examp
|
|
|
38
31
|
- [Chunking and embedding documents](references/reference-rag-chunking-and-embedding.md) - Chunk documents with MDocument, generate embeddings through the AI SDK, and prepare text and metadata for vector storage and RAG retrieval.
|
|
39
32
|
- [Reference: Metadata filters](references/reference-rag-metadata-filters.md) - Mastra provides a unified metadata filtering syntax across all vector stores, based on MongoDB/Sift query syntax.
|
|
40
33
|
- [RAG (Retrieval-Augmented Generation) in Mastra](references/reference-rag-overview.md) - RAG in Mastra helps you enhance LLM outputs by incorporating relevant context from your own data sources, improving accuracy and grounding responses in real information.
|
|
41
|
-
- [Retrieval, semantic search, reranking](references/reference-rag-retrieval.md) - After storing embeddings, you need to retrieve relevant chunks to answer user queries.
|
|
42
|
-
- [Storing embeddings in a vector database](references/reference-rag-vector-databases.md) - After generating embeddings, you need to store them in a database that supports vector similarity search.
|
|
43
|
-
- [Reference: Composite storage](references/reference-storage-composite.md) - MastraCompositeStore can compose storage domains from different providers. Use it when you need different databases for different purposes.
|
|
44
|
-
- [Reference: Storage retention (prune)](references/reference-storage-retention.md) - prune() deletes rows. It caps growth and is safe to run against large tables (batched, bounded, resumable, cancellable).
|
|
45
34
|
- [Reference: createVectorQueryTool()](references/reference-tools-vector-query-tool.md) - The createVectorQueryTool() function creates a tool for semantic search over vector stores.
|
|
46
35
|
|
|
47
36
|
|
|
@@ -1,86 +1,86 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.36.0-alpha.
|
|
2
|
+
"version": "1.36.0-alpha.2",
|
|
3
3
|
"package": "@mastra/pg",
|
|
4
4
|
"exports": {
|
|
5
5
|
"AgentsPG": {
|
|
6
6
|
"types": "dist/storage/domains/agents/index.d.ts",
|
|
7
7
|
"implementation": "dist/index.js",
|
|
8
|
-
"line":
|
|
8
|
+
"line": 4371
|
|
9
9
|
},
|
|
10
10
|
"BackgroundTasksPG": {
|
|
11
11
|
"types": "dist/storage/domains/background-tasks/index.d.ts",
|
|
12
12
|
"implementation": "dist/index.js",
|
|
13
|
-
"line":
|
|
13
|
+
"line": 5302
|
|
14
14
|
},
|
|
15
15
|
"BlobsPG": {
|
|
16
16
|
"types": "dist/storage/domains/blobs/index.d.ts",
|
|
17
17
|
"implementation": "dist/index.js",
|
|
18
|
-
"line":
|
|
18
|
+
"line": 5693
|
|
19
19
|
},
|
|
20
20
|
"ChannelsPG": {
|
|
21
21
|
"types": "dist/storage/domains/channels/index.d.ts",
|
|
22
22
|
"implementation": "dist/index.js",
|
|
23
|
-
"line":
|
|
23
|
+
"line": 5795
|
|
24
24
|
},
|
|
25
25
|
"DatasetsPG": {
|
|
26
26
|
"types": "dist/storage/domains/datasets/index.d.ts",
|
|
27
27
|
"implementation": "dist/index.js",
|
|
28
|
-
"line":
|
|
28
|
+
"line": 6037
|
|
29
29
|
},
|
|
30
30
|
"ExperimentsPG": {
|
|
31
31
|
"types": "dist/storage/domains/experiments/index.d.ts",
|
|
32
32
|
"implementation": "dist/index.js",
|
|
33
|
-
"line":
|
|
33
|
+
"line": 7294
|
|
34
34
|
},
|
|
35
35
|
"FavoritesPG": {
|
|
36
36
|
"types": "dist/storage/domains/favorites/index.d.ts",
|
|
37
37
|
"implementation": "dist/index.js",
|
|
38
|
-
"line":
|
|
38
|
+
"line": 8266
|
|
39
39
|
},
|
|
40
40
|
"KnowledgePG": {
|
|
41
41
|
"types": "dist/storage/domains/knowledge/index.d.ts",
|
|
42
42
|
"implementation": "dist/index.js",
|
|
43
|
-
"line":
|
|
43
|
+
"line": 10144
|
|
44
44
|
},
|
|
45
45
|
"MCPClientsPG": {
|
|
46
46
|
"types": "dist/storage/domains/mcp-clients/index.d.ts",
|
|
47
47
|
"implementation": "dist/index.js",
|
|
48
|
-
"line":
|
|
48
|
+
"line": 10301
|
|
49
49
|
},
|
|
50
50
|
"MCPServersPG": {
|
|
51
51
|
"types": "dist/storage/domains/mcp-servers/index.d.ts",
|
|
52
52
|
"implementation": "dist/index.js",
|
|
53
|
-
"line":
|
|
53
|
+
"line": 10870
|
|
54
54
|
},
|
|
55
55
|
"MemoryPG": {
|
|
56
56
|
"types": "dist/storage/domains/memory/index.d.ts",
|
|
57
57
|
"implementation": "dist/index.js",
|
|
58
|
-
"line":
|
|
58
|
+
"line": 11658
|
|
59
59
|
},
|
|
60
60
|
"NotificationsPG": {
|
|
61
61
|
"types": "dist/storage/domains/notifications/index.d.ts",
|
|
62
62
|
"implementation": "dist/index.js",
|
|
63
|
-
"line":
|
|
63
|
+
"line": 14469
|
|
64
64
|
},
|
|
65
65
|
"ObservabilityPG": {
|
|
66
66
|
"types": "dist/storage/domains/observability/index.d.ts",
|
|
67
67
|
"implementation": "dist/index.js",
|
|
68
|
-
"line":
|
|
68
|
+
"line": 14891
|
|
69
69
|
},
|
|
70
70
|
"ObservabilityStoragePostgresVNext": {
|
|
71
71
|
"types": "dist/storage/domains/observability/v-next/index.d.ts",
|
|
72
72
|
"implementation": "dist/index.js",
|
|
73
|
-
"line":
|
|
73
|
+
"line": 21810
|
|
74
74
|
},
|
|
75
75
|
"PGVECTOR_PROMPT": {
|
|
76
76
|
"types": "dist/vector/prompt.d.ts",
|
|
77
77
|
"implementation": "dist/index.js",
|
|
78
|
-
"line":
|
|
78
|
+
"line": 28481
|
|
79
79
|
},
|
|
80
80
|
"PgFactoryStorage": {
|
|
81
81
|
"types": "dist/storage/factory-storage.d.ts",
|
|
82
82
|
"implementation": "dist/index.js",
|
|
83
|
-
"line":
|
|
83
|
+
"line": 27967
|
|
84
84
|
},
|
|
85
85
|
"PgVector": {
|
|
86
86
|
"types": "dist/vector/index.d.ts",
|
|
@@ -95,67 +95,67 @@
|
|
|
95
95
|
"PostgresStore": {
|
|
96
96
|
"types": "dist/storage/index.d.ts",
|
|
97
97
|
"implementation": "dist/index.js",
|
|
98
|
-
"line":
|
|
98
|
+
"line": 28182
|
|
99
99
|
},
|
|
100
100
|
"PostgresStoreVNext": {
|
|
101
101
|
"types": "dist/storage/index.d.ts",
|
|
102
102
|
"implementation": "dist/index.js",
|
|
103
|
-
"line":
|
|
103
|
+
"line": 28400
|
|
104
104
|
},
|
|
105
105
|
"PromptBlocksPG": {
|
|
106
106
|
"types": "dist/storage/domains/prompt-blocks/index.d.ts",
|
|
107
107
|
"implementation": "dist/index.js",
|
|
108
|
-
"line":
|
|
108
|
+
"line": 22255
|
|
109
109
|
},
|
|
110
110
|
"SchedulesPG": {
|
|
111
111
|
"types": "dist/storage/domains/schedules/index.d.ts",
|
|
112
112
|
"implementation": "dist/index.js",
|
|
113
|
-
"line":
|
|
113
|
+
"line": 22882
|
|
114
114
|
},
|
|
115
115
|
"ScorerDefinitionsPG": {
|
|
116
116
|
"types": "dist/storage/domains/scorer-definitions/index.d.ts",
|
|
117
117
|
"implementation": "dist/index.js",
|
|
118
|
-
"line":
|
|
118
|
+
"line": 23203
|
|
119
119
|
},
|
|
120
120
|
"ScoresPG": {
|
|
121
121
|
"types": "dist/storage/domains/scores/index.d.ts",
|
|
122
122
|
"implementation": "dist/index.js",
|
|
123
|
-
"line":
|
|
123
|
+
"line": 23826
|
|
124
124
|
},
|
|
125
125
|
"SkillsPG": {
|
|
126
126
|
"types": "dist/storage/domains/skills/index.d.ts",
|
|
127
127
|
"implementation": "dist/index.js",
|
|
128
|
-
"line":
|
|
128
|
+
"line": 24269
|
|
129
129
|
},
|
|
130
130
|
"ThreadStatePG": {
|
|
131
131
|
"types": "dist/storage/domains/thread-state/index.d.ts",
|
|
132
132
|
"implementation": "dist/index.js",
|
|
133
|
-
"line":
|
|
133
|
+
"line": 24960
|
|
134
134
|
},
|
|
135
135
|
"ToolProviderConnectionsPG": {
|
|
136
136
|
"types": "dist/storage/domains/tool-provider-connections/index.d.ts",
|
|
137
137
|
"implementation": "dist/index.js",
|
|
138
|
-
"line":
|
|
138
|
+
"line": 25134
|
|
139
139
|
},
|
|
140
140
|
"WorkflowDefinitionsPG": {
|
|
141
141
|
"types": "dist/storage/domains/workflow-definitions/index.d.ts",
|
|
142
142
|
"implementation": "dist/index.js",
|
|
143
|
-
"line":
|
|
143
|
+
"line": 25398
|
|
144
144
|
},
|
|
145
145
|
"WorkflowsPG": {
|
|
146
146
|
"types": "dist/storage/domains/workflows/index.d.ts",
|
|
147
147
|
"implementation": "dist/index.js",
|
|
148
|
-
"line":
|
|
148
|
+
"line": 25781
|
|
149
149
|
},
|
|
150
150
|
"WorkspacesPG": {
|
|
151
151
|
"types": "dist/storage/domains/workspaces/index.d.ts",
|
|
152
152
|
"implementation": "dist/index.js",
|
|
153
|
-
"line":
|
|
153
|
+
"line": 27067
|
|
154
154
|
},
|
|
155
155
|
"exportSchemas": {
|
|
156
156
|
"types": "dist/storage/index.d.ts",
|
|
157
157
|
"implementation": "dist/index.js",
|
|
158
|
-
"line":
|
|
158
|
+
"line": 28149
|
|
159
159
|
}
|
|
160
160
|
},
|
|
161
161
|
"modules": {}
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
[Neon](https://neon.com) is a managed PostgreSQL service. Mastra connects to Neon through [`PostgresStore`](https://mastra.ai/integrations/databases/postgresql), which uses the Node.js `pg` driver. Neon doesn't require a separate Mastra storage package.
|
|
8
8
|
|
|
9
|
+
You can also give an agent tools to manage Neon projects and branches, run SQL, and apply schema migrations through [Mastra Connect](#connect).
|
|
10
|
+
|
|
9
11
|
## Quickstart
|
|
10
12
|
|
|
11
13
|
Create a Neon project, then copy its [pooled connection string](https://neon.com/docs/connect/connect-from-any-app) into `DATABASE_URL`.
|
|
@@ -219,4 +221,38 @@ const vector = new PgVector({
|
|
|
219
221
|
})
|
|
220
222
|
```
|
|
221
223
|
|
|
222
|
-
Setting `disableInit: true` prevents the runtime process from creating or changing the extension, tables and indexes.
|
|
224
|
+
Setting `disableInit: true` prevents the runtime process from creating or changing the extension, tables and indexes.
|
|
225
|
+
|
|
226
|
+
## Connect
|
|
227
|
+
|
|
228
|
+
Before you start, complete the [Connect setup](https://mastra.ai/docs/mastra-platform/connect) to install `@mastra/connect` and configure your platform project.
|
|
229
|
+
|
|
230
|
+
### Agent tools
|
|
231
|
+
|
|
232
|
+
Give agents tools from Neon's hosted Model Context Protocol (MCP) server to manage projects and branches, run SQL, and plan and apply schema migrations in Neon.
|
|
233
|
+
|
|
234
|
+
Connect an account with the `neon-mcp` provider ID. Run this command from the directory that contains your `.env` file:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
mastra connect add neon-mcp
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Then pass [`tools()`](https://mastra.ai/reference/connect/tools) to the agent and select the provider:
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import { Agent } from '@mastra/core/agent'
|
|
244
|
+
import { tools } from '@mastra/connect'
|
|
245
|
+
|
|
246
|
+
export const neonMcpAgent = new Agent({
|
|
247
|
+
id: 'neon-mcp-agent',
|
|
248
|
+
name: 'Neon agent',
|
|
249
|
+
instructions:
|
|
250
|
+
'You help people manage projects and branches, run SQL, and plan and apply schema migrations in Neon.',
|
|
251
|
+
model: '__GATEWAY_OPENAI_MODEL_LUNA__',
|
|
252
|
+
tools: tools({ providers: ['neon-mcp'] }),
|
|
253
|
+
})
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Mastra discovers Neon's tools from its MCP server when the agent runs. The available tools depend on the server and the connected account, not on your `@mastra/connect` version. Tool keys start with `neon-mcp_`.
|
|
257
|
+
|
|
258
|
+
To see which tools Neon provides, read the [Neon MCP server](https://neon.com/docs/ai/neon-mcp-server) documentation. To require approval before a call runs, see [MCP providers](https://mastra.ai/reference/connect/tools) in the `tools()` reference.
|
|
@@ -243,6 +243,52 @@ const thread = await memoryStore?.getThreadById({ threadId: '...' })
|
|
|
243
243
|
|
|
244
244
|
> **Warning:** If `init()` isn't called, tables won't be created and storage operations will fail silently or throw errors.
|
|
245
245
|
|
|
246
|
+
### Managed PostgreSQL and connection poolers
|
|
247
|
+
|
|
248
|
+
`PostgresStore` connects to managed PostgreSQL providers with the connection string they give you. No provider-specific package is required.
|
|
249
|
+
|
|
250
|
+
`init()` runs all schema changes on a single connection, so it works through transaction-mode connection poolers such as PgBouncer. You can use the provider's pooled connection string and let Mastra create the schema on startup.
|
|
251
|
+
|
|
252
|
+
#### Separate schema initialization
|
|
253
|
+
|
|
254
|
+
If the runtime database role can't create tables or indexes, run `init()` once during deployment with a role that can:
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
import { PostgresStore } from '@mastra/pg'
|
|
258
|
+
|
|
259
|
+
const storage = new PostgresStore({
|
|
260
|
+
id: 'pg-storage-init',
|
|
261
|
+
connectionString: process.env.DATABASE_ADMIN_URL,
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
try {
|
|
265
|
+
await storage.init()
|
|
266
|
+
// Only needed if the application uses Knowledge
|
|
267
|
+
await storage.initKnowledge()
|
|
268
|
+
} finally {
|
|
269
|
+
await storage.close()
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
The runtime role needs read and write access to the tables this script creates. See [PostgreSQL privileges](https://www.postgresql.org/docs/current/ddl-priv.html).
|
|
274
|
+
|
|
275
|
+
Then set `disableInit: true` on the runtime store so it skips schema creation:
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
import { Mastra } from '@mastra/core'
|
|
279
|
+
import { PostgresStore } from '@mastra/pg'
|
|
280
|
+
|
|
281
|
+
export const mastra = new Mastra({
|
|
282
|
+
storage: new PostgresStore({
|
|
283
|
+
id: 'pg-storage',
|
|
284
|
+
connectionString: process.env.DATABASE_URL,
|
|
285
|
+
disableInit: true,
|
|
286
|
+
}),
|
|
287
|
+
})
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
`disableInit: true` also makes explicit `init()` calls a no-op, so leave it off the store in the deployment script.
|
|
291
|
+
|
|
246
292
|
### Using an Existing Pool
|
|
247
293
|
|
|
248
294
|
If you already have a `pg.Pool` in your application (e.g., shared with an ORM or for Row Level Security), you can pass it directly to `PostgresStore`:
|
|
@@ -49,7 +49,7 @@ export const agent = new Agent({
|
|
|
49
49
|
|
|
50
50
|
**options.retainFullInput** (`boolean`): When true, the request input is processed exactly as supplied instead of being filtered against stored history. Use this when you assemble the input yourself and need the message sequence preserved. Stored history is still loaded underneath, and every input message that isn't already stored is saved to the thread, including few-shot examples. Can be set per call on memory.options or agent-wide in the memory constructor options.
|
|
51
51
|
|
|
52
|
-
**options.semanticRecall** (`boolean | { topK: number; messageRange: number | { before: number; after: number }; scope?: 'thread' | 'resource' }`): Enable semantic search in message history. Can be a boolean or an object with configuration options. When enabled, requires a vector store, and an embedder unless the vector store embeds text itself (isSelfEmbedding). Default topK is 4, default messageRange is {before: 1, after: 1}.
|
|
52
|
+
**options.semanticRecall** (`boolean | { topK: number; messageRange: number | { before: number; after: number }; scope?: 'thread' | 'resource'; maxChunkChars?: number }`): Enable semantic search in message history. Can be a boolean or an object with configuration options. When enabled, requires a vector store, and an embedder unless the vector store embeds text itself (isSelfEmbedding). Default topK is 4, default messageRange is {before: 1, after: 1}. maxChunkChars caps the characters of message text per embedded chunk; see Long messages.
|
|
53
53
|
|
|
54
54
|
**options.workingMemory** (`WorkingMemory`): Configuration for working memory feature. Can be { enabled: boolean; template?: string; schema?: ZodObject\<any> | JSONSchema7; scope?: 'thread' | 'resource' } or { enabled: boolean } to disable.
|
|
55
55
|
|
|
@@ -44,6 +44,8 @@ const processor = new SemanticRecall({
|
|
|
44
44
|
|
|
45
45
|
**options.logger** (`IMastraLogger`): Optional logger instance for structured logging
|
|
46
46
|
|
|
47
|
+
**options.maxChunkChars** (`number`): Largest number of characters of message text sent to the embedder in one input. Longer messages are split into chunks, each stored as its own vector row. When unset, the limit comes from the embedder's maxInputTokens if it declares one (FastEmbed models do), otherwise 16,384 characters (about 4,096 English tokens).
|
|
48
|
+
|
|
47
49
|
## Returns
|
|
48
50
|
|
|
49
51
|
**id** (`string`): Processor identifier set to 'semantic-recall'
|
|
@@ -105,9 +107,9 @@ export const agent = new Agent({
|
|
|
105
107
|
|
|
106
108
|
### Output processing
|
|
107
109
|
|
|
108
|
-
1. Extracts text content from new user and assistant messages
|
|
109
|
-
2.
|
|
110
|
-
3. Stores
|
|
110
|
+
1. Extracts text content from new user and assistant messages, skipping messages already embedded earlier in the same run
|
|
111
|
+
2. Splits long messages into chunks of at most `maxChunkChars` characters and generates an embedding for each chunk
|
|
112
|
+
3. Stores one vector row per chunk with metadata (thread metadata, message ID, thread ID, resource ID, role, content, timestamp). Row IDs are derived from the message ID (the first chunk uses a UUID message ID as is), so saving the same message again replaces its rows instead of adding new ones
|
|
111
113
|
4. Uses LRU caching for embeddings to avoid redundant API calls
|
|
112
114
|
|
|
113
115
|
### Cross-thread recall
|
package/dist/index.cjs
CHANGED
|
@@ -2719,7 +2719,8 @@ async function loadSchemaSnapshot(client, schemaName) {
|
|
|
2719
2719
|
notNullColumns,
|
|
2720
2720
|
indexes,
|
|
2721
2721
|
replicaIdentityIndexes,
|
|
2722
|
-
primaryKeyIndexes
|
|
2722
|
+
primaryKeyIndexes,
|
|
2723
|
+
createdTables: /* @__PURE__ */ new Set()
|
|
2723
2724
|
};
|
|
2724
2725
|
}
|
|
2725
2726
|
// src/storage/db/index.ts
|
|
@@ -2879,26 +2880,30 @@ function generateTableSQL({ tableName, schema, schemaName, compositePrimaryKey,
|
|
|
2879
2880
|
` : ""}
|
|
2880
2881
|
`;
|
|
2881
2882
|
}
|
|
2883
|
+
function indexColumnsSQL(columns, opclass) {
|
|
2884
|
+
return columns.map((col) => {
|
|
2885
|
+
const [colName, ...modifiers] = col.includes(" DESC") || col.includes(" ASC") ? col.split(" ") : [col];
|
|
2886
|
+
if (!colName) throw new Error(`Invalid column specification: ${col}`);
|
|
2887
|
+
return [
|
|
2888
|
+
`"${(0, _mastra_core_utils.parseSqlIdentifier)(colName, "column name")}"`,
|
|
2889
|
+
opclass,
|
|
2890
|
+
...modifiers
|
|
2891
|
+
].filter(Boolean).join(" ");
|
|
2892
|
+
}).join(", ");
|
|
2893
|
+
}
|
|
2882
2894
|
/**
|
|
2883
2895
|
* Generates a CREATE INDEX SQL statement from index options.
|
|
2884
2896
|
* Used by exportSchemas to produce index DDL without a database connection.
|
|
2885
2897
|
*/
|
|
2886
2898
|
function generateIndexSQL(options, schemaName) {
|
|
2887
|
-
const { name, table, columns, unique = false, where, method = "btree" } = options;
|
|
2899
|
+
const { name, table, columns, unique = false, where, method = "btree", opclass } = options;
|
|
2888
2900
|
const fullTableName = getTableName$6({
|
|
2889
2901
|
indexName: table,
|
|
2890
2902
|
schemaName: getSchemaName$6(schemaName)
|
|
2891
2903
|
});
|
|
2892
2904
|
const uniqueStr = unique ? "UNIQUE " : "";
|
|
2893
2905
|
const methodStr = method !== "btree" ? `USING ${method} ` : "";
|
|
2894
|
-
const columnsStr = columns
|
|
2895
|
-
if (col.includes(" DESC") || col.includes(" ASC")) {
|
|
2896
|
-
const [colName, ...modifiers] = col.split(" ");
|
|
2897
|
-
if (!colName) throw new Error(`Invalid column specification: ${col}`);
|
|
2898
|
-
return `"${(0, _mastra_core_utils.parseSqlIdentifier)(colName, "column name")}" ${modifiers.join(" ")}`;
|
|
2899
|
-
}
|
|
2900
|
-
return `"${(0, _mastra_core_utils.parseSqlIdentifier)(col, "column name")}"`;
|
|
2901
|
-
}).join(", ");
|
|
2906
|
+
const columnsStr = indexColumnsSQL(columns, opclass);
|
|
2902
2907
|
const whereStr = where ? ` WHERE ${where}` : "";
|
|
2903
2908
|
return `CREATE ${uniqueStr}INDEX IF NOT EXISTS ${`"${(0, _mastra_core_utils.parseSqlIdentifier)(name, "index name")}"`} ON ${fullTableName} ${methodStr}(${columnsStr})${whereStr};`;
|
|
2904
2909
|
}
|
|
@@ -3409,6 +3414,7 @@ var PgDB = class extends _mastra_core_base.MastraBase {
|
|
|
3409
3414
|
if (this.schemaName) await this.setupSchema();
|
|
3410
3415
|
const snapshot = this.schemaSnapshot;
|
|
3411
3416
|
if (!snapshot || !this.snapshotShowsTableConverged(snapshot, tableName)) {
|
|
3417
|
+
const isNewTable = snapshot ? !snapshot.tables.has(tableName) : false;
|
|
3412
3418
|
const sql = generateTableSQL({
|
|
3413
3419
|
tableName,
|
|
3414
3420
|
schema,
|
|
@@ -3422,6 +3428,7 @@ var PgDB = class extends _mastra_core_base.MastraBase {
|
|
|
3422
3428
|
}
|
|
3423
3429
|
if (snapshot) {
|
|
3424
3430
|
snapshot.tables.add(tableName);
|
|
3431
|
+
if (isNewTable) snapshot.createdTables.add(tableName);
|
|
3425
3432
|
const created = this.snapshotColumns(snapshot, tableName);
|
|
3426
3433
|
for (const [name, def] of Object.entries(schema)) {
|
|
3427
3434
|
const parsedName = (0, _mastra_core_utils.parseSqlIdentifier)(name, "column name");
|
|
@@ -3890,18 +3897,9 @@ MIGRATION REQUIRED: Duplicate spans detected in ${duplicateInfo.tableName}\n====
|
|
|
3890
3897
|
const snapshot = this.schemaSnapshot;
|
|
3891
3898
|
if (snapshot?.indexes.has(name)) return;
|
|
3892
3899
|
const uniqueStr = unique ? "UNIQUE " : "";
|
|
3893
|
-
const concurrentStr = concurrent ? "CONCURRENTLY " : "";
|
|
3900
|
+
const concurrentStr = concurrent && !this.isTableCreatedInThisInit(table) ? "CONCURRENTLY " : "";
|
|
3894
3901
|
const methodStr = method !== "btree" ? `USING ${method} ` : "";
|
|
3895
|
-
const columnsStr = columns
|
|
3896
|
-
if (col.includes(" DESC") || col.includes(" ASC")) {
|
|
3897
|
-
const [colName, ...modifiers] = col.split(" ");
|
|
3898
|
-
if (!colName) throw new Error(`Invalid column specification: ${col}`);
|
|
3899
|
-
const quotedCol = `"${(0, _mastra_core_utils.parseSqlIdentifier)(colName, "column name")}" ${modifiers.join(" ")}`;
|
|
3900
|
-
return opclass ? `${quotedCol} ${opclass}` : quotedCol;
|
|
3901
|
-
}
|
|
3902
|
-
const quotedCol = `"${(0, _mastra_core_utils.parseSqlIdentifier)(col, "column name")}"`;
|
|
3903
|
-
return opclass ? `${quotedCol} ${opclass}` : quotedCol;
|
|
3904
|
-
}).join(", ");
|
|
3902
|
+
const columnsStr = indexColumnsSQL(columns, opclass);
|
|
3905
3903
|
const whereStr = where ? ` WHERE ${where}` : "";
|
|
3906
3904
|
const tablespaceStr = tablespace ? ` TABLESPACE ${tablespace}` : "";
|
|
3907
3905
|
let withStr = "";
|
|
@@ -3934,6 +3932,13 @@ MIGRATION REQUIRED: Duplicate spans detected in ${duplicateInfo.tableName}\n====
|
|
|
3934
3932
|
if (snapshot?.indexes.has(indexName)) return;
|
|
3935
3933
|
if (await buildIndex(this.client, this.schemaName || "public", indexName, () => this.timedIndexBuild(indexName, sql), this.logger)) snapshot?.indexes.add(indexName);
|
|
3936
3934
|
}
|
|
3935
|
+
/**
|
|
3936
|
+
* Whether `tableName` was absent when this init's snapshot was read and this
|
|
3937
|
+
* init created it, so its indexes can be built without CONCURRENTLY.
|
|
3938
|
+
*/
|
|
3939
|
+
isTableCreatedInThisInit(tableName) {
|
|
3940
|
+
return this.schemaSnapshot?.createdTables.has(tableName) ?? false;
|
|
3941
|
+
}
|
|
3937
3942
|
async timedIndexBuild(indexName, sql) {
|
|
3938
3943
|
const startedAt = Date.now();
|
|
3939
3944
|
this.logger.info(`Creating index ${indexName}`);
|
|
@@ -18337,6 +18342,11 @@ async function batchCreateFeedback(client, schema, args, partitioning) {
|
|
|
18337
18342
|
const rows = [...new Map(args.feedbacks.map((feedback) => [feedback.feedbackId, feedback])).values()].map(feedbackRecordToRow);
|
|
18338
18343
|
await insertRows(client, schema, TABLE_FEEDBACK_EVENTS, rows, partitioning, FEEDBACK_UPSERT_CLAUSE);
|
|
18339
18344
|
}
|
|
18345
|
+
async function getFeedbackById(client, schema, feedbackId) {
|
|
18346
|
+
const row = await client.oneOrNone(`SELECT ${FEEDBACK_SELECT_COLUMNS} FROM ${qualifiedTable(schema, TABLE_FEEDBACK_EVENTS)}
|
|
18347
|
+
WHERE "feedbackId" = $1 ORDER BY "cursorId" DESC LIMIT 1`, [feedbackId]);
|
|
18348
|
+
return row ? rowToFeedbackRecord(row) : null;
|
|
18349
|
+
}
|
|
18340
18350
|
async function updateFeedbackReviewStatus(client, schema, args) {
|
|
18341
18351
|
const { feedbackId, reviewStatus } = parseUpdateFeedbackReviewStatusArgs(args);
|
|
18342
18352
|
const row = await client.oneOrNone(`UPDATE ${qualifiedTable(schema, TABLE_FEEDBACK_EVENTS)}
|
|
@@ -22172,6 +22182,9 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
|
|
|
22172
22182
|
async getScoreById(scoreId) {
|
|
22173
22183
|
return this.#run("GET_SCORE_BY_ID", () => getScoreById(this.#readClient, this.#schema, scoreId), { scoreId });
|
|
22174
22184
|
}
|
|
22185
|
+
async getFeedbackById(feedbackId) {
|
|
22186
|
+
return this.#run("GET_FEEDBACK_BY_ID", () => getFeedbackById(this.#readClient, this.#schema, feedbackId), { feedbackId });
|
|
22187
|
+
}
|
|
22175
22188
|
async listFeedback(args) {
|
|
22176
22189
|
return this.#run("LIST_FEEDBACK", () => listFeedback(this.#readClient, this.#schema, args));
|
|
22177
22190
|
}
|
|
@@ -25956,15 +25969,16 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
25956
25969
|
this.logger?.warn?.(`Failed to create index ${stateBaseIndexName}:`, error);
|
|
25957
25970
|
}
|
|
25958
25971
|
if (await this.#db.getColumnType(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT, "snapshot") !== "jsonb") return;
|
|
25972
|
+
const concurrently = !this.#db.isTableCreatedInThisInit(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
25959
25973
|
const indexName = workflowSnapshotStatusIndexName(this.#schema);
|
|
25960
25974
|
try {
|
|
25961
|
-
await this.#db.createIndexFromStatement(indexName, workflowSnapshotStatusIndexSQL(indexName, this.#schema,
|
|
25975
|
+
await this.#db.createIndexFromStatement(indexName, workflowSnapshotStatusIndexSQL(indexName, this.#schema, concurrently));
|
|
25962
25976
|
} catch (error) {
|
|
25963
25977
|
this.logger?.warn?.(`Failed to create index ${indexName}:`, error);
|
|
25964
25978
|
}
|
|
25965
25979
|
const threadIdIndexName = workflowSnapshotThreadIdIndexName(this.#schema);
|
|
25966
25980
|
try {
|
|
25967
|
-
await this.#db.createIndexFromStatement(threadIdIndexName, workflowSnapshotThreadIdIndexSQL(threadIdIndexName, this.#schema,
|
|
25981
|
+
await this.#db.createIndexFromStatement(threadIdIndexName, workflowSnapshotThreadIdIndexSQL(threadIdIndexName, this.#schema, concurrently));
|
|
25968
25982
|
} catch (error) {
|
|
25969
25983
|
this.logger?.warn?.(`Failed to create index ${threadIdIndexName}:`, error);
|
|
25970
25984
|
}
|
|
@@ -27012,18 +27026,9 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
27012
27026
|
}
|
|
27013
27027
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
27014
27028
|
const v2WhereClause = v2Conditions.length > 0 ? `WHERE ${v2Conditions.join(" AND ")}` : "";
|
|
27015
|
-
let total = 0;
|
|
27016
27029
|
const usePagination = typeof perPage === "number" && typeof page === "number";
|
|
27017
|
-
if (usePagination) {
|
|
27018
|
-
const countResult = await this.#db.client.one(`SELECT (SELECT COUNT(*) FROM ${getTableName({
|
|
27019
|
-
indexName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
27020
|
-
schemaName: getSchemaName(this.#schema)
|
|
27021
|
-
})} ${whereClause})
|
|
27022
|
-
+ (SELECT COUNT(*) FROM ${this.#runsTable()} ${v2WhereClause}) AS count`, values);
|
|
27023
|
-
total = Number(countResult.count);
|
|
27024
|
-
}
|
|
27025
27030
|
const normalizedPerPage = usePagination ? (0, _mastra_core_storage.normalizePerPage)(perPage, Number.MAX_SAFE_INTEGER) : 0;
|
|
27026
|
-
const offset = usePagination ? page * normalizedPerPage :
|
|
27031
|
+
const offset = usePagination ? page * normalizedPerPage : 0;
|
|
27027
27032
|
let v1Snapshot = "snapshot";
|
|
27028
27033
|
if (summary) {
|
|
27029
27034
|
const snapshotJson = await this.#db.getColumnType(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT, "snapshot") === "jsonb" ? "snapshot" : `regexp_replace(snapshot::text, '\\\\u(0000|[Dd][89A-Fa-f][0-9A-Fa-f]{2})', '', 'g')::jsonb`;
|
|
@@ -27043,6 +27048,18 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
27043
27048
|
] : values;
|
|
27044
27049
|
const result = await this.#db.client.manyOrNone(query, queryValues);
|
|
27045
27050
|
const runs = await Promise.all((result || []).map((row) => this.#parseRun(this.#db.client, row)));
|
|
27051
|
+
let total = 0;
|
|
27052
|
+
if (usePagination) {
|
|
27053
|
+
total = offset + runs.length;
|
|
27054
|
+
if (runs.length === normalizedPerPage || runs.length === 0 && offset > 0) {
|
|
27055
|
+
const countResult = await this.#db.client.one(`SELECT (SELECT COUNT(*) FROM ${getTableName({
|
|
27056
|
+
indexName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
27057
|
+
schemaName: getSchemaName(this.#schema)
|
|
27058
|
+
})} ${whereClause})
|
|
27059
|
+
+ (SELECT COUNT(*) FROM ${this.#runsTable()} ${v2WhereClause}) AS count`, values);
|
|
27060
|
+
total = Number(countResult.count);
|
|
27061
|
+
}
|
|
27062
|
+
}
|
|
27046
27063
|
return {
|
|
27047
27064
|
runs,
|
|
27048
27065
|
total: total || runs.length
|