@mastra/pg 1.11.1 → 1.12.0-alpha.0
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 +27 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-memory-semantic-recall.md +1 -1
- package/dist/docs/references/docs-memory-storage.md +1 -1
- package/dist/docs/references/docs-rag-retrieval.md +4 -1
- package/dist/docs/references/reference-vectors-pg.md +2 -0
- package/dist/index.cjs +105 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +105 -48
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/pool-config.d.ts +24 -0
- package/dist/storage/pool-config.d.ts.map +1 -0
- package/dist/storage/test-utils.d.ts.map +1 -1
- package/dist/vector/index.d.ts.map +1 -1
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @mastra/pg
|
|
2
2
|
|
|
3
|
+
## 1.12.0-alpha.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added the `disableInit` option to the `MastraVector` base class. When set to `true`, vector stores skip creating schemas, extensions, tables, and indexes at application startup. This matches the existing `disableInit` behavior on storage adapters and is useful for deployments where schemas and indexes are created ahead of time by a privileged database role, while the application runs with a least-privilege role. ([#17272](https://github.com/mastra-ai/mastra/pull/17272))
|
|
8
|
+
|
|
9
|
+
**Usage**
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
const vector = new PgVector({
|
|
13
|
+
id: 'vectors',
|
|
14
|
+
connectionString: process.env.DATABASE_URL,
|
|
15
|
+
disableInit: true,
|
|
16
|
+
});
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The `MASTRA_DISABLE_STORAGE_INIT` environment variable also disables vector init, so a single flag prevents both storage and vector stores from creating schemas, tables, or indexes at startup.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Fixed `PostgresStore` ignoring an explicit `ssl` option when the `connectionString` also carries an `sslmode=`/`ssl=` query param. node-postgres re-parses the connection string and `Object.assign`s the URL-derived `ssl` over the explicit one, so a config like `{ connectionString: '...?sslmode=require', ssl: { rejectUnauthorized: false } }` silently dropped `rejectUnauthorized: false` and failed with `UNABLE_TO_GET_ISSUER_CERT_LOCALLY` against self-signed CAs. The connection-string branch now parses the URL and applies the explicit `ssl` last, while still honoring URL-driven SSL when no `ssl` option is provided. Fixes #17307. ([#17356](https://github.com/mastra-ai/mastra/pull/17356))
|
|
24
|
+
|
|
25
|
+
- Improved Postgres memory message save performance ([#17351](https://github.com/mastra-ai/mastra/pull/17351))
|
|
26
|
+
|
|
27
|
+
- Updated dependencies [[`8ace89d`](https://github.com/mastra-ai/mastra/commit/8ace89df77f762e622d3b9f7f65ad7524350d050), [`fa63872`](https://github.com/mastra-ai/mastra/commit/fa6387280954e6b667bec5714b55ba082bc627ff), [`f07b646`](https://github.com/mastra-ai/mastra/commit/f07b64604ab7d25391179790b7fd4823df9e2dff), [`d8838ae`](https://github.com/mastra-ai/mastra/commit/d8838ae80b69780361693d27098f7f6684af12fe), [`40f9297`](https://github.com/mastra-ai/mastra/commit/40f9297003b921c62373d3e8d3a4bda76c9f6de3), [`0f0d1ba`](https://github.com/mastra-ai/mastra/commit/0f0d1ba67bfcb2204e571401662f1eceefc03357), [`8c31bcd`](https://github.com/mastra-ai/mastra/commit/8c31bcdb00e597880d5939b1b7d7566fbe5dacae), [`95b14cd`](https://github.com/mastra-ai/mastra/commit/95b14cdd820e86d97ac05fe568424c513a252e31), [`aa36be2`](https://github.com/mastra-ai/mastra/commit/aa36be23aa513b7dc53cb8ca16b7fab8f20e43ad), [`212c635`](https://github.com/mastra-ai/mastra/commit/212c635203e61d036ab41db8ff86c3893dc795b3), [`d8838ae`](https://github.com/mastra-ai/mastra/commit/d8838ae80b69780361693d27098f7f6684af12fe), [`9aa5a73`](https://github.com/mastra-ai/mastra/commit/9aa5a73e7e110f6e9365eec69364a33d5f03bb56), [`f73c789`](https://github.com/mastra-ai/mastra/commit/f73c789e8ef21561580395d2c410119cab5848c8), [`8bd16da`](https://github.com/mastra-ai/mastra/commit/8bd16da73a4cb874d739373643dbd6a6e7f88684), [`c8630f8`](https://github.com/mastra-ai/mastra/commit/c8630f80d4f40cb5d22e60ab162b618b1907167a), [`47f71dc`](https://github.com/mastra-ai/mastra/commit/47f71dc6fbcbd12d71e21a979e676e20a02bd77d), [`50ceae2`](https://github.com/mastra-ai/mastra/commit/50ceae270878e2f8fb2b2c6c2faab09df0007c8a), [`8cdde58`](https://github.com/mastra-ai/mastra/commit/8cdde5875bbba6702d9df226f2b20232b8d75d6c), [`847ff1e`](https://github.com/mastra-ai/mastra/commit/847ff1e0d94368d94b2e173e4e0908e115568ef3), [`259d409`](https://github.com/mastra-ai/mastra/commit/259d409a514174299dbde1ff5e1121209b3ba850), [`9e16c68`](https://github.com/mastra-ai/mastra/commit/9e16c6818b6485ccb43df28aba6f3a2219d28662), [`cefca33`](https://github.com/mastra-ai/mastra/commit/cefca33ae666e69810c935fedf95a929c173d1d7), [`d00e8c5`](https://github.com/mastra-ai/mastra/commit/d00e8c50daebe5bce5bf2f48bde39c86fc3d2fe4), [`36fa7e2`](https://github.com/mastra-ai/mastra/commit/36fa7e24d14e58a1eb46147097b32f583e5b8775), [`87e9774`](https://github.com/mastra-ai/mastra/commit/87e97741c1e493cd6d62f478eb810b49bda4d57c), [`65a72e7`](https://github.com/mastra-ai/mastra/commit/65a72e70c25eedea8ff985a6624b96be2850236b), [`0f77241`](https://github.com/mastra-ai/mastra/commit/0f7724108806703799a8ba80ad0f09414afd5066), [`92ff509`](https://github.com/mastra-ai/mastra/commit/92ff5098ef8a990438ca038077021a5f7541ec1d), [`3fce5e7`](https://github.com/mastra-ai/mastra/commit/3fce5e70d011d289043e75003ef3336ed4aa43c3), [`a763592`](https://github.com/mastra-ai/mastra/commit/a763592c3db46963ef1011cfe16fe372816e775e), [`80c7737`](https://github.com/mastra-ai/mastra/commit/80c7737e32d7917b5f356957d67c169d01744fd3), [`3f1cf47`](https://github.com/mastra-ai/mastra/commit/3f1cf476f74c1e4cc2df908837e05853a5347e31)]:
|
|
28
|
+
- @mastra/core@1.38.0-alpha.3
|
|
29
|
+
|
|
3
30
|
## 1.11.1
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -247,7 +247,7 @@ const agent = new Agent({
|
|
|
247
247
|
})
|
|
248
248
|
```
|
|
249
249
|
|
|
250
|
-
The model router automatically handles API key detection from environment variables (`OPENAI_API_KEY`, `
|
|
250
|
+
The model router automatically handles API key detection from environment variables (`OPENAI_API_KEY`, `GOOGLE_API_KEY`, `OPENROUTER_API_KEY`). Google models also fall back to `GOOGLE_GENERATIVE_AI_API_KEY`.
|
|
251
251
|
|
|
252
252
|
### Using AI SDK Packages
|
|
253
253
|
|
|
@@ -472,7 +472,10 @@ const initialResults = await pgVector.query({
|
|
|
472
472
|
})
|
|
473
473
|
|
|
474
474
|
// Create a relevance scorer
|
|
475
|
-
const relevanceProvider = new MastraAgentRelevanceScorer(
|
|
475
|
+
const relevanceProvider = new MastraAgentRelevanceScorer(
|
|
476
|
+
'relevance-scorer',
|
|
477
|
+
'openai/gpt-5.4',
|
|
478
|
+
)
|
|
476
479
|
|
|
477
480
|
// Re-rank the results
|
|
478
481
|
const rerankedResults = await rerank({
|
|
@@ -26,6 +26,8 @@ The PgVector class provides vector search using [PostgreSQL](https://www.postgre
|
|
|
26
26
|
|
|
27
27
|
**pgPoolOptions** (`PoolConfig`): Additional pg pool configuration options
|
|
28
28
|
|
|
29
|
+
**disableInit** (`boolean`): When true, automatic DDL (schema, extension, table, and index creation) inside \`createIndex\` is skipped. Useful for CI/CD pipelines where schema and indexes are managed separately and the runtime database role lacks DDL privileges. Can also be enabled with the \`MASTRA\_DISABLE\_STORAGE\_INIT\` environment variable. (Default: `false`)
|
|
30
|
+
|
|
29
31
|
## Constructor examples
|
|
30
32
|
|
|
31
33
|
### Connection String
|
package/dist/index.cjs
CHANGED
|
@@ -13,6 +13,7 @@ var crypto$1 = require('crypto');
|
|
|
13
13
|
var module$1 = require('module');
|
|
14
14
|
var agent = require('@mastra/core/agent');
|
|
15
15
|
var evals = require('@mastra/core/evals');
|
|
16
|
+
var pgConnectionString = require('pg-connection-string');
|
|
16
17
|
|
|
17
18
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
18
19
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -631,7 +632,7 @@ var PgVector = class extends vector.MastraVector {
|
|
|
631
632
|
constructor(config) {
|
|
632
633
|
try {
|
|
633
634
|
validateConfig("PgVector", config);
|
|
634
|
-
super({ id: config.id });
|
|
635
|
+
super({ id: config.id, disableInit: config.disableInit });
|
|
635
636
|
this.schema = config.schemaName;
|
|
636
637
|
let poolConfig;
|
|
637
638
|
if (isConnectionStringConfig(config)) {
|
|
@@ -1245,6 +1246,9 @@ var PgVector = class extends vector.MastraVector {
|
|
|
1245
1246
|
this.logger?.trackException(mastraError);
|
|
1246
1247
|
throw mastraError;
|
|
1247
1248
|
}
|
|
1249
|
+
if (this.disableInit || process.env.MASTRA_DISABLE_STORAGE_INIT === "true") {
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1248
1252
|
const indexCacheKey = await this.getIndexCacheKey({
|
|
1249
1253
|
indexName,
|
|
1250
1254
|
dimension,
|
|
@@ -7980,6 +7984,9 @@ var MCPServersPG = class _MCPServersPG extends storage.MCPServersStorage {
|
|
|
7980
7984
|
}
|
|
7981
7985
|
};
|
|
7982
7986
|
var OM_TABLE = "mastra_observational_memory";
|
|
7987
|
+
var POSTGRES_MAX_BIND_PARAMETERS = 65535;
|
|
7988
|
+
var MESSAGE_INSERT_BIND_PARAMETERS = 8;
|
|
7989
|
+
var MAX_MESSAGES_PER_INSERT = Math.floor(POSTGRES_MAX_BIND_PARAMETERS / MESSAGE_INSERT_BIND_PARAMETERS);
|
|
7983
7990
|
var OM_MIGRATION_COLUMNS = [
|
|
7984
7991
|
"observedMessageIds",
|
|
7985
7992
|
"observedTimezone",
|
|
@@ -8014,6 +8021,24 @@ function getTableName4({ indexName, schemaName }) {
|
|
|
8014
8021
|
function inPlaceholders(count, startIndex = 1) {
|
|
8015
8022
|
return Array.from({ length: count }, (_, i) => `$${i + startIndex}`).join(", ");
|
|
8016
8023
|
}
|
|
8024
|
+
function dedupeMessagesForSave(messages) {
|
|
8025
|
+
const deduped = /* @__PURE__ */ new Map();
|
|
8026
|
+
for (const message of messages) {
|
|
8027
|
+
const existing = deduped.get(message.id);
|
|
8028
|
+
if (existing) {
|
|
8029
|
+
deduped.set(message.id, {
|
|
8030
|
+
...message,
|
|
8031
|
+
createdAt: existing.createdAt
|
|
8032
|
+
});
|
|
8033
|
+
} else {
|
|
8034
|
+
deduped.set(message.id, {
|
|
8035
|
+
...message,
|
|
8036
|
+
createdAt: message.createdAt || /* @__PURE__ */ new Date()
|
|
8037
|
+
});
|
|
8038
|
+
}
|
|
8039
|
+
}
|
|
8040
|
+
return Array.from(deduped.values());
|
|
8041
|
+
}
|
|
8017
8042
|
var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
8018
8043
|
supportsObservationalMemory = true;
|
|
8019
8044
|
#db;
|
|
@@ -8899,63 +8924,83 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
|
8899
8924
|
text: `Thread ID is required`
|
|
8900
8925
|
});
|
|
8901
8926
|
}
|
|
8902
|
-
const thread = await this.getThreadById({ threadId });
|
|
8903
|
-
if (!thread) {
|
|
8904
|
-
throw new error.MastraError({
|
|
8905
|
-
id: storage.createStorageErrorId("PG", "SAVE_MESSAGES", "FAILED"),
|
|
8906
|
-
domain: error.ErrorDomain.STORAGE,
|
|
8907
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
8908
|
-
text: `Thread ${threadId} not found`,
|
|
8909
|
-
details: {
|
|
8910
|
-
threadId
|
|
8911
|
-
}
|
|
8912
|
-
});
|
|
8913
|
-
}
|
|
8914
8927
|
try {
|
|
8915
8928
|
const tableName = getTableName4({ indexName: storage.TABLE_MESSAGES, schemaName: getSchemaName4(this.#schema) });
|
|
8929
|
+
const threadIds = /* @__PURE__ */ new Set();
|
|
8930
|
+
for (const message of messages) {
|
|
8931
|
+
if (!message.threadId) {
|
|
8932
|
+
throw new Error(
|
|
8933
|
+
`Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`
|
|
8934
|
+
);
|
|
8935
|
+
}
|
|
8936
|
+
if (!message.resourceId) {
|
|
8937
|
+
throw new Error(
|
|
8938
|
+
`Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`
|
|
8939
|
+
);
|
|
8940
|
+
}
|
|
8941
|
+
threadIds.add(message.threadId);
|
|
8942
|
+
}
|
|
8943
|
+
for (const threadIdToCheck of threadIds) {
|
|
8944
|
+
const thread = await this.getThreadById({ threadId: threadIdToCheck });
|
|
8945
|
+
if (!thread) {
|
|
8946
|
+
throw new error.MastraError({
|
|
8947
|
+
id: storage.createStorageErrorId("PG", "SAVE_MESSAGES", "FAILED"),
|
|
8948
|
+
domain: error.ErrorDomain.STORAGE,
|
|
8949
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
8950
|
+
text: `Thread ${threadIdToCheck} not found`,
|
|
8951
|
+
details: {
|
|
8952
|
+
threadId: threadIdToCheck
|
|
8953
|
+
}
|
|
8954
|
+
});
|
|
8955
|
+
}
|
|
8956
|
+
}
|
|
8957
|
+
const messagesToSave = dedupeMessagesForSave(messages);
|
|
8916
8958
|
await this.#db.client.tx(async (t) => {
|
|
8917
|
-
for (
|
|
8918
|
-
|
|
8919
|
-
|
|
8920
|
-
|
|
8921
|
-
);
|
|
8922
|
-
|
|
8923
|
-
|
|
8924
|
-
|
|
8925
|
-
|
|
8959
|
+
for (let offset = 0; offset < messagesToSave.length; offset += MAX_MESSAGES_PER_INSERT) {
|
|
8960
|
+
const batch = messagesToSave.slice(offset, offset + MAX_MESSAGES_PER_INSERT);
|
|
8961
|
+
const values = [];
|
|
8962
|
+
const valuePlaceholders = batch.map((message, messageIndex) => {
|
|
8963
|
+
const createdAt = message.createdAt || /* @__PURE__ */ new Date();
|
|
8964
|
+
values.push(
|
|
8965
|
+
message.id,
|
|
8966
|
+
message.threadId,
|
|
8967
|
+
typeof message.content === "string" ? message.content : JSON.stringify(message.content),
|
|
8968
|
+
createdAt,
|
|
8969
|
+
createdAt,
|
|
8970
|
+
message.role,
|
|
8971
|
+
message.type || "v2",
|
|
8972
|
+
message.resourceId
|
|
8926
8973
|
);
|
|
8927
|
-
|
|
8974
|
+
const paramOffset = messageIndex * MESSAGE_INSERT_BIND_PARAMETERS;
|
|
8975
|
+
return `(${Array.from(
|
|
8976
|
+
{ length: MESSAGE_INSERT_BIND_PARAMETERS },
|
|
8977
|
+
(_, paramIndex) => `$${paramOffset + paramIndex + 1}`
|
|
8978
|
+
).join(", ")})`;
|
|
8979
|
+
}).join(", ");
|
|
8928
8980
|
await t.none(
|
|
8929
8981
|
`INSERT INTO ${tableName} (id, thread_id, content, "createdAt", "createdAtZ", role, type, "resourceId")
|
|
8930
|
-
VALUES
|
|
8982
|
+
VALUES ${valuePlaceholders}
|
|
8931
8983
|
ON CONFLICT (id) DO UPDATE SET
|
|
8932
8984
|
thread_id = EXCLUDED.thread_id,
|
|
8933
8985
|
content = EXCLUDED.content,
|
|
8934
8986
|
role = EXCLUDED.role,
|
|
8935
8987
|
type = EXCLUDED.type,
|
|
8936
8988
|
"resourceId" = EXCLUDED."resourceId"`,
|
|
8937
|
-
|
|
8938
|
-
message.id,
|
|
8939
|
-
message.threadId,
|
|
8940
|
-
typeof message.content === "string" ? message.content : JSON.stringify(message.content),
|
|
8941
|
-
message.createdAt || /* @__PURE__ */ new Date(),
|
|
8942
|
-
message.createdAt || /* @__PURE__ */ new Date(),
|
|
8943
|
-
message.role,
|
|
8944
|
-
message.type || "v2",
|
|
8945
|
-
message.resourceId
|
|
8946
|
-
]
|
|
8989
|
+
values
|
|
8947
8990
|
);
|
|
8948
8991
|
}
|
|
8949
8992
|
const threadTableName = getTableName4({ indexName: storage.TABLE_THREADS, schemaName: getSchemaName4(this.#schema) });
|
|
8950
8993
|
const now = /* @__PURE__ */ new Date();
|
|
8951
|
-
|
|
8952
|
-
|
|
8953
|
-
|
|
8954
|
-
|
|
8955
|
-
|
|
8956
|
-
|
|
8957
|
-
|
|
8958
|
-
|
|
8994
|
+
for (const threadIdToUpdate of threadIds) {
|
|
8995
|
+
await t.none(
|
|
8996
|
+
`UPDATE ${threadTableName}
|
|
8997
|
+
SET
|
|
8998
|
+
"updatedAt" = $1,
|
|
8999
|
+
"updatedAtZ" = $2
|
|
9000
|
+
WHERE id = $3`,
|
|
9001
|
+
[now, now, threadIdToUpdate]
|
|
9002
|
+
);
|
|
9003
|
+
}
|
|
8959
9004
|
});
|
|
8960
9005
|
const messagesWithParsedContent = messages.map((message) => {
|
|
8961
9006
|
if (typeof message.content === "string") {
|
|
@@ -8970,6 +9015,9 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
|
8970
9015
|
const list = new agent.MessageList().add(messagesWithParsedContent, "memory");
|
|
8971
9016
|
return { messages: list.get.all.db() };
|
|
8972
9017
|
} catch (error$1) {
|
|
9018
|
+
if (error$1 instanceof error.MastraError) {
|
|
9019
|
+
throw error$1;
|
|
9020
|
+
}
|
|
8973
9021
|
throw new error.MastraError(
|
|
8974
9022
|
{
|
|
8975
9023
|
id: storage.createStorageErrorId("PG", "SAVE_MESSAGES", "FAILED"),
|
|
@@ -14930,6 +14978,15 @@ var WorkspacesPG = class _WorkspacesPG extends storage.WorkspacesStorage {
|
|
|
14930
14978
|
};
|
|
14931
14979
|
}
|
|
14932
14980
|
};
|
|
14981
|
+
function buildConnectionStringPoolConfig(config, defaults) {
|
|
14982
|
+
const parsed = pgConnectionString.parse(config.connectionString);
|
|
14983
|
+
return {
|
|
14984
|
+
...parsed,
|
|
14985
|
+
...config.ssl !== void 0 ? { ssl: config.ssl } : {},
|
|
14986
|
+
max: config.max ?? defaults.max,
|
|
14987
|
+
idleTimeoutMillis: config.idleTimeoutMillis ?? defaults.idleTimeoutMillis
|
|
14988
|
+
};
|
|
14989
|
+
}
|
|
14933
14990
|
|
|
14934
14991
|
// src/storage/index.ts
|
|
14935
14992
|
var DEFAULT_MAX_CONNECTIONS = 20;
|
|
@@ -15020,12 +15077,12 @@ var PostgresStore = class extends storage.MastraCompositeStore {
|
|
|
15020
15077
|
}
|
|
15021
15078
|
createPool(config) {
|
|
15022
15079
|
if (isConnectionStringConfig(config)) {
|
|
15023
|
-
return new pg.Pool(
|
|
15024
|
-
|
|
15025
|
-
|
|
15026
|
-
|
|
15027
|
-
|
|
15028
|
-
|
|
15080
|
+
return new pg.Pool(
|
|
15081
|
+
buildConnectionStringPoolConfig(config, {
|
|
15082
|
+
max: DEFAULT_MAX_CONNECTIONS,
|
|
15083
|
+
idleTimeoutMillis: DEFAULT_IDLE_TIMEOUT_MS
|
|
15084
|
+
})
|
|
15085
|
+
);
|
|
15029
15086
|
}
|
|
15030
15087
|
if (isHostConfig(config)) {
|
|
15031
15088
|
return new pg.Pool({
|