@mastra/pg 1.0.0-beta.10 → 1.0.0-beta.12
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 +143 -0
- package/dist/docs/README.md +36 -0
- package/dist/docs/SKILL.md +37 -0
- package/dist/docs/SOURCE_MAP.json +6 -0
- package/dist/docs/memory/01-storage.md +181 -0
- package/dist/docs/memory/02-working-memory.md +386 -0
- package/dist/docs/memory/03-semantic-recall.md +235 -0
- package/dist/docs/memory/04-reference.md +135 -0
- package/dist/docs/processors/01-reference.md +295 -0
- package/dist/docs/rag/01-overview.md +74 -0
- package/dist/docs/rag/02-vector-databases.md +638 -0
- package/dist/docs/rag/03-retrieval.md +549 -0
- package/dist/docs/rag/04-reference.md +351 -0
- package/dist/docs/storage/01-reference.md +667 -0
- package/dist/docs/tools/01-reference.md +440 -0
- package/dist/docs/vectors/01-reference.md +307 -0
- package/dist/index.cjs +499 -156
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +500 -157
- package/dist/index.js.map +1 -1
- package/dist/shared/config.d.ts +61 -66
- package/dist/shared/config.d.ts.map +1 -1
- package/dist/storage/client.d.ts +91 -0
- package/dist/storage/client.d.ts.map +1 -0
- package/dist/storage/db/index.d.ts +36 -17
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +2 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +35 -14
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/test-utils.d.ts.map +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
2
|
-
import { createVectorErrorId, AgentsStorage, TABLE_AGENTS,
|
|
2
|
+
import { createVectorErrorId, TABLE_SCHEMAS, AgentsStorage, TABLE_AGENTS, createStorageErrorId, normalizePerPage, calculatePagination, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, ObservabilityStorage, TABLE_SPANS, listTracesArgsSchema, ScoresStorage, TABLE_SCORERS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, MastraStorage, TraceStatus, getDefaultValue, transformScoreRow as transformScoreRow$1, getSqlType } from '@mastra/core/storage';
|
|
3
3
|
import { parseSqlIdentifier, parseFieldKey } from '@mastra/core/utils';
|
|
4
4
|
import { MastraVector } from '@mastra/core/vector';
|
|
5
5
|
import { Mutex } from 'async-mutex';
|
|
6
6
|
import * as pg from 'pg';
|
|
7
|
+
import { Pool } from 'pg';
|
|
7
8
|
import xxhash from 'xxhash-wasm';
|
|
8
9
|
import { BaseFilterTranslator } from '@mastra/core/vector/filter';
|
|
9
|
-
import pgPromise from 'pg-promise';
|
|
10
10
|
import { MastraBase } from '@mastra/core/base';
|
|
11
11
|
import { MessageList } from '@mastra/core/agent';
|
|
12
12
|
import { saveScorePayloadSchema } from '@mastra/core/evals';
|
|
@@ -14,8 +14,11 @@ import { saveScorePayloadSchema } from '@mastra/core/evals';
|
|
|
14
14
|
// src/vector/index.ts
|
|
15
15
|
|
|
16
16
|
// src/shared/config.ts
|
|
17
|
+
var isPoolConfig = (cfg) => {
|
|
18
|
+
return "pool" in cfg;
|
|
19
|
+
};
|
|
17
20
|
var isConnectionStringConfig = (cfg) => {
|
|
18
|
-
return "connectionString" in cfg;
|
|
21
|
+
return "connectionString" in cfg && typeof cfg.connectionString === "string";
|
|
19
22
|
};
|
|
20
23
|
var isHostConfig = (cfg) => {
|
|
21
24
|
return "host" in cfg && "database" in cfg && "user" in cfg && "password" in cfg;
|
|
@@ -23,16 +26,13 @@ var isHostConfig = (cfg) => {
|
|
|
23
26
|
var isCloudSqlConfig = (cfg) => {
|
|
24
27
|
return "stream" in cfg || "password" in cfg && typeof cfg.password === "function";
|
|
25
28
|
};
|
|
26
|
-
var isClientConfig = (cfg) => {
|
|
27
|
-
return "client" in cfg;
|
|
28
|
-
};
|
|
29
29
|
var validateConfig = (name, config) => {
|
|
30
30
|
if (!config.id || typeof config.id !== "string" || config.id.trim() === "") {
|
|
31
31
|
throw new Error(`${name}: id must be provided and cannot be empty.`);
|
|
32
32
|
}
|
|
33
|
-
if (
|
|
34
|
-
if (!config.
|
|
35
|
-
throw new Error(`${name}:
|
|
33
|
+
if (isPoolConfig(config)) {
|
|
34
|
+
if (!config.pool) {
|
|
35
|
+
throw new Error(`${name}: pool must be provided when using pool config.`);
|
|
36
36
|
}
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
@@ -53,7 +53,7 @@ var validateConfig = (name, config) => {
|
|
|
53
53
|
}
|
|
54
54
|
} else {
|
|
55
55
|
throw new Error(
|
|
56
|
-
`${name}: invalid config. Provide either {
|
|
56
|
+
`${name}: invalid config. Provide either {pool}, {connectionString}, {host,port,database,user,password}, or a pg ClientConfig (e.g., Cloud SQL connector with \`stream\`).`
|
|
57
57
|
);
|
|
58
58
|
}
|
|
59
59
|
};
|
|
@@ -518,8 +518,8 @@ var PgVector = class extends MastraVector {
|
|
|
518
518
|
} else if (isCloudSqlConfig(config)) {
|
|
519
519
|
poolConfig = {
|
|
520
520
|
...config,
|
|
521
|
-
max: config.max ?? 20,
|
|
522
|
-
idleTimeoutMillis: config.idleTimeoutMillis ?? 3e4,
|
|
521
|
+
max: config.pgPoolOptions?.max ?? 20,
|
|
522
|
+
idleTimeoutMillis: config.pgPoolOptions?.idleTimeoutMillis ?? 3e4,
|
|
523
523
|
connectionTimeoutMillis: 2e3,
|
|
524
524
|
...config.pgPoolOptions
|
|
525
525
|
};
|
|
@@ -1661,6 +1661,132 @@ var PgVector = class extends MastraVector {
|
|
|
1661
1661
|
}
|
|
1662
1662
|
}
|
|
1663
1663
|
};
|
|
1664
|
+
|
|
1665
|
+
// src/storage/client.ts
|
|
1666
|
+
function truncateQuery(query, maxLength = 100) {
|
|
1667
|
+
const normalized = query.replace(/\s+/g, " ").trim();
|
|
1668
|
+
if (normalized.length <= maxLength) {
|
|
1669
|
+
return normalized;
|
|
1670
|
+
}
|
|
1671
|
+
return normalized.slice(0, maxLength) + "...";
|
|
1672
|
+
}
|
|
1673
|
+
var PoolAdapter = class {
|
|
1674
|
+
constructor($pool) {
|
|
1675
|
+
this.$pool = $pool;
|
|
1676
|
+
}
|
|
1677
|
+
connect() {
|
|
1678
|
+
return this.$pool.connect();
|
|
1679
|
+
}
|
|
1680
|
+
async none(query, values) {
|
|
1681
|
+
await this.$pool.query(query, values);
|
|
1682
|
+
return null;
|
|
1683
|
+
}
|
|
1684
|
+
async one(query, values) {
|
|
1685
|
+
const result = await this.$pool.query(query, values);
|
|
1686
|
+
if (result.rows.length === 0) {
|
|
1687
|
+
throw new Error(`No data returned from query: ${truncateQuery(query)}`);
|
|
1688
|
+
}
|
|
1689
|
+
if (result.rows.length > 1) {
|
|
1690
|
+
throw new Error(`Multiple rows returned when one was expected: ${truncateQuery(query)}`);
|
|
1691
|
+
}
|
|
1692
|
+
return result.rows[0];
|
|
1693
|
+
}
|
|
1694
|
+
async oneOrNone(query, values) {
|
|
1695
|
+
const result = await this.$pool.query(query, values);
|
|
1696
|
+
if (result.rows.length === 0) {
|
|
1697
|
+
return null;
|
|
1698
|
+
}
|
|
1699
|
+
if (result.rows.length > 1) {
|
|
1700
|
+
throw new Error(`Multiple rows returned when one or none was expected: ${truncateQuery(query)}`);
|
|
1701
|
+
}
|
|
1702
|
+
return result.rows[0];
|
|
1703
|
+
}
|
|
1704
|
+
async any(query, values) {
|
|
1705
|
+
const result = await this.$pool.query(query, values);
|
|
1706
|
+
return result.rows;
|
|
1707
|
+
}
|
|
1708
|
+
async manyOrNone(query, values) {
|
|
1709
|
+
return this.any(query, values);
|
|
1710
|
+
}
|
|
1711
|
+
async many(query, values) {
|
|
1712
|
+
const result = await this.$pool.query(query, values);
|
|
1713
|
+
if (result.rows.length === 0) {
|
|
1714
|
+
throw new Error(`No data returned from query: ${truncateQuery(query)}`);
|
|
1715
|
+
}
|
|
1716
|
+
return result.rows;
|
|
1717
|
+
}
|
|
1718
|
+
async query(query, values) {
|
|
1719
|
+
return this.$pool.query(query, values);
|
|
1720
|
+
}
|
|
1721
|
+
async tx(callback) {
|
|
1722
|
+
const client = await this.$pool.connect();
|
|
1723
|
+
try {
|
|
1724
|
+
await client.query("BEGIN");
|
|
1725
|
+
const txClient = new TransactionClient(client);
|
|
1726
|
+
const result = await callback(txClient);
|
|
1727
|
+
await client.query("COMMIT");
|
|
1728
|
+
return result;
|
|
1729
|
+
} catch (error) {
|
|
1730
|
+
try {
|
|
1731
|
+
await client.query("ROLLBACK");
|
|
1732
|
+
} catch (rollbackError) {
|
|
1733
|
+
console.error("Transaction rollback failed:", rollbackError);
|
|
1734
|
+
}
|
|
1735
|
+
throw error;
|
|
1736
|
+
} finally {
|
|
1737
|
+
client.release();
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
};
|
|
1741
|
+
var TransactionClient = class {
|
|
1742
|
+
constructor(client) {
|
|
1743
|
+
this.client = client;
|
|
1744
|
+
}
|
|
1745
|
+
async none(query, values) {
|
|
1746
|
+
await this.client.query(query, values);
|
|
1747
|
+
return null;
|
|
1748
|
+
}
|
|
1749
|
+
async one(query, values) {
|
|
1750
|
+
const result = await this.client.query(query, values);
|
|
1751
|
+
if (result.rows.length === 0) {
|
|
1752
|
+
throw new Error(`No data returned from query: ${truncateQuery(query)}`);
|
|
1753
|
+
}
|
|
1754
|
+
if (result.rows.length > 1) {
|
|
1755
|
+
throw new Error(`Multiple rows returned when one was expected: ${truncateQuery(query)}`);
|
|
1756
|
+
}
|
|
1757
|
+
return result.rows[0];
|
|
1758
|
+
}
|
|
1759
|
+
async oneOrNone(query, values) {
|
|
1760
|
+
const result = await this.client.query(query, values);
|
|
1761
|
+
if (result.rows.length === 0) {
|
|
1762
|
+
return null;
|
|
1763
|
+
}
|
|
1764
|
+
if (result.rows.length > 1) {
|
|
1765
|
+
throw new Error(`Multiple rows returned when one or none was expected: ${truncateQuery(query)}`);
|
|
1766
|
+
}
|
|
1767
|
+
return result.rows[0];
|
|
1768
|
+
}
|
|
1769
|
+
async any(query, values) {
|
|
1770
|
+
const result = await this.client.query(query, values);
|
|
1771
|
+
return result.rows;
|
|
1772
|
+
}
|
|
1773
|
+
async manyOrNone(query, values) {
|
|
1774
|
+
return this.any(query, values);
|
|
1775
|
+
}
|
|
1776
|
+
async many(query, values) {
|
|
1777
|
+
const result = await this.client.query(query, values);
|
|
1778
|
+
if (result.rows.length === 0) {
|
|
1779
|
+
throw new Error(`No data returned from query: ${truncateQuery(query)}`);
|
|
1780
|
+
}
|
|
1781
|
+
return result.rows;
|
|
1782
|
+
}
|
|
1783
|
+
async query(query, values) {
|
|
1784
|
+
return this.client.query(query, values);
|
|
1785
|
+
}
|
|
1786
|
+
async batch(promises) {
|
|
1787
|
+
return Promise.all(promises);
|
|
1788
|
+
}
|
|
1789
|
+
};
|
|
1664
1790
|
function resolvePgConfig(config) {
|
|
1665
1791
|
if ("client" in config) {
|
|
1666
1792
|
return {
|
|
@@ -1670,10 +1796,32 @@ function resolvePgConfig(config) {
|
|
|
1670
1796
|
indexes: config.indexes
|
|
1671
1797
|
};
|
|
1672
1798
|
}
|
|
1673
|
-
|
|
1674
|
-
|
|
1799
|
+
if ("pool" in config) {
|
|
1800
|
+
return {
|
|
1801
|
+
client: new PoolAdapter(config.pool),
|
|
1802
|
+
schemaName: config.schemaName,
|
|
1803
|
+
skipDefaultIndexes: config.skipDefaultIndexes,
|
|
1804
|
+
indexes: config.indexes
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
let pool;
|
|
1808
|
+
if ("connectionString" in config) {
|
|
1809
|
+
pool = new Pool({
|
|
1810
|
+
connectionString: config.connectionString,
|
|
1811
|
+
ssl: config.ssl
|
|
1812
|
+
});
|
|
1813
|
+
} else {
|
|
1814
|
+
pool = new Pool({
|
|
1815
|
+
host: config.host,
|
|
1816
|
+
port: config.port,
|
|
1817
|
+
database: config.database,
|
|
1818
|
+
user: config.user,
|
|
1819
|
+
password: config.password,
|
|
1820
|
+
ssl: config.ssl
|
|
1821
|
+
});
|
|
1822
|
+
}
|
|
1675
1823
|
return {
|
|
1676
|
-
client,
|
|
1824
|
+
client: new PoolAdapter(pool),
|
|
1677
1825
|
schemaName: config.schemaName,
|
|
1678
1826
|
skipDefaultIndexes: config.skipDefaultIndexes,
|
|
1679
1827
|
indexes: config.indexes
|
|
@@ -1688,6 +1836,87 @@ function getTableName({ indexName, schemaName }) {
|
|
|
1688
1836
|
const quotedSchemaName = schemaName;
|
|
1689
1837
|
return quotedSchemaName ? `${quotedSchemaName}.${quotedIndexName}` : quotedIndexName;
|
|
1690
1838
|
}
|
|
1839
|
+
function mapToSqlType(type) {
|
|
1840
|
+
switch (type) {
|
|
1841
|
+
case "uuid":
|
|
1842
|
+
return "UUID";
|
|
1843
|
+
case "boolean":
|
|
1844
|
+
return "BOOLEAN";
|
|
1845
|
+
default:
|
|
1846
|
+
return getSqlType(type);
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
function generateTableSQL({
|
|
1850
|
+
tableName,
|
|
1851
|
+
schema,
|
|
1852
|
+
schemaName
|
|
1853
|
+
}) {
|
|
1854
|
+
const timeZColumns = Object.entries(schema).filter(([_, def]) => def.type === "timestamp").map(([name]) => {
|
|
1855
|
+
const parsedName = parseSqlIdentifier(name, "column name");
|
|
1856
|
+
return `"${parsedName}Z" TIMESTAMPTZ DEFAULT NOW()`;
|
|
1857
|
+
});
|
|
1858
|
+
const columns = Object.entries(schema).map(([name, def]) => {
|
|
1859
|
+
const parsedName = parseSqlIdentifier(name, "column name");
|
|
1860
|
+
const constraints = [];
|
|
1861
|
+
if (def.primaryKey) constraints.push("PRIMARY KEY");
|
|
1862
|
+
if (!def.nullable) constraints.push("NOT NULL");
|
|
1863
|
+
return `"${parsedName}" ${mapToSqlType(def.type)} ${constraints.join(" ")}`;
|
|
1864
|
+
});
|
|
1865
|
+
const finalColumns = [...columns, ...timeZColumns].join(",\n");
|
|
1866
|
+
const parsedSchemaName = schemaName ? parseSqlIdentifier(schemaName, "schema name") : "";
|
|
1867
|
+
const constraintPrefix = parsedSchemaName ? `${parsedSchemaName}_` : "";
|
|
1868
|
+
const quotedSchemaName = getSchemaName(schemaName);
|
|
1869
|
+
const sql = `
|
|
1870
|
+
CREATE TABLE IF NOT EXISTS ${getTableName({ indexName: tableName, schemaName: quotedSchemaName })} (
|
|
1871
|
+
${finalColumns}
|
|
1872
|
+
);
|
|
1873
|
+
${tableName === TABLE_WORKFLOW_SNAPSHOT ? `
|
|
1874
|
+
DO $$ BEGIN
|
|
1875
|
+
IF NOT EXISTS (
|
|
1876
|
+
SELECT 1 FROM pg_constraint WHERE conname = '${constraintPrefix}mastra_workflow_snapshot_workflow_name_run_id_key'
|
|
1877
|
+
) AND NOT EXISTS (
|
|
1878
|
+
SELECT 1 FROM pg_indexes WHERE indexname = '${constraintPrefix}mastra_workflow_snapshot_workflow_name_run_id_key'
|
|
1879
|
+
) THEN
|
|
1880
|
+
ALTER TABLE ${getTableName({ indexName: tableName, schemaName: quotedSchemaName })}
|
|
1881
|
+
ADD CONSTRAINT ${constraintPrefix}mastra_workflow_snapshot_workflow_name_run_id_key
|
|
1882
|
+
UNIQUE (workflow_name, run_id);
|
|
1883
|
+
END IF;
|
|
1884
|
+
END $$;
|
|
1885
|
+
` : ""}
|
|
1886
|
+
${tableName === TABLE_SPANS ? `
|
|
1887
|
+
DO $$ BEGIN
|
|
1888
|
+
IF NOT EXISTS (
|
|
1889
|
+
SELECT 1 FROM pg_constraint WHERE conname = '${constraintPrefix}mastra_ai_spans_traceid_spanid_pk'
|
|
1890
|
+
) THEN
|
|
1891
|
+
ALTER TABLE ${getTableName({ indexName: tableName, schemaName: quotedSchemaName })}
|
|
1892
|
+
ADD CONSTRAINT ${constraintPrefix}mastra_ai_spans_traceid_spanid_pk
|
|
1893
|
+
PRIMARY KEY ("traceId", "spanId");
|
|
1894
|
+
END IF;
|
|
1895
|
+
END $$;
|
|
1896
|
+
` : ""}
|
|
1897
|
+
`;
|
|
1898
|
+
return sql;
|
|
1899
|
+
}
|
|
1900
|
+
function exportSchemas(schemaName) {
|
|
1901
|
+
const statements = [];
|
|
1902
|
+
if (schemaName) {
|
|
1903
|
+
const quotedSchemaName = getSchemaName(schemaName);
|
|
1904
|
+
statements.push(`-- Create schema if it doesn't exist`);
|
|
1905
|
+
statements.push(`CREATE SCHEMA IF NOT EXISTS ${quotedSchemaName};`);
|
|
1906
|
+
statements.push("");
|
|
1907
|
+
}
|
|
1908
|
+
for (const [tableName, schema] of Object.entries(TABLE_SCHEMAS)) {
|
|
1909
|
+
statements.push(`-- Table: ${tableName}`);
|
|
1910
|
+
const sql = generateTableSQL({
|
|
1911
|
+
tableName,
|
|
1912
|
+
schema,
|
|
1913
|
+
schemaName
|
|
1914
|
+
});
|
|
1915
|
+
statements.push(sql.trim());
|
|
1916
|
+
statements.push("");
|
|
1917
|
+
}
|
|
1918
|
+
return statements.join("\n");
|
|
1919
|
+
}
|
|
1691
1920
|
var schemaSetupRegistry = /* @__PURE__ */ new Map();
|
|
1692
1921
|
var PgDB = class extends MastraBase {
|
|
1693
1922
|
client;
|
|
@@ -1805,16 +2034,6 @@ var PgDB = class extends MastraBase {
|
|
|
1805
2034
|
}
|
|
1806
2035
|
await registryEntry.promise;
|
|
1807
2036
|
}
|
|
1808
|
-
getSqlType(type) {
|
|
1809
|
-
switch (type) {
|
|
1810
|
-
case "uuid":
|
|
1811
|
-
return "UUID";
|
|
1812
|
-
case "boolean":
|
|
1813
|
-
return "BOOLEAN";
|
|
1814
|
-
default:
|
|
1815
|
-
return getSqlType(type);
|
|
1816
|
-
}
|
|
1817
|
-
}
|
|
1818
2037
|
getDefaultValue(type) {
|
|
1819
2038
|
switch (type) {
|
|
1820
2039
|
case "timestamp":
|
|
@@ -1884,52 +2103,10 @@ var PgDB = class extends MastraBase {
|
|
|
1884
2103
|
}) {
|
|
1885
2104
|
try {
|
|
1886
2105
|
const timeZColumnNames = Object.entries(schema).filter(([_, def]) => def.type === "timestamp").map(([name]) => name);
|
|
1887
|
-
const timeZColumns = Object.entries(schema).filter(([_, def]) => def.type === "timestamp").map(([name]) => {
|
|
1888
|
-
const parsedName = parseSqlIdentifier(name, "column name");
|
|
1889
|
-
return `"${parsedName}Z" TIMESTAMPTZ DEFAULT NOW()`;
|
|
1890
|
-
});
|
|
1891
|
-
const columns = Object.entries(schema).map(([name, def]) => {
|
|
1892
|
-
const parsedName = parseSqlIdentifier(name, "column name");
|
|
1893
|
-
const constraints = [];
|
|
1894
|
-
if (def.primaryKey) constraints.push("PRIMARY KEY");
|
|
1895
|
-
if (!def.nullable) constraints.push("NOT NULL");
|
|
1896
|
-
return `"${parsedName}" ${this.getSqlType(def.type)} ${constraints.join(" ")}`;
|
|
1897
|
-
});
|
|
1898
2106
|
if (this.schemaName) {
|
|
1899
2107
|
await this.setupSchema();
|
|
1900
2108
|
}
|
|
1901
|
-
const
|
|
1902
|
-
const constraintPrefix = this.schemaName ? `${this.schemaName}_` : "";
|
|
1903
|
-
const schemaName = getSchemaName(this.schemaName);
|
|
1904
|
-
const sql = `
|
|
1905
|
-
CREATE TABLE IF NOT EXISTS ${getTableName({ indexName: tableName, schemaName })} (
|
|
1906
|
-
${finalColumns}
|
|
1907
|
-
);
|
|
1908
|
-
${tableName === TABLE_WORKFLOW_SNAPSHOT ? `
|
|
1909
|
-
DO $$ BEGIN
|
|
1910
|
-
IF NOT EXISTS (
|
|
1911
|
-
SELECT 1 FROM pg_constraint WHERE conname = '${constraintPrefix}mastra_workflow_snapshot_workflow_name_run_id_key'
|
|
1912
|
-
) AND NOT EXISTS (
|
|
1913
|
-
SELECT 1 FROM pg_indexes WHERE indexname = '${constraintPrefix}mastra_workflow_snapshot_workflow_name_run_id_key'
|
|
1914
|
-
) THEN
|
|
1915
|
-
ALTER TABLE ${getTableName({ indexName: tableName, schemaName })}
|
|
1916
|
-
ADD CONSTRAINT ${constraintPrefix}mastra_workflow_snapshot_workflow_name_run_id_key
|
|
1917
|
-
UNIQUE (workflow_name, run_id);
|
|
1918
|
-
END IF;
|
|
1919
|
-
END $$;
|
|
1920
|
-
` : ""}
|
|
1921
|
-
${tableName === TABLE_SPANS ? `
|
|
1922
|
-
DO $$ BEGIN
|
|
1923
|
-
IF NOT EXISTS (
|
|
1924
|
-
SELECT 1 FROM pg_constraint WHERE conname = '${constraintPrefix}mastra_ai_spans_traceid_spanid_pk'
|
|
1925
|
-
) THEN
|
|
1926
|
-
ALTER TABLE ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })}
|
|
1927
|
-
ADD CONSTRAINT ${constraintPrefix}mastra_ai_spans_traceid_spanid_pk
|
|
1928
|
-
PRIMARY KEY ("traceId", "spanId");
|
|
1929
|
-
END IF;
|
|
1930
|
-
END $$;
|
|
1931
|
-
` : ""}
|
|
1932
|
-
`;
|
|
2109
|
+
const sql = generateTableSQL({ tableName, schema, schemaName: this.schemaName });
|
|
1933
2110
|
await this.client.none(sql);
|
|
1934
2111
|
await this.alterTable({
|
|
1935
2112
|
tableName,
|
|
@@ -2003,7 +2180,7 @@ var PgDB = class extends MastraBase {
|
|
|
2003
2180
|
const columnExists = await this.hasColumn(TABLE_SPANS, columnName);
|
|
2004
2181
|
if (!columnExists) {
|
|
2005
2182
|
const parsedColumnName = parseSqlIdentifier(columnName, "column name");
|
|
2006
|
-
const sqlType =
|
|
2183
|
+
const sqlType = mapToSqlType(columnDef.type);
|
|
2007
2184
|
const nullable = columnDef.nullable ? "" : "NOT NULL";
|
|
2008
2185
|
const defaultValue = !columnDef.nullable ? this.getDefaultValue(columnDef.type) : "";
|
|
2009
2186
|
const alterSql = `ALTER TABLE ${fullTableName} ADD COLUMN IF NOT EXISTS "${parsedColumnName}" ${sqlType} ${nullable} ${defaultValue}`.trim();
|
|
@@ -2050,7 +2227,7 @@ var PgDB = class extends MastraBase {
|
|
|
2050
2227
|
if (schema[columnName]) {
|
|
2051
2228
|
const columnDef = schema[columnName];
|
|
2052
2229
|
const parsedColumnName = parseSqlIdentifier(columnName, "column name");
|
|
2053
|
-
const sqlType =
|
|
2230
|
+
const sqlType = mapToSqlType(columnDef.type);
|
|
2054
2231
|
const nullable = columnDef.nullable ? "" : "NOT NULL";
|
|
2055
2232
|
const defaultValue = !columnDef.nullable ? this.getDefaultValue(columnDef.type) : "";
|
|
2056
2233
|
const alterSql = `ALTER TABLE ${fullTableName} ADD COLUMN IF NOT EXISTS "${parsedColumnName}" ${sqlType} ${nullable} ${defaultValue}`.trim();
|
|
@@ -2370,9 +2547,9 @@ var PgDB = class extends MastraBase {
|
|
|
2370
2547
|
size: result.size || "0",
|
|
2371
2548
|
definition: result.definition || "",
|
|
2372
2549
|
method: result.method || "btree",
|
|
2373
|
-
scans: parseInt(result.scans) || 0,
|
|
2374
|
-
tuples_read: parseInt(result.tuples_read) || 0,
|
|
2375
|
-
tuples_fetched: parseInt(result.tuples_fetched) || 0
|
|
2550
|
+
scans: parseInt(String(result.scans)) || 0,
|
|
2551
|
+
tuples_read: parseInt(String(result.tuples_read)) || 0,
|
|
2552
|
+
tuples_fetched: parseInt(String(result.tuples_fetched)) || 0
|
|
2376
2553
|
};
|
|
2377
2554
|
} catch (error) {
|
|
2378
2555
|
throw new MastraError(
|
|
@@ -2889,6 +3066,9 @@ function getTableName3({ indexName, schemaName }) {
|
|
|
2889
3066
|
const quotedIndexName = `"${indexName}"`;
|
|
2890
3067
|
return schemaName ? `${schemaName}.${quotedIndexName}` : quotedIndexName;
|
|
2891
3068
|
}
|
|
3069
|
+
function inPlaceholders(count, startIndex = 1) {
|
|
3070
|
+
return Array.from({ length: count }, (_, i) => `$${i + startIndex}`).join(", ");
|
|
3071
|
+
}
|
|
2892
3072
|
var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
2893
3073
|
#db;
|
|
2894
3074
|
#schema;
|
|
@@ -3049,13 +3229,19 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
3049
3229
|
};
|
|
3050
3230
|
}
|
|
3051
3231
|
const limitValue = perPageInput === false ? total : perPage;
|
|
3052
|
-
const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "updatedAt" ${baseQuery} ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`;
|
|
3053
|
-
const rows = await this.#db.client.manyOrNone(
|
|
3232
|
+
const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "createdAtZ", "updatedAt", "updatedAtZ" ${baseQuery} ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`;
|
|
3233
|
+
const rows = await this.#db.client.manyOrNone(
|
|
3234
|
+
dataQuery,
|
|
3235
|
+
[...queryParams, limitValue, offset]
|
|
3236
|
+
);
|
|
3054
3237
|
const threads = (rows || []).map((thread) => ({
|
|
3055
|
-
|
|
3238
|
+
id: thread.id,
|
|
3239
|
+
resourceId: thread.resourceId,
|
|
3240
|
+
title: thread.title,
|
|
3056
3241
|
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
3057
|
-
|
|
3058
|
-
|
|
3242
|
+
// Use timezone-aware columns (*Z) for correct UTC timestamps, with fallback for legacy data
|
|
3243
|
+
createdAt: thread.createdAtZ || thread.createdAt,
|
|
3244
|
+
updatedAt: thread.updatedAtZ || thread.updatedAt
|
|
3059
3245
|
}));
|
|
3060
3246
|
return {
|
|
3061
3247
|
threads,
|
|
@@ -3160,17 +3346,18 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
3160
3346
|
...metadata
|
|
3161
3347
|
};
|
|
3162
3348
|
try {
|
|
3349
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3163
3350
|
const thread = await this.#db.client.one(
|
|
3164
3351
|
`UPDATE ${threadTableName}
|
|
3165
3352
|
SET
|
|
3166
3353
|
title = $1,
|
|
3167
3354
|
metadata = $2,
|
|
3168
3355
|
"updatedAt" = $3,
|
|
3169
|
-
"updatedAtZ" = $
|
|
3170
|
-
WHERE id = $
|
|
3356
|
+
"updatedAtZ" = $4
|
|
3357
|
+
WHERE id = $5
|
|
3171
3358
|
RETURNING *
|
|
3172
3359
|
`,
|
|
3173
|
-
[title, mergedMetadata,
|
|
3360
|
+
[title, mergedMetadata, now, now, id]
|
|
3174
3361
|
);
|
|
3175
3362
|
return {
|
|
3176
3363
|
id: thread.id,
|
|
@@ -3313,7 +3500,7 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
3313
3500
|
const tableName = getTableName3({ indexName: TABLE_MESSAGES, schemaName: getSchemaName3(this.#schema) });
|
|
3314
3501
|
const query = `
|
|
3315
3502
|
${selectStatement} FROM ${tableName}
|
|
3316
|
-
WHERE id IN (${messageIds.
|
|
3503
|
+
WHERE id IN (${inPlaceholders(messageIds.length)})
|
|
3317
3504
|
ORDER BY "createdAt" DESC
|
|
3318
3505
|
`;
|
|
3319
3506
|
const resultRows = await this.#db.client.manyOrNone(query, messageIds);
|
|
@@ -3374,8 +3561,7 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
3374
3561
|
const orderByStatement = `ORDER BY "${field}" ${direction}`;
|
|
3375
3562
|
const selectStatement = `SELECT id, content, role, type, "createdAt", "createdAtZ", thread_id AS "threadId", "resourceId"`;
|
|
3376
3563
|
const tableName = getTableName3({ indexName: TABLE_MESSAGES, schemaName: getSchemaName3(this.#schema) });
|
|
3377
|
-
const
|
|
3378
|
-
const conditions = [`thread_id IN (${threadPlaceholders})`];
|
|
3564
|
+
const conditions = [`thread_id IN (${inPlaceholders(threadIds.length)})`];
|
|
3379
3565
|
const queryParams = [...threadIds];
|
|
3380
3566
|
let paramIndex = threadIds.length + 1;
|
|
3381
3567
|
if (resourceId) {
|
|
@@ -3383,11 +3569,13 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
3383
3569
|
queryParams.push(resourceId);
|
|
3384
3570
|
}
|
|
3385
3571
|
if (filter?.dateRange?.start) {
|
|
3386
|
-
|
|
3572
|
+
const startOp = filter.dateRange.startExclusive ? ">" : ">=";
|
|
3573
|
+
conditions.push(`"createdAt" ${startOp} $${paramIndex++}`);
|
|
3387
3574
|
queryParams.push(filter.dateRange.start);
|
|
3388
3575
|
}
|
|
3389
3576
|
if (filter?.dateRange?.end) {
|
|
3390
|
-
|
|
3577
|
+
const endOp = filter.dateRange.endExclusive ? "<" : "<=";
|
|
3578
|
+
conditions.push(`"createdAt" ${endOp} $${paramIndex++}`);
|
|
3391
3579
|
queryParams.push(filter.dateRange.end);
|
|
3392
3580
|
}
|
|
3393
3581
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
@@ -3532,14 +3720,15 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
3532
3720
|
);
|
|
3533
3721
|
});
|
|
3534
3722
|
const threadTableName = getTableName3({ indexName: TABLE_THREADS, schemaName: getSchemaName3(this.#schema) });
|
|
3723
|
+
const nowStr = (/* @__PURE__ */ new Date()).toISOString();
|
|
3535
3724
|
const threadUpdate = t.none(
|
|
3536
3725
|
`UPDATE ${threadTableName}
|
|
3537
3726
|
SET
|
|
3538
3727
|
"updatedAt" = $1,
|
|
3539
|
-
"updatedAtZ" = $
|
|
3540
|
-
WHERE id = $
|
|
3728
|
+
"updatedAtZ" = $2
|
|
3729
|
+
WHERE id = $3
|
|
3541
3730
|
`,
|
|
3542
|
-
[
|
|
3731
|
+
[nowStr, nowStr, threadId]
|
|
3543
3732
|
);
|
|
3544
3733
|
await Promise.all([...messageInserts, threadUpdate]);
|
|
3545
3734
|
});
|
|
@@ -3576,8 +3765,8 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
3576
3765
|
return [];
|
|
3577
3766
|
}
|
|
3578
3767
|
const messageIds = messages.map((m) => m.id);
|
|
3579
|
-
const selectQuery = `SELECT id, content, role, type, "createdAt", "createdAtZ", thread_id AS "threadId", "resourceId" FROM ${getTableName3({ indexName: TABLE_MESSAGES, schemaName: getSchemaName3(this.#schema) })} WHERE id IN ($
|
|
3580
|
-
const existingMessagesDb = await this.#db.client.manyOrNone(selectQuery,
|
|
3768
|
+
const selectQuery = `SELECT id, content, role, type, "createdAt", "createdAtZ", thread_id AS "threadId", "resourceId" FROM ${getTableName3({ indexName: TABLE_MESSAGES, schemaName: getSchemaName3(this.#schema) })} WHERE id IN (${inPlaceholders(messageIds.length)})`;
|
|
3769
|
+
const existingMessagesDb = await this.#db.client.manyOrNone(selectQuery, messageIds);
|
|
3581
3770
|
if (existingMessagesDb.length === 0) {
|
|
3582
3771
|
return [];
|
|
3583
3772
|
}
|
|
@@ -3638,10 +3827,11 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
3638
3827
|
}
|
|
3639
3828
|
}
|
|
3640
3829
|
if (threadIdsToUpdate.size > 0) {
|
|
3830
|
+
const threadIds = Array.from(threadIdsToUpdate);
|
|
3641
3831
|
queries.push(
|
|
3642
3832
|
t.none(
|
|
3643
|
-
`UPDATE ${getTableName3({ indexName: TABLE_THREADS, schemaName: getSchemaName3(this.#schema) })} SET "updatedAt" = NOW(), "updatedAtZ" = NOW() WHERE id IN ($
|
|
3644
|
-
|
|
3833
|
+
`UPDATE ${getTableName3({ indexName: TABLE_THREADS, schemaName: getSchemaName3(this.#schema) })} SET "updatedAt" = NOW(), "updatedAtZ" = NOW() WHERE id IN (${inPlaceholders(threadIds.length)})`,
|
|
3834
|
+
threadIds
|
|
3645
3835
|
)
|
|
3646
3836
|
);
|
|
3647
3837
|
}
|
|
@@ -3649,7 +3839,7 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
3649
3839
|
await t.batch(queries);
|
|
3650
3840
|
}
|
|
3651
3841
|
});
|
|
3652
|
-
const updatedMessages = await this.#db.client.manyOrNone(selectQuery,
|
|
3842
|
+
const updatedMessages = await this.#db.client.manyOrNone(selectQuery, messageIds);
|
|
3653
3843
|
return (updatedMessages || []).map((row) => {
|
|
3654
3844
|
const message = this.normalizeMessageRow(row);
|
|
3655
3845
|
if (typeof message.content === "string") {
|
|
@@ -3761,15 +3951,159 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
3761
3951
|
values.push(JSON.stringify(updatedResource.metadata));
|
|
3762
3952
|
paramIndex++;
|
|
3763
3953
|
}
|
|
3764
|
-
|
|
3765
|
-
|
|
3954
|
+
const updatedAtStr = updatedResource.updatedAt.toISOString();
|
|
3955
|
+
updates.push(`"updatedAt" = $${paramIndex++}`);
|
|
3956
|
+
values.push(updatedAtStr);
|
|
3766
3957
|
updates.push(`"updatedAtZ" = $${paramIndex++}`);
|
|
3767
|
-
values.push(
|
|
3768
|
-
paramIndex++;
|
|
3958
|
+
values.push(updatedAtStr);
|
|
3769
3959
|
values.push(resourceId);
|
|
3770
3960
|
await this.#db.client.none(`UPDATE ${tableName} SET ${updates.join(", ")} WHERE id = $${paramIndex}`, values);
|
|
3771
3961
|
return updatedResource;
|
|
3772
3962
|
}
|
|
3963
|
+
async cloneThread(args) {
|
|
3964
|
+
const { sourceThreadId, newThreadId: providedThreadId, resourceId, title, metadata, options } = args;
|
|
3965
|
+
const sourceThread = await this.getThreadById({ threadId: sourceThreadId });
|
|
3966
|
+
if (!sourceThread) {
|
|
3967
|
+
throw new MastraError({
|
|
3968
|
+
id: createStorageErrorId("PG", "CLONE_THREAD", "SOURCE_NOT_FOUND"),
|
|
3969
|
+
domain: ErrorDomain.STORAGE,
|
|
3970
|
+
category: ErrorCategory.USER,
|
|
3971
|
+
text: `Source thread with id ${sourceThreadId} not found`,
|
|
3972
|
+
details: { sourceThreadId }
|
|
3973
|
+
});
|
|
3974
|
+
}
|
|
3975
|
+
const newThreadId = providedThreadId || crypto.randomUUID();
|
|
3976
|
+
const existingThread = await this.getThreadById({ threadId: newThreadId });
|
|
3977
|
+
if (existingThread) {
|
|
3978
|
+
throw new MastraError({
|
|
3979
|
+
id: createStorageErrorId("PG", "CLONE_THREAD", "THREAD_EXISTS"),
|
|
3980
|
+
domain: ErrorDomain.STORAGE,
|
|
3981
|
+
category: ErrorCategory.USER,
|
|
3982
|
+
text: `Thread with id ${newThreadId} already exists`,
|
|
3983
|
+
details: { newThreadId }
|
|
3984
|
+
});
|
|
3985
|
+
}
|
|
3986
|
+
const threadTableName = getTableName3({ indexName: TABLE_THREADS, schemaName: getSchemaName3(this.#schema) });
|
|
3987
|
+
const messageTableName = getTableName3({ indexName: TABLE_MESSAGES, schemaName: getSchemaName3(this.#schema) });
|
|
3988
|
+
try {
|
|
3989
|
+
return await this.#db.client.tx(async (t) => {
|
|
3990
|
+
let messageQuery = `SELECT id, content, role, type, "createdAt", "createdAtZ", thread_id AS "threadId", "resourceId"
|
|
3991
|
+
FROM ${messageTableName} WHERE thread_id = $1`;
|
|
3992
|
+
const messageParams = [sourceThreadId];
|
|
3993
|
+
let paramIndex = 2;
|
|
3994
|
+
if (options?.messageFilter?.startDate) {
|
|
3995
|
+
messageQuery += ` AND "createdAt" >= $${paramIndex++}`;
|
|
3996
|
+
messageParams.push(options.messageFilter.startDate);
|
|
3997
|
+
}
|
|
3998
|
+
if (options?.messageFilter?.endDate) {
|
|
3999
|
+
messageQuery += ` AND "createdAt" <= $${paramIndex++}`;
|
|
4000
|
+
messageParams.push(options.messageFilter.endDate);
|
|
4001
|
+
}
|
|
4002
|
+
if (options?.messageFilter?.messageIds && options.messageFilter.messageIds.length > 0) {
|
|
4003
|
+
messageQuery += ` AND id IN (${options.messageFilter.messageIds.map(() => `$${paramIndex++}`).join(", ")})`;
|
|
4004
|
+
messageParams.push(...options.messageFilter.messageIds);
|
|
4005
|
+
}
|
|
4006
|
+
messageQuery += ` ORDER BY "createdAt" ASC`;
|
|
4007
|
+
if (options?.messageLimit && options.messageLimit > 0) {
|
|
4008
|
+
const limitQuery = `SELECT * FROM (${messageQuery.replace('ORDER BY "createdAt" ASC', 'ORDER BY "createdAt" DESC')} LIMIT $${paramIndex}) AS limited ORDER BY "createdAt" ASC`;
|
|
4009
|
+
messageParams.push(options.messageLimit);
|
|
4010
|
+
messageQuery = limitQuery;
|
|
4011
|
+
}
|
|
4012
|
+
const sourceMessages = await t.manyOrNone(messageQuery, messageParams);
|
|
4013
|
+
const now = /* @__PURE__ */ new Date();
|
|
4014
|
+
const lastMessageId = sourceMessages.length > 0 ? sourceMessages[sourceMessages.length - 1].id : void 0;
|
|
4015
|
+
const cloneMetadata = {
|
|
4016
|
+
sourceThreadId,
|
|
4017
|
+
clonedAt: now,
|
|
4018
|
+
...lastMessageId && { lastMessageId }
|
|
4019
|
+
};
|
|
4020
|
+
const newThread = {
|
|
4021
|
+
id: newThreadId,
|
|
4022
|
+
resourceId: resourceId || sourceThread.resourceId,
|
|
4023
|
+
title: title || (sourceThread.title ? `Clone of ${sourceThread.title}` : void 0),
|
|
4024
|
+
metadata: {
|
|
4025
|
+
...metadata,
|
|
4026
|
+
clone: cloneMetadata
|
|
4027
|
+
},
|
|
4028
|
+
createdAt: now,
|
|
4029
|
+
updatedAt: now
|
|
4030
|
+
};
|
|
4031
|
+
await t.none(
|
|
4032
|
+
`INSERT INTO ${threadTableName} (
|
|
4033
|
+
id,
|
|
4034
|
+
"resourceId",
|
|
4035
|
+
title,
|
|
4036
|
+
metadata,
|
|
4037
|
+
"createdAt",
|
|
4038
|
+
"createdAtZ",
|
|
4039
|
+
"updatedAt",
|
|
4040
|
+
"updatedAtZ"
|
|
4041
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
|
|
4042
|
+
[
|
|
4043
|
+
newThread.id,
|
|
4044
|
+
newThread.resourceId,
|
|
4045
|
+
newThread.title,
|
|
4046
|
+
newThread.metadata ? JSON.stringify(newThread.metadata) : null,
|
|
4047
|
+
now,
|
|
4048
|
+
now,
|
|
4049
|
+
now,
|
|
4050
|
+
now
|
|
4051
|
+
]
|
|
4052
|
+
);
|
|
4053
|
+
const clonedMessages = [];
|
|
4054
|
+
const targetResourceId = resourceId || sourceThread.resourceId;
|
|
4055
|
+
for (const sourceMsg of sourceMessages) {
|
|
4056
|
+
const newMessageId = crypto.randomUUID();
|
|
4057
|
+
const normalizedMsg = this.normalizeMessageRow(sourceMsg);
|
|
4058
|
+
let parsedContent = normalizedMsg.content;
|
|
4059
|
+
try {
|
|
4060
|
+
parsedContent = JSON.parse(normalizedMsg.content);
|
|
4061
|
+
} catch {
|
|
4062
|
+
}
|
|
4063
|
+
await t.none(
|
|
4064
|
+
`INSERT INTO ${messageTableName} (id, thread_id, content, "createdAt", "createdAtZ", role, type, "resourceId")
|
|
4065
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
|
|
4066
|
+
[
|
|
4067
|
+
newMessageId,
|
|
4068
|
+
newThreadId,
|
|
4069
|
+
typeof normalizedMsg.content === "string" ? normalizedMsg.content : JSON.stringify(normalizedMsg.content),
|
|
4070
|
+
normalizedMsg.createdAt,
|
|
4071
|
+
normalizedMsg.createdAt,
|
|
4072
|
+
normalizedMsg.role,
|
|
4073
|
+
normalizedMsg.type || "v2",
|
|
4074
|
+
targetResourceId
|
|
4075
|
+
]
|
|
4076
|
+
);
|
|
4077
|
+
clonedMessages.push({
|
|
4078
|
+
id: newMessageId,
|
|
4079
|
+
threadId: newThreadId,
|
|
4080
|
+
content: parsedContent,
|
|
4081
|
+
role: normalizedMsg.role,
|
|
4082
|
+
type: normalizedMsg.type,
|
|
4083
|
+
createdAt: new Date(normalizedMsg.createdAt),
|
|
4084
|
+
resourceId: targetResourceId
|
|
4085
|
+
});
|
|
4086
|
+
}
|
|
4087
|
+
return {
|
|
4088
|
+
thread: newThread,
|
|
4089
|
+
clonedMessages
|
|
4090
|
+
};
|
|
4091
|
+
});
|
|
4092
|
+
} catch (error) {
|
|
4093
|
+
if (error instanceof MastraError) {
|
|
4094
|
+
throw error;
|
|
4095
|
+
}
|
|
4096
|
+
throw new MastraError(
|
|
4097
|
+
{
|
|
4098
|
+
id: createStorageErrorId("PG", "CLONE_THREAD", "FAILED"),
|
|
4099
|
+
domain: ErrorDomain.STORAGE,
|
|
4100
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
4101
|
+
details: { sourceThreadId, newThreadId }
|
|
4102
|
+
},
|
|
4103
|
+
error
|
|
4104
|
+
);
|
|
4105
|
+
}
|
|
4106
|
+
}
|
|
3773
4107
|
};
|
|
3774
4108
|
var ObservabilityPG = class _ObservabilityPG extends ObservabilityStorage {
|
|
3775
4109
|
#db;
|
|
@@ -5044,9 +5378,12 @@ var WorkflowsPG = class _WorkflowsPG extends WorkflowsStorage {
|
|
|
5044
5378
|
};
|
|
5045
5379
|
|
|
5046
5380
|
// src/storage/index.ts
|
|
5381
|
+
var DEFAULT_MAX_CONNECTIONS = 20;
|
|
5382
|
+
var DEFAULT_IDLE_TIMEOUT_MS = 3e4;
|
|
5047
5383
|
var PostgresStore = class extends MastraStorage {
|
|
5384
|
+
#pool;
|
|
5048
5385
|
#db;
|
|
5049
|
-
#
|
|
5386
|
+
#ownsPool;
|
|
5050
5387
|
schema;
|
|
5051
5388
|
isInitialized = false;
|
|
5052
5389
|
stores;
|
|
@@ -5055,59 +5392,26 @@ var PostgresStore = class extends MastraStorage {
|
|
|
5055
5392
|
validateConfig("PostgresStore", config);
|
|
5056
5393
|
super({ id: config.id, name: "PostgresStore", disableInit: config.disableInit });
|
|
5057
5394
|
this.schema = config.schemaName || "public";
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
this.#
|
|
5395
|
+
if (isPoolConfig(config)) {
|
|
5396
|
+
this.#pool = config.pool;
|
|
5397
|
+
this.#ownsPool = false;
|
|
5061
5398
|
} else {
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
pgConfig = {
|
|
5073
|
-
...config,
|
|
5074
|
-
id: config.id,
|
|
5075
|
-
max: config.max,
|
|
5076
|
-
idleTimeoutMillis: config.idleTimeoutMillis
|
|
5077
|
-
};
|
|
5078
|
-
} else if (isHostConfig(config)) {
|
|
5079
|
-
pgConfig = {
|
|
5080
|
-
id: config.id,
|
|
5081
|
-
host: config.host,
|
|
5082
|
-
port: config.port,
|
|
5083
|
-
database: config.database,
|
|
5084
|
-
user: config.user,
|
|
5085
|
-
password: config.password,
|
|
5086
|
-
ssl: config.ssl,
|
|
5087
|
-
max: config.max,
|
|
5088
|
-
idleTimeoutMillis: config.idleTimeoutMillis
|
|
5089
|
-
};
|
|
5090
|
-
} else {
|
|
5091
|
-
throw new Error(
|
|
5092
|
-
"PostgresStore: invalid config. Provide either {client}, {connectionString}, {host,port,database,user,password}, or a pg ClientConfig (e.g., Cloud SQL connector with `stream`)."
|
|
5093
|
-
);
|
|
5094
|
-
}
|
|
5095
|
-
this.#db = this.#pgp(pgConfig);
|
|
5096
|
-
}
|
|
5097
|
-
const skipDefaultIndexes = config.skipDefaultIndexes;
|
|
5098
|
-
const indexes = config.indexes;
|
|
5099
|
-
const domainConfig = { client: this.#db, schemaName: this.schema, skipDefaultIndexes, indexes };
|
|
5100
|
-
const scores = new ScoresPG(domainConfig);
|
|
5101
|
-
const workflows = new WorkflowsPG(domainConfig);
|
|
5102
|
-
const memory = new MemoryPG(domainConfig);
|
|
5103
|
-
const observability = new ObservabilityPG(domainConfig);
|
|
5104
|
-
const agents = new AgentsPG(domainConfig);
|
|
5399
|
+
this.#pool = this.createPool(config);
|
|
5400
|
+
this.#ownsPool = true;
|
|
5401
|
+
}
|
|
5402
|
+
this.#db = new PoolAdapter(this.#pool);
|
|
5403
|
+
const domainConfig = {
|
|
5404
|
+
client: this.#db,
|
|
5405
|
+
schemaName: this.schema,
|
|
5406
|
+
skipDefaultIndexes: config.skipDefaultIndexes,
|
|
5407
|
+
indexes: config.indexes
|
|
5408
|
+
};
|
|
5105
5409
|
this.stores = {
|
|
5106
|
-
scores,
|
|
5107
|
-
workflows,
|
|
5108
|
-
memory,
|
|
5109
|
-
observability,
|
|
5110
|
-
agents
|
|
5410
|
+
scores: new ScoresPG(domainConfig),
|
|
5411
|
+
workflows: new WorkflowsPG(domainConfig),
|
|
5412
|
+
memory: new MemoryPG(domainConfig),
|
|
5413
|
+
observability: new ObservabilityPG(domainConfig),
|
|
5414
|
+
agents: new AgentsPG(domainConfig)
|
|
5111
5415
|
};
|
|
5112
5416
|
} catch (e) {
|
|
5113
5417
|
throw new MastraError(
|
|
@@ -5120,6 +5424,32 @@ var PostgresStore = class extends MastraStorage {
|
|
|
5120
5424
|
);
|
|
5121
5425
|
}
|
|
5122
5426
|
}
|
|
5427
|
+
createPool(config) {
|
|
5428
|
+
if (isConnectionStringConfig(config)) {
|
|
5429
|
+
return new Pool({
|
|
5430
|
+
connectionString: config.connectionString,
|
|
5431
|
+
ssl: config.ssl,
|
|
5432
|
+
max: config.max ?? DEFAULT_MAX_CONNECTIONS,
|
|
5433
|
+
idleTimeoutMillis: config.idleTimeoutMillis ?? DEFAULT_IDLE_TIMEOUT_MS
|
|
5434
|
+
});
|
|
5435
|
+
}
|
|
5436
|
+
if (isHostConfig(config)) {
|
|
5437
|
+
return new Pool({
|
|
5438
|
+
host: config.host,
|
|
5439
|
+
port: config.port,
|
|
5440
|
+
database: config.database,
|
|
5441
|
+
user: config.user,
|
|
5442
|
+
password: config.password,
|
|
5443
|
+
ssl: config.ssl,
|
|
5444
|
+
max: config.max ?? DEFAULT_MAX_CONNECTIONS,
|
|
5445
|
+
idleTimeoutMillis: config.idleTimeoutMillis ?? DEFAULT_IDLE_TIMEOUT_MS
|
|
5446
|
+
});
|
|
5447
|
+
}
|
|
5448
|
+
if (isCloudSqlConfig(config)) {
|
|
5449
|
+
return new Pool(config);
|
|
5450
|
+
}
|
|
5451
|
+
throw new Error("PostgresStore: invalid config");
|
|
5452
|
+
}
|
|
5123
5453
|
async init() {
|
|
5124
5454
|
if (this.isInitialized) {
|
|
5125
5455
|
return;
|
|
@@ -5139,19 +5469,32 @@ var PostgresStore = class extends MastraStorage {
|
|
|
5139
5469
|
);
|
|
5140
5470
|
}
|
|
5141
5471
|
}
|
|
5472
|
+
/**
|
|
5473
|
+
* Database client for executing queries.
|
|
5474
|
+
*
|
|
5475
|
+
* @example
|
|
5476
|
+
* ```typescript
|
|
5477
|
+
* const rows = await store.db.any('SELECT * FROM users WHERE active = $1', [true]);
|
|
5478
|
+
* const user = await store.db.one('SELECT * FROM users WHERE id = $1', [userId]);
|
|
5479
|
+
* ```
|
|
5480
|
+
*/
|
|
5142
5481
|
get db() {
|
|
5143
5482
|
return this.#db;
|
|
5144
5483
|
}
|
|
5145
|
-
|
|
5146
|
-
|
|
5484
|
+
/**
|
|
5485
|
+
* The underlying pg.Pool for direct database access or ORM integration.
|
|
5486
|
+
*/
|
|
5487
|
+
get pool() {
|
|
5488
|
+
return this.#pool;
|
|
5147
5489
|
}
|
|
5148
5490
|
/**
|
|
5149
|
-
* Closes the
|
|
5150
|
-
*
|
|
5151
|
-
* This will close ALL connections in the pool, including pre-configured clients.
|
|
5491
|
+
* Closes the connection pool if it was created by this store.
|
|
5492
|
+
* If a pool was passed in via config, it will not be closed.
|
|
5152
5493
|
*/
|
|
5153
5494
|
async close() {
|
|
5154
|
-
this
|
|
5495
|
+
if (this.#ownsPool) {
|
|
5496
|
+
await this.#pool.end();
|
|
5497
|
+
}
|
|
5155
5498
|
}
|
|
5156
5499
|
};
|
|
5157
5500
|
|
|
@@ -5254,6 +5597,6 @@ Example Complex Query:
|
|
|
5254
5597
|
]
|
|
5255
5598
|
}`;
|
|
5256
5599
|
|
|
5257
|
-
export { AgentsPG, MemoryPG, ObservabilityPG, PGVECTOR_PROMPT, PgVector, PostgresStore, ScoresPG, WorkflowsPG };
|
|
5600
|
+
export { AgentsPG, MemoryPG, ObservabilityPG, PGVECTOR_PROMPT, PgVector, PoolAdapter, PostgresStore, ScoresPG, WorkflowsPG, exportSchemas };
|
|
5258
5601
|
//# sourceMappingURL=index.js.map
|
|
5259
5602
|
//# sourceMappingURL=index.js.map
|